fix(ui): hydration-safe banner clock — no build-time clock in the prerendered banner (#44, v0.10.1)

This commit is contained in:
2026-10-03 18:36:19 +00:00
parent 1993623548
commit f1633eb518
+9 -1
View File
@@ -63,6 +63,9 @@ export function MissionControl() {
const [activeTab, setActiveTab] = useState<string | null>(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).