"use client"; /** * PticaShell — cockpit chrome: sticky topbar (ПТИЦА wordmark + 4 tab buttons, * active state driven by props) and a left rail of anchor buttons that * scrollIntoView the matching hero/scan sections, plus a mono timestamp footer. * * The timestamp is rendered only after mount (useState gated by an effect) to * avoid an SSR/client hydration mismatch on the clock value. The effect drives a * UI clock — no HTTP — which is the allowed use of useEffect here. */ import { useEffect, useState } from "react"; import styles from "@/app/site-finder/analysis/[cad]/ptica/ptica.module.css"; export type PticaTab = "analysis" | "scenarios" | "reports" | "compare"; interface TabDef { id: PticaTab; label: string; } const TABS: TabDef[] = [ { id: "analysis", label: "Анализ участка" }, { id: "scenarios", label: "Сценарии" }, { id: "reports", label: "Отчёты" }, { id: "compare", label: "Сравнение" }, ]; interface RailItem { anchor: string; label: string; } const RAIL: RailItem[] = [ { anchor: "passport", label: "Паспорт" }, { anchor: "potential", label: "Потенциал" }, { anchor: "scan", label: "Скан" }, { anchor: "economy", label: "Экономика" }, { anchor: "risks", label: "Риски" }, { anchor: "compare-anchor", label: "Сравнение" }, ]; const BirdMark = ({ className }: { className: string }) => ( ); interface Props { activeTab: PticaTab; onTabChange: (tab: PticaTab) => void; children: React.ReactNode; } function scrollToAnchor(anchor: string) { if (typeof document === "undefined") return; const el = document.getElementById(anchor); el?.scrollIntoView({ behavior: "smooth", block: "start" }); } export function PticaShell({ activeTab, onTabChange, children }: Props) { const [clock, setClock] = useState(null); useEffect(() => { function tick() { const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); const ss = String(now.getSeconds()).padStart(2, "0"); setClock(`${hh}:${mm}:${ss}`); } tick(); const id = window.setInterval(tick, 1000); return () => window.clearInterval(id); }, []); return ( {/* ── Left rail ───────────────────────────────────────────────── */} {/* ── Main column ─────────────────────────────────────────────── */} ПТИЦА платформа территориального информационно-цифрового анализа {TABS.map((tab) => ( onTabChange(tab.id)} > {tab.label} ))} {clock ?? "—"} {children} ); }