Commit Graph

27 Commits

Author SHA1 Message Date
20f1058e9e fix: protect today's record from scrape overwrites
Change upsertDay WHERE guard from >= to > date('now') so today is
treated identically to past dates. Once a park's operating day starts
the API drops that date, making it appear closed. The record written
when the date was still future is the correct one and must be preserved.

Only strictly future dates (> today) are now eligible for upserts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:42:03 -04:00
5ea2dafc0e fix: preserve historical day records, skip scraping past months
upsertDay: add WHERE park_days.date >= date('now') to the ON CONFLICT
DO UPDATE clause. Past dates now behave as INSERT OR IGNORE — new rows
are written freely but existing historical records are never overwritten.
The API stops returning elapsed dates, so the DB row is the permanent
source of truth for any date that has already occurred.

isMonthScraped: months whose last day is before today are permanently
skipped regardless of staleness age. The API has no data for past months
so re-scraping them wastes API calls and cannot improve the records.
Current and future months continue to use the 7-day staleness window.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:37:27 -04:00
d4c8046515 improve: redesign mobile card layout for usability
All checks were successful
Build and Deploy / Build & Push (push) Successful in 3m24s
Replace the cramped 7-column day grid with a clean open-days list.
Each card now shows:
- Park name + "Open today" / "Closed today" badge in the header
- One row per open day (Today, Monday, Friday...) with full hours
- Today row highlighted in amber; passholder days labeled inline
- Whole card is a tap target linking to the park detail page

Also:
- Hide the legend below sm breakpoint (not needed on phones)
- Reduce horizontal padding to 16px on mobile (was 24px)
- Tighten MobileCardList vertical spacing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:33:02 -04:00
b4183507a8 chore: remove logo from header and README
All checks were successful
Build and Deploy / Build & Push (push) Successful in 3m3s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:28:39 -04:00
81ff6ea659 feat: roller coaster logo and working favicon
- public/logo.svg: amber coaster silhouette (lift hill + vertical loop +
  camelback) on transparent background; used in header and README
- app/icon.tsx: PNG favicon via Next.js ImageResponse (works in all
  browsers including Safari); renders simplified hill + loop on dark
  rounded-square background
- app/page.tsx: logo img added next to "Thoosie Calendar" title in header
- README.md: logo displayed at top of document
- Remove app/icon.svg (replaced by icon.tsx → PNG)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:26:45 -04:00
8b1c8dcb29 chore: rebrand to Thoosie Calendar, add favicon
- Rename app title and header from "Six Flags Calendar" to "Thoosie Calendar"
- Update layout metadata title and description
- Update README title
- Add app/icon.svg favicon: amber T on dark background, picked up
  automatically by Next.js App Router

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:18:22 -04:00
e7b72ff95b feat: add live ride status via Queue-Times.com API
All checks were successful
Build and Deploy / Build & Push (push) Successful in 2m51s
Park detail pages now show real-time ride open/closed status and wait
times sourced from Queue-Times.com (updates every 5 min) when a park
is operating. Falls back to the Six Flags schedule API for off-hours
or parks without a Queue-Times mapping.

- lib/queue-times-map.ts: maps all 24 park IDs to Queue-Times park IDs
- lib/scrapers/queuetimes.ts: fetches and parses queue_times.json with
  5-minute ISR cache; returns LiveRidesResult with isOpen + waitMinutes
- app/park/[id]/page.tsx: tries Queue-Times first; renders LiveRideList
  with Live badge and per-ride wait times; falls back to RideList for
  schedule data when live data is unavailable
- README: documents two-tier ride status approach

Attribution: Queue-Times.com (displayed in UI per their API terms)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:15:36 -04:00
ba8cd46e75 docs: update README with current feature set, remove CI/CD section
- Add park detail pages and ride status to description
- Replace flat park list with regional table
- Add debug command documentation
- Remove CI/CD section (Gitea Actions config docs)
- Clean up deployment section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:03:32 -04:00
b0bbb4d465 fix: resolve ESLint errors blocking Docker build
All checks were successful
Build and Deploy / Build & Push (push) Successful in 2m45s
- Remove unused formatDate() from park page (replaced by formatShortDate)
- Remove unused date prop from DayCell component
- Change let to const for cellBorderRadius in ParkCard
- Change let to const for bg in ParkMonthCalendar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 11:55:17 -04:00
e48038c399 feat: UI redesign with park detail pages and ride status
Some checks failed
Build and Deploy / Build & Push (push) Failing after 22s
Visual overhaul:
- Warmer color system with amber accent for Today, better text hierarchy
- Row hover highlighting, sticky column shadow on horizontal scroll
- Closed cells replaced with dot (·) instead of "Closed" text
- Regional grouping (Northeast/Southeast/Midwest/Texas & South/West)
- Two-row header with park count badge and WeekNav on separate lines
- Amber "Today" button in WeekNav when off current week
- Mobile card layout (< 1024px) with 7-day grid per park; table on desktop
- Skeleton loading state via app/loading.tsx

Park detail pages (/park/[id]):
- Month calendar view with ← → navigation via ?month= param
- Live ride status fetched from Six Flags API (cached 1h)
- Ride hours only shown when they differ from park operating hours
- Fallback to nearest upcoming open day when today is dropped by API,
  including cross-month fallback for end-of-month edge case

Data layer:
- Park type gains region field; parks.ts exports groupByRegion()
- db.ts gains getParkMonthData() for single-park month queries
- sixflags.ts gains scrapeRidesForDay() returning RidesFetchResult
  with rides, dataDate, isExact, and parkHoursLabel

Removed: CalendarGrid.tsx, MonthNav.tsx (dead code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 11:53:06 -04:00
5f82407fea feat: show full park names in calendar (e.g. Six Flags Great Adventure)
All checks were successful
Build and Deploy / Build & Push (push) Successful in 3m14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 11:02:28 -04:00
e2d90b3c5b feat: hide parks with no open days in the current week
Some checks failed
Build and Deploy / Build & Push (push) Has been cancelled
Header subtitle now shows "X of 24 parks open" for context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 11:00:53 -04:00
91e09b0548 feat: detect passholder preview days and filter plain buyouts
All checks were successful
Build and Deploy / Build & Push (push) Successful in 3m9s
- Buyout days are now treated as closed unless they carry a Passholder
  Preview event, in which case they surface as a distinct purple cell
  in the UI showing "Passholder" + hours
- DB gains a special_type column (auto-migrated on next startup)
- scrape.ts threads specialType through to upsertDay
- debug.ts now shows events, isBuyout, isPassholderPreview, and
  specialType in the parsed result section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 10:53:05 -04:00
7c28d8f89f feat: save debug output to debug/{parkId}_{date}.txt
All checks were successful
Build and Deploy / Build & Push (push) Successful in 5m13s
Creates debug/ folder (txt files gitignored). Output is printed to
the terminal and written to the file simultaneously.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 10:45:55 -04:00
8a68251beb feat: add debug script for inspecting raw API data per park+date
All checks were successful
Build and Deploy / Build & Push (push) Successful in 4m23s
npm run debug -- --park greatadventure --date 2026-07-04

Prints the raw API response for that day alongside the parsed result
so mismatched or missing hours can be traced to their source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 10:39:37 -04:00
5bef17aa41 refactor: one-line-per-park output with inline month progress
All checks were successful
Build and Deploy / Build & Push (push) Successful in 3m11s
Each park prints a row of █ (fetched) and · (skipped) as months
complete, then ends with open day count, "up to date", or error count.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 10:31:11 -04:00
bc5777c9e2 refactor: scrape all 12 months per park before moving to next park
All checks were successful
Build and Deploy / Build & Push (push) Successful in 2m54s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 10:25:20 -04:00
09dcfde16e ci: use docker/metadata-action and build-push-action
All checks were successful
Build and Deploy / Build & Push (push) Successful in 14m31s
Cleaner pipeline using official Docker actions. Supports semver tags
alongside latest. Registry driven by vars.REGISTRY variable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 01:37:09 -04:00
2bc10c98d9 chore: remove build from compose, pull from registry only
Some checks failed
Build and Deploy / build-and-push (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 01:26:45 -04:00
cd3c3fab7e fix: add public/ directory so Docker COPY doesn't fail
Some checks failed
Build and Deploy / build-and-push (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 01:15:54 -04:00
12af38c5f6 chore: hardcode registry URL and clean up readme
Some checks failed
Build and Deploy / build-and-push (push) Failing after 38s
docker-compose no longer needs REGISTRY_URL env var.
README now uses the actual registry host throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 01:13:16 -04:00
a2b59b2f8d fix: derive registry host from gitea.server_url instead of unset variable
Some checks failed
Build and Deploy / build-and-push (push) Failing after 1m7s
REGISTRY_URL var was empty so docker login fell through to Docker Hub.
Now strips protocol from gitea.server_url to get the registry hostname —
no manual variable needed. docker-compose defaults to the known host.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 01:10:20 -04:00
4118d31df8 Update README.md
Some checks failed
Build and Deploy / build-and-push (push) Failing after 6s
2026-04-04 01:00:07 -04:00
c32967ebf1 Update README.md 2026-04-04 00:56:39 -04:00
548c7ae09e feat: initial project scaffold with CI/CD and Docker deployment
Next.js 15 + Tailwind CSS v4 week calendar showing Six Flags park hours.
Scrapes the internal CloudFront API, stores results in SQLite.
Includes Dockerfile (Debian/Playwright-compatible), docker-compose, and
Gitea Actions pipeline that builds and pushes to the container registry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 00:48:09 -04:00
af6aa29474 chore: add project config 2026-04-03 22:06:54 -04:00
6a139597ad docs: initialize project 2026-04-03 22:05:47 -04:00