"use client"; import { useQuery } from "@tanstack/react-query"; import { getKpis, type KpiSummary } from "@/lib/api"; interface Props { scenarioIds: string[]; scenarioNames: Record; } const KPI_LABELS: { key: keyof KpiSummary; label: string; format: "pct" | "num" | "inr" }[] = [ { key: "solved_tariff_inr_per_kwh", label: "Tariff (₹/kWh)", format: "inr" }, { key: "equity_irr", label: "Equity IRR", format: "pct" }, { key: "project_irr", label: "Project IRR", format: "pct" }, { key: "min_dscr", label: "Min DSCR", format: "num" }, { key: "avg_dscr", label: "Avg DSCR", format: "num" }, { key: "total_capex_cr", label: "Total Capex (Cr)", format: "num" }, { key: "lcoe_inr_per_kwh", label: "LCOE (₹/kWh)", format: "inr" }, { key: "payback_years", label: "Payback (yrs)", format: "num" }, { key: "solar_y1_cuf", label: "Solar Y1 CUF", format: "pct" }, { key: "wind_y1_plf", label: "Wind Y1 PLF", format: "pct" }, { key: "rtc_cuf_achieved", label: "RTC CUF", format: "pct" }, { key: "total_shortfall_mwh", label: "Shortfall (MWh)", format: "num" }, { key: "total_mcp_revenue_cr", label: "MCP Revenue (Cr)", format: "num" }, ]; function fmtCell(v: number | null | undefined, format: "pct" | "num" | "inr"): string { if (v == null) return "—"; if (format === "pct") return `${(v * 100).toFixed(1)}%`; if (format === "inr") return `₹${v.toFixed(2)}`; return v.toFixed(2); } function KpiRow({ rowKey, label, format, kpiMap, ids, }: { rowKey: keyof KpiSummary; label: string; format: "pct" | "num" | "inr"; kpiMap: Record; ids: string[]; }) { const values = ids.map((id) => kpiMap[id]?.[rowKey] as number | null | undefined); const nums = values.filter((v): v is number => v != null); const best = nums.length > 0 ? Math.max(...nums) : null; return ( {label} {ids.map((id, i) => { const v = values[i]; const isBest = v != null && v === best && nums.length > 1; return ( {fmtCell(v, format)} ); })} ); } export function ScenarioCompare({ scenarioIds, scenarioNames }: Props) { const queries = scenarioIds.map((id) => // eslint-disable-next-line react-hooks/rules-of-hooks useQuery({ queryKey: ["kpis", id], queryFn: () => getKpis(id), }) ); const kpiMap: Record = {}; for (let i = 0; i < scenarioIds.length; i++) { const data = queries[i].data; if (data) kpiMap[scenarioIds[i]] = data; } const isLoading = queries.some((q) => q.isLoading); if (isLoading) { return
Loading comparison…
; } return (
{scenarioIds.map((id) => ( ))} {KPI_LABELS.map(({ key, label, format }) => ( ))}
KPI {scenarioNames[id] ?? id.slice(0, 8)}
); }