Add mobile optimization and PDGA update date simulation

Mobile improvements:
- Responsive table layout with hidden columns on mobile
- Touch-friendly buttons and improved spacing
- Consolidated information display for small screens
- Mobile-specific CSS with media queries

PDGA rating simulation:
- Calculate next official PDGA update date (2nd Tuesday of each month)
- Filter tournaments to only include rounds before next update
- Simulate realistic rating predictions based on PDGA schedule
- Account for rolling 12-month window and round expiration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Samuel Enocsson
2025-08-12 17:22:12 +02:00
parent 2994f221f7
commit ef3881a0ac
2 changed files with 155 additions and 19 deletions
+52 -4
View File
@@ -165,7 +165,11 @@ async function getPlayerCompetitionRatings(browser, pdgaNumber) {
const url = `https://www.pdga.com/player/${pdgaNumber}`;
await page.goto(url, { waitUntil: 'networkidle2' });
const tournamentUrls = await page.evaluate(() => {
// Calculate the next PDGA update date to filter tournaments
const nextUpdateDate = getNextPDGAUpdateDate();
const tournamentUrls = await page.evaluate((nextUpdateTimestamp) => {
const nextUpdateDate = new Date(nextUpdateTimestamp);
const tables = document.querySelectorAll('table[id*="player-results"]');
const urls = [];
@@ -185,7 +189,7 @@ async function getPlayerCompetitionRatings(browser, pdgaNumber) {
const oneYearAgo = new Date();
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
if (date > oneYearAgo) {
if (date > oneYearAgo && date < nextUpdateDate) {
const href = tournamentCell.getAttribute('href');
if (href) {
urls.push({
@@ -200,7 +204,7 @@ async function getPlayerCompetitionRatings(browser, pdgaNumber) {
});
return urls.slice(0, 8); // Reduce number of tournaments to scrape
});
}, nextUpdateDate.getTime());
console.log(`Found ${tournamentUrls.length} recent tournaments for PDGA ${pdgaNumber}`);
@@ -287,11 +291,55 @@ function parseDate(dateStr) {
return new Date(dateStr);
}
function getNextPDGAUpdateDate() {
const today = new Date();
const currentMonth = today.getMonth();
const currentYear = today.getFullYear();
// Calculate 2nd Tuesday of current month
const firstDayOfMonth = new Date(currentYear, currentMonth, 1);
const firstTuesday = new Date(firstDayOfMonth);
// Find first Tuesday (day 2 = Tuesday, 0 = Sunday)
const daysUntilTuesday = (2 - firstDayOfMonth.getDay() + 7) % 7;
firstTuesday.setDate(1 + daysUntilTuesday);
// Second Tuesday is 7 days after first Tuesday
const secondTuesday = new Date(firstTuesday);
secondTuesday.setDate(firstTuesday.getDate() + 7);
// If today is before or on the 2nd Tuesday of this month, use this month's date
// Otherwise, use next month's 2nd Tuesday
if (today <= secondTuesday) {
return secondTuesday;
} else {
// Calculate 2nd Tuesday of next month
const nextMonth = currentMonth === 11 ? 0 : currentMonth + 1;
const nextYear = currentMonth === 11 ? currentYear + 1 : currentYear;
const firstDayNextMonth = new Date(nextYear, nextMonth, 1);
const firstTuesdayNext = new Date(firstDayNextMonth);
const daysUntilTuesdayNext = (2 - firstDayNextMonth.getDay() + 7) % 7;
firstTuesdayNext.setDate(1 + daysUntilTuesdayNext);
const secondTuesdayNext = new Date(firstTuesdayNext);
secondTuesdayNext.setDate(firstTuesdayNext.getDate() + 7);
return secondTuesdayNext;
}
}
function calculatePredictedRating(roundRatings) {
if (!roundRatings || roundRatings.length === 0) return 0;
// Sort by date (most recent first) and extract ratings
// Get the next PDGA rating update date - only include rounds before this date
const nextUpdateDate = getNextPDGAUpdateDate();
console.log(`Next PDGA update date: ${nextUpdateDate.toDateString()}`);
// Filter rounds to only include those before the next update date, then sort by date (most recent first) and extract ratings
const sortedRatings = roundRatings
.filter(r => r.date < nextUpdateDate) // Only include rounds before next update
.sort((a, b) => b.date - a.date)
.map(r => r.rating)
.filter(r => r > 0);