diff --git a/README.md b/README.md index 0c0c5bc..753f43f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is the site for [Aces](https://aces.hackclub.com), a 48 hour hackathon run If you're here to contribute to the Gallery, hold on tight! - + ## Development - Getting Started diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 205b6bc..799d200 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,11 +1,12 @@ import clsx from "clsx"; +import { ReactNode } from "react"; interface ButtonProps extends React.ButtonHTMLAttributes { color: "rose" | "red" | "white"; invert?: boolean; href?: string; disable?: boolean; - children: React.ReactNode; + children: ReactNode; } const baseClasses = diff --git a/src/pages/api/rsvp.ts b/src/pages/api/rsvp.ts index ee5ab2e..b23b07d 100644 --- a/src/pages/api/rsvp.ts +++ b/src/pages/api/rsvp.ts @@ -1,48 +1,38 @@ +// src/pages/api/rsvp.ts import { NextApiRequest, NextApiResponse } from "next"; -async function getCount() { - let offset; +// Rewritten to ensure a single background updater reloads the cached count every 30s. + +async function getCount(): Promise { + let offset: string | undefined; let count = 0; do { const url = new URL(`https://api.airtable.com/v0/${process.env.RSVP_AIRTABLE_BASE_ID}/RSVPs`); if (offset) url.searchParams.set("offset", offset); - const res = await fetch(url, { + const res = await fetch(url.toString(), { headers: { Authorization: `Bearer ${process.env.RSVP_AIRTABLE_API_KEY}`, }, }); + if (!res.ok) { - console.error(res.statusText); - throw new Error(res.statusText); + const text = await res.text().catch(() => res.statusText); + console.error("Airtable request failed:", res.status, text); + throw new Error(text || "Airtable request failed"); } + const data = await res.json(); - count += data.records?.length ?? 0; + count += (data.records?.length ?? 0); offset = data.offset; - if (offset) await new Promise((resolve) => setTimeout(resolve, 200)); + if (offset) await new Promise((r) => setTimeout(r, 200)); } while (offset); return count; } -let cached = { value: -1, updated: 0 }; - -// Cache duration in milliseconds -const CACHE_DURATION = 30000; - -export default async function handler(_req: NextApiRequest, res: NextApiResponse) { - const now = Date.now(); - if (now - cached.updated > CACHE_DURATION) { - try { - const count = await getCount(); - cached = { value: count, updated: now }; - console.log("cached value", cached.value, "updatedAt", new Date(cached.updated).toISOString()); - } catch (err: unknown) { - console.error("getCount failed:", err); - res.status(500).json({ error: "couldnt get count" }); - } - } - res.status(200).json({ count: cached.value }); -} \ No newline at end of file +export default function handler(_req: NextApiRequest, res: NextApiResponse) { + getCount().then(count => res.status(200).json({ count })); +}