import { Battery, Sun, Zap } from 'lucide-react' import { PowerFlowCard } from '../components/PowerFlowCard' import { SocGauge } from '../components/SocGauge' import { TelemetryChart } from '../components/TelemetryChart' import { useAuditDailyToday } from '../hooks/useAuditDailyToday' import { useSiteStatus } from '../hooks/useSiteStatus' import { useTelemetryToday } from '../hooks/useTelemetryToday' function fmtEnergy(v: string | number | null | undefined): string { const n = typeof v === 'number' ? v : v == null ? NaN : Number(v) if (!Number.isFinite(n)) return '—' return `${n.toLocaleString('cs-CZ', { maximumFractionDigits: 3 })} kWh` } function fmtMoney(v: string | number | null | undefined): string { const n = typeof v === 'number' ? v : v == null ? NaN : Number(v) if (!Number.isFinite(n)) return '—' return `${n.toLocaleString('cs-CZ', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Kč` } function modeBadgeClass(code: string | null): string { const c = (code ?? '').toUpperCase() if (c.includes('AUTO')) return 'bg-emerald-500/15 text-emerald-300 ring-1 ring-emerald-500/35' if (c.includes('SELF')) return 'bg-cyan-500/15 text-cyan-300 ring-1 ring-cyan-500/35' if (c.includes('MANUAL') || c.includes('FORCE')) return 'bg-amber-500/15 text-amber-200 ring-1 ring-amber-500/35' if (c.includes('OFF') || c.includes('IDLE')) return 'bg-slate-600/40 text-slate-300 ring-1 ring-slate-500/30' return 'bg-slate-700/60 text-slate-200 ring-1 ring-slate-600/50' } function batteryStyles(powerW: number | null | undefined): { border: string; icon: string } { if (powerW == null || Number.isNaN(powerW)) { return { border: 'border-l-slate-600', icon: 'text-slate-400' } } if (powerW >= 0) { return { border: 'border-l-emerald-500', icon: 'text-emerald-400' } } return { border: 'border-l-orange-500', icon: 'text-orange-400' } } function gridStyles(powerW: number | null | undefined): { border: string; icon: string } { if (powerW == null || Number.isNaN(powerW)) { return { border: 'border-l-slate-600', icon: 'text-slate-400' } } if (powerW >= 0) { return { border: 'border-l-red-500', icon: 'text-red-400' } } return { border: 'border-l-emerald-500', icon: 'text-emerald-400' } } function SectionTitle({ kicker, title }: { kicker: string; title: string }) { return (

{kicker}

{title}

) } function CardSkeleton() { return
} function StatBlock({ label, value }: { label: string; value: string }) { return (

{label}

{value}

) } function StatSkeleton() { return
} export function Dashboard() { const { site, ready: siteReady, hasLiveData } = useSiteStatus() const siteId = site?.site_id ?? null const { points, ready: telemetryReady, hasChartData } = useTelemetryToday(siteId) const { daily, ready: auditReady, hasDaily } = useAuditDailyToday(siteId) const liveSkeleton = !siteReady || !hasLiveData const chartSkeleton = !telemetryReady || !hasChartData const econSkeleton = !auditReady || !hasDaily const hbOk = site?.ems_heartbeat_status === 'ok' const bat = batteryStyles(site?.battery_power_w ?? null) const grd = gridStyles(site?.grid_power_w ?? null) return (

EMS Platform

Přehled lokality a auditu

{!siteReady ? (
) : site ? (
{site.site_name} {site.active_mode ?? '—'} {site.mode_name ? ` · ${site.mode_name}` : ''} EMS
) : null}
{liveSkeleton ? (
) : (
)}
{econSkeleton ? (
) : (
)}
) }