diff --git a/src/components/RSVP.tsx b/src/components/RSVP.tsx index a575d2c..43d557e 100644 --- a/src/components/RSVP.tsx +++ b/src/components/RSVP.tsx @@ -1,15 +1,17 @@ +"use client" + import useSWR from "swr"; const fetcher = (url: string) => fetch(url).then(res => res.json()); export default function RSVP() { - const { data, error } = useSWR("https://aces.femboyin.tech/count", fetcher, { - refreshInterval: 60000, + const { data, error } = useSWR("/api/rsvp", fetcher, { + refreshInterval: 10000, revalidateOnFocus: false, }); if (error) return error!; - if (!data) return ... + if (!data || data.count === -1) return ... - return {data.record_count} + return {data.count} } \ No newline at end of file diff --git a/src/pages/api/git.ts b/src/pages/api/git.ts index 929f59e..426d00f 100644 --- a/src/pages/api/git.ts +++ b/src/pages/api/git.ts @@ -1,7 +1,5 @@ import { NextApiRequest, NextApiResponse } from "next"; -const branch = process.env.NODE_ENV === "production" ? "main" : "dev"; - let cache: { hash: string, message: string @@ -9,7 +7,7 @@ let cache: { export default async function handler(_req: NextApiRequest, res: NextApiResponse) { if (!cache) { - const githubRes = await fetch(`https://api.github.com/repos/hackclub/aces/commits/${branch}`) + const githubRes = await fetch(`https://api.github.com/repos/hackclub/aces/commits/main`) if (!githubRes.ok) throw new Error(`GitHub API error: ${githubRes.status}`) const json = await githubRes.json() cache = { diff --git a/src/pages/api/rsvp.ts b/src/pages/api/rsvp.ts new file mode 100644 index 0000000..ee5ab2e --- /dev/null +++ b/src/pages/api/rsvp.ts @@ -0,0 +1,48 @@ +import { NextApiRequest, NextApiResponse } from "next"; + +async function getCount() { + let offset; + 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, { + headers: { + Authorization: `Bearer ${process.env.RSVP_AIRTABLE_API_KEY}`, + }, + }); + if (!res.ok) { + console.error(res.statusText); + throw new Error(res.statusText); + } + const data = await res.json(); + count += data.records?.length ?? 0; + offset = data.offset; + + if (offset) await new Promise((resolve) => setTimeout(resolve, 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 diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 8bc50dc..1a22bb7 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -94,7 +94,7 @@ export default function Home() { />
Build your own digital board/card game, get a{" "} - grant to build it irl, and head to DC for{" "} + grant to make it real, and head to DC for{" "} AwesomeCon to showcase it, then stay for an in-person hackathon!