"use client"; import type { ParcelAnalysis, ParcelAnalysisNoise, ParcelAnalysisAirQuality, ParcelAnalysisWind, ParcelAnalysisWeather, } from "@/types/site-finder"; import { SectionLabel } from "@/components/ui/SectionLabel"; import { EmptyState } from "@/components/ui/EmptyState"; import { SeasonalWeatherBlock } from "./SeasonalWeatherBlock"; import { HydrologyBlock } from "./HydrologyBlock"; interface Props { data: ParcelAnalysis; } // ── helpers ────────────────────────────────────────────────────────────────── const SOURCE_TYPE_LABELS: Record = { highway: "Магистраль", railway: "Ж/д", industrial: "Производство", aerodrome: "Аэродром", }; function noiseBg(score: number): string { if (score >= 0.7) return "#dcfce7"; if (score >= 0.4) return "#fef3c7"; return "#fecaca"; } function pm25Color(v: number): string { if (v < 10) return "#16a34a"; if (v < 25) return "#d97706"; if (v < 50) return "#ea580c"; return "#dc2626"; } function pm10Color(v: number): string { if (v < 20) return "#16a34a"; if (v < 50) return "#d97706"; if (v < 100) return "#ea580c"; return "#dc2626"; } function no2Color(v: number): string { if (v < 40) return "#16a34a"; if (v < 100) return "#d97706"; return "#dc2626"; } function formatTs(iso: string): string { try { return new Date(iso).toLocaleDateString("ru-RU", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", }); } catch { return iso; } } function uvColor(uv: number): string { if (uv < 3) return "#16a34a"; if (uv < 6) return "#d97706"; if (uv < 8) return "#ea580c"; return "#dc2626"; } // ── WindArrow SVG ───────────────────────────────────────────────────────────── function WindArrow({ deg }: { deg: number }) { return ( ); } // ── Noise ───────────────────────────────────────────────────────────────────── function NoiseBlock({ noise }: { noise: ParcelAnalysisNoise }) { return (
Шум
~{Math.round(noise.estimated_db)} dB
{noise.level}
{noise.sources.length > 0 && (
Источники ({noise.sources.length})
{noise.sources.slice(0, 5).map((s, i) => (
{SOURCE_TYPE_LABELS[s.source_type] ?? s.source_type} {s.name ? ` «${s.name}»` : ""} — {Math.round(s.distance_m)} м ( {Math.round(s.estimated_db)} dB)
))}
)}
); } // ── Air quality ─────────────────────────────────────────────────────────────── function AqBadge({ label, value, unit, color, }: { label: string; value: number; unit: string; color: string; }) { return (
{label}
{value.toFixed(1)}
{unit}
); } function AirQualityBlock({ aq }: { aq: ParcelAnalysisAirQuality | null }) { if (!aq) { return (
Воздух
Данные недоступны
); } return (
Воздух
{aq.source} · {formatTs(aq.ts)}
); } // ── Wind ────────────────────────────────────────────────────────────────────── function WindBlock({ wind }: { wind: ParcelAnalysisWind | null }) { if (!wind) { return (
Ветер
Данные недоступны
); } return (
Ветер
{wind.dominant_direction_label} {wind.max_speed_m_s != null ? ` · до ${wind.max_speed_m_s} м/с` : ""}
за {wind.forecast_days} дн.
); } // ── Weather (7-day forecast) ────────────────────────────────────────────────── function WeatherBlock({ weather, }: { weather: ParcelAnalysisWeather | null | undefined; }) { if (!weather) { return (
Погода / Климат
Прогноз недоступен
); } const { temperature: t, wind } = weather; return (
Погода / Климат
Температура
{t.min_c != null && t.max_c != null ? `${t.min_c}…${t.max_c}°C` : t.min_c != null ? `от ${t.min_c}°C` : t.max_c != null ? `до ${t.max_c}°C` : "—"}
{(t.avg_min_c != null || t.avg_max_c != null) && (
ср. {t.avg_min_c != null ? `${t.avg_min_c}` : "?"} {"/"} {t.avg_max_c != null ? `${t.avg_max_c}` : "?"}°C
)}
Осадки
{weather.precipitation_total_mm} мм {" "} (за {weather.forecast_days} дн.)
{weather.precipitation_days} дн. с осадками
{weather.uv_index_max != null && (
UV макс:
{weather.uv_index_max}
)}
{wind.dominant_direction_label} {wind.max_speed_m_s != null ? ` · до ${wind.max_speed_m_s} м/с` : ""}
{weather.source} · {weather.forecast_days} дн.
); } // ── EnvironmentTab ──────────────────────────────────────────────────────────── export function EnvironmentTab({ data }: Props) { const hasEnv = data.noise !== undefined || data.air_quality !== undefined || data.wind !== undefined || data.weather !== undefined; return (
{/* Primary env grid */} {hasEnv && (
Внешние факторы
{data.noise !== undefined ? ( data.noise !== null ? ( ) : (
Шум
Данные недоступны
) ) : null} {data.weather !== undefined ? ( ) : ( )}
)} {/* Seasonal weather */} {"seasonal_weather" in data && (
Климат (нормали 30 лет)
)} {/* Hydrology */} {data.hydrology !== undefined && (
Гидрология
)} {!hasEnv && !("seasonal_weather" in data) && data.hydrology === undefined && ( )}
); }