From 11fa490599cd81d961ccf941c0d0e164beff8877 Mon Sep 17 00:00:00 2001 From: Sharang Parnerkar <30073382+mighty840@users.noreply.github.com> Date: Fri, 17 Apr 2026 10:56:52 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20finanzplan=20scenario=20selector=20?= =?UTF-8?q?=E2=80=94=20load=20from=20API,=20no=20hardcoded=20UUID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the FM-name-based 'wandeldarlehen' hack with a proper scenario picker. Scenarios are fetched from /api/finanzplan, default is selected automatically. Dropdown appears when multiple scenarios exist. Co-Authored-By: Claude Sonnet 4.6 --- .../components/slides/FinanzplanSlide.tsx | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/pitch-deck/components/slides/FinanzplanSlide.tsx b/pitch-deck/components/slides/FinanzplanSlide.tsx index 2629c0e..cd67dd5 100644 --- a/pitch-deck/components/slides/FinanzplanSlide.tsx +++ b/pitch-deck/components/slides/FinanzplanSlide.tsx @@ -61,8 +61,12 @@ function formatCell(v: number | undefined): string { return Math.round(v).toLocaleString('de-DE', { maximumFractionDigits: 0 }) } +interface FpScenario { id: string; name: string; is_default: boolean } + export default function FinanzplanSlide({ lang, investorId, preferredScenarioId }: FinanzplanSlideProps) { const [sheets, setSheets] = useState([]) + const [scenarios, setScenarios] = useState([]) + const [selectedScenarioId, setSelectedScenarioId] = useState('') const [activeSheet, setActiveSheet] = useState('personalkosten') const [rows, setRows] = useState([]) const [loading, setLoading] = useState(false) @@ -77,19 +81,26 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId [fm.activeResults], ) - // Determine fp_scenario_id from the active FM scenario name - const fpScenarioParam = fm.activeScenario?.name?.toLowerCase().includes('wandeldarlehen') - ? '?scenarioId=c0000000-0000-0000-0000-000000000200' - : '' - - // Load sheet list + // Load sheet list + scenarios useEffect(() => { fetch('/api/finanzplan', { cache: 'no-store' }) .then(r => r.json()) - .then(data => setSheets(data.sheets || [])) + .then(data => { + setSheets(data.sheets || []) + const scens: FpScenario[] = data.scenarios || [] + setScenarios(scens) + // Pick default scenario on first load + if (!selectedScenarioId) { + const def = scens.find(s => s.is_default) ?? scens[0] + if (def) setSelectedScenarioId(def.id) + } + }) .catch(() => {}) + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) + const scenarioParam = selectedScenarioId ? `?scenarioId=${selectedScenarioId}` : '' + // Load sheet data const loadSheet = useCallback(async (name: string) => { if (name === 'kpis' || name === 'charts') { @@ -99,12 +110,12 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId } setLoading(true) try { - const r = await fetch(`/api/finanzplan/${name}${fpScenarioParam}`, { cache: 'no-store' }) + const r = await fetch(`/api/finanzplan/${name}${scenarioParam}`, { cache: 'no-store' }) const data = await r.json() setRows(data.rows || []) } catch { /* ignore */ } setLoading(false) - }, [fpScenarioParam]) + }, [scenarioParam]) useEffect(() => { loadSheet(activeSheet) }, [activeSheet, loadSheet]) @@ -112,7 +123,7 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId const handleCompute = async () => { setComputing(true) try { - await fetch('/api/finanzplan/compute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' }) + await fetch('/api/finanzplan/compute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ scenarioId: selectedScenarioId || undefined }) }) await loadSheet(activeSheet) } catch { /* ignore */ } setComputing(false) @@ -182,6 +193,17 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId ))}
+ {scenarios.length > 1 && ( + + )}