diff --git a/apps/web/src/components/api-health-gate.tsx b/apps/web/src/components/api-health-gate.tsx index 0d51df3..17cc940 100644 --- a/apps/web/src/components/api-health-gate.tsx +++ b/apps/web/src/components/api-health-gate.tsx @@ -1,11 +1,22 @@ import { useCallback, useEffect, useState } from "react"; import { Link, Outlet, useLocation } from "react-router"; +import { CheckIcon } from "lucide-react"; import { Button, buttonVariants } from "@/components/ui/button"; import { checkApiHealth, requestWake } from "@/lib/api"; const CONTACT_EMAIL = "murugu2001@gmail.com"; const POLL_INTERVAL_MS = 8000; +// Heuristic cold-start phases (keyed to elapsed seconds). The box can't report +// real boot progress to a page that can't reach it, so this is an honest estimate +// matching the actual sequence; the gate flips to the app the instant /health 200s. +const BOOT_PHASES = [ + { at: 0, label: "Waking up a server" }, + { at: 20, label: "Pulling container images (~3 GB)" }, + { at: 110, label: "Starting the pipeline — Postgres, Redpanda, Debezium, API" }, + { at: 165, label: "Reconnecting" }, +] as const; + type Status = "checking" | "up" | "down"; /** @@ -91,29 +102,80 @@ function InstanceStarting({ retrying: boolean; }) { const isPublicForm = variant === "publicForm"; + // Count elapsed seconds so the screen shows motion + an honest "how long" cue. + const [elapsed, setElapsed] = useState(0); + useEffect(() => { + const id = window.setInterval(() => setElapsed((e) => e + 1), 1000); + return () => window.clearInterval(id); + }, []); + const phaseIdx = BOOT_PHASES.reduce((acc, p, i) => (elapsed >= p.at ? i : acc), 0); + const overtime = elapsed > 210; + const mmss = `${Math.floor(elapsed / 60)}:${String(elapsed % 60).padStart(2, "0")}`; + return (
- To save resources, EventForm’s backend powers down when idle. - Ask whoever shared this link to sign in — that starts - it back up (a couple of minutes). If that’s you, sign in below; - this page loads the form on its own once it’s running. -
- ) : ( +- To save resources, EventForm’s backend powers down when idle, so - the first visit takes a minute. Sign in to wake it — - this page reconnects automatically once it’s up. + To stay (nearly) free to host, EventForm runs on a single small server + that powers down when idle. Your visit is waking it — + the first load takes about 2–3 minutes while it + boots and pulls ~3 GB of container images, then it’s instant + until it idles again.
- )} + {isPublicForm && ( ++ Only a signed-in user can start it — if it doesn’t come up, ask + whoever shared this link to sign in. +
+ )} ++ {overtime + ? "Taking longer than usual — it should still come up; you can retry below." + : `${mmss} elapsed · usually ~2–3 min · reconnects on its own`} +
+- Still not loading after a few minutes?{" "} + +