gendesign/frontend/src/components/site-finder/ptica/ScanCard.tsx
Light1YT 05eb70eb62
All checks were successful
CI / changes (pull_request) Successful in 5s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 55s
CI / openapi-codegen-check (pull_request) Successful in 1m57s
feat(site-finder): ПТИЦА dark cockpit — increment 1 (shell + hero + Development Scan)
New non-destructive route /site-finder/analysis/[cad]/ptica rendering the existing
/analyze data in the «ПТИЦА» operator-terminal cockpit. The light analysis page,
Section1-6, globals.css and package.json are untouched.

PR#1 scope: app-shell (topbar + 4 tabs + left rail), hero (dark Leaflet map +
parcel passport KV-grid + Buildability radial gauge + invest-score block), and the
Development Scan card grid — wired to useParcelAnalyzeQuery / ParcelAnalysis.

Data honesty: real fields render live (passport egrn.*, district, utilities.summary,
median_price, pipeline_24mo); absent fields show muted placeholders with source
captions (buildability/risk = derived proxy «предв.»; invest/buy-signal «после
прогноза»; КСИТ/height/ОКС/economy «—») via typed ptica-adapt.ts — no fake numbers
presented as live.

Dark theme is a CSS-module scoped under .pticaRoot[data-theme=dark] (cannot leak to
the light app); IBM Plex Mono added via next/font (no dep/lockfile change). Leaflet
via dynamic(ssr:false). TS strict, no any. Deferred to follow-up PRs: Scenarios
(forecast), Reports+Compare tabs, 16 detail drawers, Three.js 3D massing.
2026-06-20 15:29:53 +05:00

61 lines
1.7 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";
/**
* ScanCard — generic dark cockpit card: title (+ optional badge), metric rows,
* and a "Подробнее" button that is RENDERED but disabled in INCREMENT 1 (drill-
* down detail ships in a later release).
*
* Each row's value flows from a {value, isReal, caption} view-model: placeholder
* fields are rendered muted with their caption so they never read as live data.
*/
import styles from "@/app/site-finder/analysis/[cad]/ptica/ptica.module.css";
import type { PticaScanCard } from "@/components/site-finder/ptica/ptica-adapt";
interface Props {
card: PticaScanCard;
}
export function ScanCard({ card }: Props) {
const { title, badge, rows, emptyState } = card;
return (
<div className={`${styles.card} ${styles.scanCard}`}>
<h3 className={styles.cardTitle}>
{title}
{badge && <span className={styles.cardTitleSub}>{badge}</span>}
</h3>
{emptyState ? (
<div className={styles.emptyState}>{emptyState}</div>
) : (
rows.map((row) => {
const placeholder = !row.field.isReal;
return (
<div
key={row.key}
className={`${styles.kvrow} ${
placeholder ? styles.kvrowPlaceholder : ""
}`}
>
<span className={styles.k}>{row.key}</span>
<span className={styles.v} title={row.field.caption}>
{row.field.value}
</span>
</div>
);
})
)}
<button
type="button"
className={styles.detailBtn}
disabled
aria-disabled="true"
title="Детализация — в следующем релизе"
>
Подробнее
</button>
</div>
);
}