From f1633eb518ef5b0fc674855b74ce407de5716eaf Mon Sep 17 00:00:00 2001 From: Kamil Krzywda Date: Sat, 3 Oct 2026 18:36:19 +0000 Subject: [PATCH] =?UTF-8?q?fix(ui):=20hydration-safe=20banner=20clock=20?= =?UTF-8?q?=E2=80=94=20no=20build-time=20clock=20in=20the=20prerendered=20?= =?UTF-8?q?banner=20(#44,=20v0.10.1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/mission-control.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/components/mission-control.tsx b/components/mission-control.tsx index d45cfba..03e874e 100644 --- a/components/mission-control.tsx +++ b/components/mission-control.tsx @@ -63,6 +63,9 @@ export function MissionControl() { const [activeTab, setActiveTab] = useState(null) // #38 — admin DB CRUD overlay, opened from the header. const [adminOpen, setAdminOpen] = useState(false) + // #44 (v0.10.1) — true only after hydration: the banner clock must render '' in both SSR and the + // first client render, otherwise the prerendered (build-time) string desyncs at hydration. + const [hydrated, setHydrated] = useState(false) // #44 — the four mount fetches, extracted into a callback so the NEXT TURN button (5b) can // re-run them after /api/turn: a tick can change all four snapshots (the turn always; inventory @@ -120,6 +123,9 @@ export function MissionControl() { return () => clearInterval(id) }, []) + // #44 (v0.10.1) — flip after hydration so the banner clock can start (SSR/first render both ''). + useEffect(() => setHydrated(true), []) + // #27 — restore the persisted tab once on mount (validated against TAB_IDS). useEffect(() => { const stored = window.localStorage.getItem(ACTIVE_TAB_KEY) @@ -139,7 +145,9 @@ export function MissionControl() { .catch(() => {}) }, []) - const timeStr = new Date().toLocaleTimeString('en-GB', { hour12: false }) + // #44 (v0.10.1) — hydration-safe: '' until hydrated (SSR and first client render agree), then the + // live time on the 1s tick — no more build-time clock baked into the prerendered HTML. + const timeStr = hydrated ? new Date().toLocaleTimeString('en-GB', { hour12: false }) : '' // Slugs of the researched techs — drives the effective caps + build gates in the SHIP SYSTEMS // tab via the same pure helpers the API enforces (lib/game/tech.ts).