/** * Scenario detail — params + the latest persisted MC projection. * * Reuses FanChart from the What-If page. If the scenario has no MC run * yet, prompts the user to run /recompute. */ import { useQuery } from '@tanstack/react-query'; import { Link, useParams } from 'react-router-dom'; import { api } from '@/api/client'; import { ApiError } from '@/api/client'; import { FanChart } from '@/components/FanChart'; import { gbp, pct } from '@/lib/format'; export function ScenarioDetail() { const params = useParams<{ id: string }>(); const id = Number(params.id); const scen = useQuery({ queryKey: ['scenarios', id], queryFn: () => api.scenarios.get(id), enabled: Number.isFinite(id), }); const proj = useQuery({ queryKey: ['scenarios', id, 'projection'], queryFn: () => api.scenarios.projection(id), enabled: Number.isFinite(id), retry: (count, err) => { // Don't retry the 404 — it's the "no run yet" empty state. if (err instanceof ApiError && err.status === 404) return false; return count < 2; }, }); if (!Number.isFinite(id)) { return
Invalid scenario id.
; } if (scen.isLoading) returnLoading…
; if (scen.isError || !scen.data) { return ({s.kind} · {s.jurisdiction} · {s.strategy} · leave UK y{s.leave_uk_year} ·{' '} {s.glide_path} glide · {s.horizon_years}y horizon
{s.description &&{s.description}
}No projection yet.
Run python -m fire_planner recompute-all or{' '}
POST /recompute to fill in MC projections for all scenarios.
Loading projection…
) : (