gendesign/frontend/src/app/site-finder/analysis/[cad]/page.tsx
lekss361 440b53cef0 feat(sf-fe-a4): AnalysisSidebar (scrollspy) + Breadcrumb + UserAvatar
Wire analysis/[cad]/page.tsx: replace SidebarPlaceholder with
AnalysisSidebar (sticky, IntersectionObserver scrollspy on sections
1/2/3/3.1/3.2/3.3/4/5), header with AnalysisBreadcrumb (SiteFinder
→ cad → Анализ) and UserAvatar (gd_org_id from localStorage, SSR-safe).

Add lucide-react to package.json (was used in A1 but missing from deps).
2026-05-18 01:12:18 +03:00

182 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { use } from "react";
import { LayoutDashboard } from "lucide-react";
import { AnalysisSidebar } from "@/components/site-finder/analysis/AnalysisSidebar";
import { AnalysisBreadcrumb } from "@/components/site-finder/analysis/AnalysisBreadcrumb";
import { UserAvatar } from "@/components/site-finder/analysis/UserAvatar";
// ── Section placeholder (Wave 34 refactor will replace these) ─────────────────
interface SectionPlaceholderProps {
id: string;
title: string;
note?: string;
}
function SectionPlaceholder({ id, title, note }: SectionPlaceholderProps) {
return (
<section
id={id}
style={{
background: "var(--bg-card)",
border: "1px solid var(--border-card)",
borderRadius: 12,
padding: 20,
marginBottom: 24,
}}
>
<h2
style={{
margin: "0 0 8px",
fontSize: 18,
fontWeight: 600,
color: "var(--fg-primary)",
}}
>
{title}
</h2>
{note && (
<p style={{ margin: 0, fontSize: 13, color: "var(--fg-tertiary)" }}>
{note}
</p>
)}
<div
style={{
marginTop: 16,
padding: "24px 16px",
background: "var(--bg-card-alt)",
border: "1px dashed var(--border-strong)",
borderRadius: 8,
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "var(--fg-tertiary)",
fontSize: 13,
}}
>
<LayoutDashboard
size={16}
strokeWidth={1.5}
style={{ marginRight: 8, flexShrink: 0 }}
/>
Заполняется в Wave 24 (A5A11)
</div>
</section>
);
}
// ── Page ──────────────────────────────────────────────────────────────────────
interface PageProps {
params: Promise<{ cad: string }>;
}
export default function AnalysisPage({ params }: PageProps) {
// React 19: use() unwraps Promise params (app router pattern)
const { cad } = use(params);
return (
<main
style={{
minHeight: "100vh",
background: "var(--bg-app)",
display: "flex",
flexDirection: "column",
}}
>
{/* ── Header ─────────────────────────────────────────────────────────── */}
<header
style={{
background: "var(--bg-card)",
borderBottom: "1px solid var(--border-card)",
padding: "12px 24px",
display: "flex",
alignItems: "center",
gap: 12,
flexWrap: "wrap",
position: "sticky",
top: 0,
zIndex: 10,
minHeight: 56,
boxSizing: "border-box",
}}
>
<AnalysisBreadcrumb cadNum={cad} />
{/* Push avatar to the right */}
<div style={{ marginLeft: "auto" }}>
<UserAvatar />
</div>
</header>
{/* ── Body: sidebar + scrollable sections ───────────────────────────── */}
<div style={{ display: "flex", flex: 1 }}>
<AnalysisSidebar />
{/* Main scrollable content */}
<article
style={{
flex: 1,
padding: "24px 32px",
overflowY: "auto",
maxWidth: 1000,
}}
>
{/* Section 1 — TODO A5 */}
<SectionPlaceholder
id="section-1"
title="1. Объект"
note="TODO A5: HeadlineBar вердикт + 4 KPI (Площадь / Район / Медиана / Score) + mini-map + EGRN table + POI list 2GIS"
/>
{/* Section 2 — TODO A6 */}
<SectionPlaceholder
id="section-2"
title="2. Земля и риски"
note="TODO A6: reuse NspdEngineeringNearbyBlock в новом layout headline+map"
/>
{/* Section 3 — TODO A7/A8/A9 */}
<SectionPlaceholder
id="section-3"
title="3. Рынок"
note="TODO A7: WeightProfilePanel (настройки выборки) · A8: BestLayoutsBlock / Pipeline24moBlock / VelocityBlock · A9: CompetitorTable с drawer drill-in"
/>
{/* Sub-section anchor targets (invisible) for scrollspy / direct links */}
<div
id="section-3-1"
style={{ height: 0, overflow: "hidden" }}
aria-hidden="true"
/>
<div
id="section-3-2"
style={{ height: 0, overflow: "hidden" }}
aria-hidden="true"
/>
<div
id="section-3-3"
style={{ height: 0, overflow: "hidden" }}
aria-hidden="true"
/>
{/* Section 4 — TODO A10 */}
<SectionPlaceholder
id="section-4"
title="4. Инфраструктура"
note="TODO A10: ScoreBreakdownPanel + ScoreBreakdownStackedBar + GateVerdictBanner + GeologyBlock / HydrologyBlock / GeotechRiskBlock"
/>
{/* Section 5 — TODO A11 */}
<SectionPlaceholder
id="section-5"
title="5. Свежесть"
note="TODO A11: SeasonalWeatherBlock + air quality (reuse EnvironmentTab logic split на блоки)"
/>
</article>
</div>
</main>
);
}