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>
This commit is contained in:
2026-04-04 00:48:09 -04:00
parent af6aa29474
commit 548c7ae09e
26 changed files with 9602 additions and 0 deletions

77
components/WeekNav.tsx Normal file
View File

@@ -0,0 +1,77 @@
"use client";
import { useRouter } from "next/navigation";
interface WeekNavProps {
weekStart: string; // YYYY-MM-DD (Sunday)
weekDates: string[]; // 7 dates YYYY-MM-DD
}
const MONTHS = [
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec",
];
function formatLabel(dates: string[]): string {
const s = new Date(dates[0] + "T00:00:00");
const e = new Date(dates[6] + "T00:00:00");
if (s.getFullYear() === e.getFullYear() && s.getMonth() === e.getMonth()) {
return `${MONTHS[s.getMonth()]} ${s.getDate()}${e.getDate()}, ${s.getFullYear()}`;
}
const startStr = `${MONTHS[s.getMonth()]} ${s.getDate()}`;
const endStr = `${MONTHS[e.getMonth()]} ${e.getDate()}, ${e.getFullYear()}`;
return `${startStr} ${endStr}`;
}
function shiftWeek(weekStart: string, delta: number): string {
const d = new Date(weekStart + "T00:00:00");
d.setDate(d.getDate() + delta * 7);
return d.toISOString().slice(0, 10);
}
export function WeekNav({ weekStart, weekDates }: WeekNavProps) {
const router = useRouter();
const nav = (delta: number) =>
router.push(`/?week=${shiftWeek(weekStart, delta)}`);
return (
<div style={{ display: "flex", alignItems: "center", gap: 16 }}>
<button
onClick={() => nav(-1)}
aria-label="Previous week"
style={btnStyle}
>
</button>
<span style={{
fontSize: "1.1rem",
fontWeight: 600,
color: "var(--color-text)",
minWidth: 220,
textAlign: "center",
}}>
{formatLabel(weekDates)}
</span>
<button
onClick={() => nav(1)}
aria-label="Next week"
style={btnStyle}
>
</button>
</div>
);
}
const btnStyle: React.CSSProperties = {
padding: "6px 14px",
borderRadius: 6,
border: "1px solid var(--color-border)",
background: "var(--color-surface)",
color: "var(--color-text-muted)",
cursor: "pointer",
fontSize: "1rem",
lineHeight: 1,
};