fix(pitch-deck): GuV + Cashflow tabs read from fp_* data, Break-Even as year
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m31s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 40s
CI / test-python-voice (push) Successful in 37s
CI / test-bqas (push) Successful in 31s

FinancialsSlide:
- Break-Even: shows year (2029) instead of formatted number (2.029)
- GuV tab: replaced AnnualPLTable (useFinancialModel) with fp_guv data table
  Shows: Revenue, Personnel, EBIT, Taxes, Net Income per year
- Cashflow tab: replaced AnnualCashflowChart (useFinancialModel) with
  fp_liquiditaet bar chart showing cash position + EBIT per year
- Both tabs now show "Quelle: Finanzplan" label

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-19 20:33:30 +02:00
parent 7b31b462a0
commit b0918fd946

View File

@@ -103,14 +103,15 @@ export default function FinancialsSlide({ lang, investorId, preferredScenarioId,
color="#22c55e"
delay={0.15}
/>
<KPICard
label="Break-Even"
value={kpiBreakEven || 0}
trend={kpiBreakEven && kpiBreakEven <= 2029 ? 'up' : 'down'}
color="#eab308"
delay={0.2}
subLabel=""
/>
<FadeInView delay={0.2}>
<div className="bg-white/[0.06] backdrop-blur-xl border border-white/10 rounded-2xl p-3 text-center">
<p className="text-[10px] uppercase tracking-wider text-white/40 mb-1">Break-Even</p>
<p className="text-2xl font-bold text-white">{kpiBreakEven || '—'}</p>
<span className={`text-xs ${kpiBreakEven && kpiBreakEven <= 2029 ? 'text-emerald-400' : 'text-red-400'}`}>
{kpiBreakEven && kpiBreakEven <= 2029 ? '↑' : kpiBreakEven ? '↓' : ''}
</span>
</div>
</FadeInView>
<KPICard
label="EBIT 2030"
value={fpLast?.ebit ? Math.round(fpLast.ebit / 1_000_000 * 10) / 10 : 0}
@@ -203,8 +204,8 @@ export default function FinancialsSlide({ lang, investorId, preferredScenarioId,
</>
)}
{/* TAB: GuV — Annual P&L Table */}
{activeTab === 'guv' && activeResults && (
{/* TAB: GuV — from fp_guv */}
{activeTab === 'guv' && (
<FadeInView delay={0.1}>
<div className="bg-white/[0.05] backdrop-blur-xl border border-white/10 rounded-2xl p-4">
<div className="flex items-center justify-between mb-3">
@@ -212,26 +213,74 @@ export default function FinancialsSlide({ lang, investorId, preferredScenarioId,
{de ? 'Gewinn- und Verlustrechnung (5 Jahre)' : 'Profit & Loss Statement (5 Years)'}
</p>
<p className="text-[9px] text-white/20">
{de ? 'Alle Werte in EUR' : 'All values in EUR'}
{de ? 'Alle Werte in EUR · Quelle: Finanzplan' : 'All values in EUR · Source: Financial Plan'}
</p>
</div>
<AnnualPLTable results={activeResults.results} lang={lang} />
<table className="w-full text-xs">
<thead>
<tr className="border-b border-white/10">
<th className="text-left py-2 text-white/40 font-medium"></th>
{[2026,2027,2028,2029,2030].map(y => <th key={y} className="text-right py-2 px-2 text-white/40 font-medium">{y}</th>)}
</tr>
</thead>
<tbody>
{[
{ label: de ? 'Umsatzerlöse' : 'Revenue', key: 'revenue', bold: true },
{ label: de ? 'Personalkosten' : 'Personnel', key: 'personal', bold: false },
{ label: 'EBIT', key: 'ebit', bold: true },
{ label: de ? 'Steuern' : 'Taxes', key: 'steuern', bold: false },
{ label: de ? 'Jahresüberschuss' : 'Net Income', key: 'netIncome', bold: true },
].map((row, idx) => (
<tr key={idx} className={`border-b border-white/[0.03] ${row.bold ? 'bg-white/[0.02]' : ''}`}>
<td className={`py-1.5 ${row.bold ? 'font-bold text-white/70' : 'text-white/50'}`}>{row.label}</td>
{[2026,2027,2028,2029,2030].map(y => {
const v = fpKPIs[`y${y}`]?.[row.key as keyof typeof fpKPIs['y2026']] || 0
const num = typeof v === 'number' ? v : 0
return (
<td key={y} className={`text-right py-1.5 px-2 font-mono ${num < 0 ? 'text-red-400' : row.bold ? 'text-white/70 font-bold' : 'text-white/50'}`}>
{num === 0 ? '—' : (num >= 1000000 || num <= -1000000) ? `${(num/1000000).toFixed(1)}M` : `${Math.round(num/1000)}k`}
</td>
)
})}
</tr>
))}
</tbody>
</table>
</div>
</FadeInView>
)}
{/* TAB: Cashflow & Finanzbedarf */}
{activeTab === 'cashflow' && activeResults && (
{/* TAB: Cashflow — from fp_* */}
{activeTab === 'cashflow' && (
<FadeInView delay={0.1}>
<div className="bg-white/[0.05] backdrop-blur-xl border border-white/10 rounded-2xl p-4">
<p className="text-xs text-white/40 mb-3">
{de ? 'Jaehrlicher Cashflow & Finanzbedarf' : 'Annual Cash Flow & Funding Requirements'}
{de ? 'Liquidität & Cashflow (5 Jahre) · Quelle: Finanzplan' : 'Liquidity & Cash Flow (5 Years) · Source: Financial Plan'}
</p>
<AnnualCashflowChart
results={activeResults.results}
initialFunding={initialFunding}
lang={lang}
/>
<div className="grid grid-cols-5 gap-2 items-end h-48">
{[2026,2027,2028,2029,2030].map((y, idx) => {
const liq = fpKPIs[`y${y}`]?.liquiditaet || 0
const ebit = fpKPIs[`y${y}`]?.ebit || 0
const maxAbs = Math.max(...[2026,2027,2028,2029,2030].map(yr => Math.abs(fpKPIs[`y${yr}`]?.liquiditaet || 0)), 1)
const h = Math.abs(liq) / maxAbs * 140
return (
<div key={idx} className="flex flex-col items-center">
<div className="text-[8px] text-white/40 mb-1">{liq >= 1000000 ? `${(liq/1000000).toFixed(1)}M` : liq <= -1000000 ? `${(liq/1000000).toFixed(1)}M` : `${Math.round(liq/1000)}k`}</div>
<div className="w-12 flex flex-col justify-end" style={{ height: '150px' }}>
<div className={`${liq >= 0 ? 'bg-emerald-500/60 rounded-t' : 'bg-red-500/60 rounded-b'} w-full`} style={{ height: `${Math.max(h, 4)}px` }} />
</div>
<span className="text-[10px] text-white/40 mt-1">{y}</span>
<span className={`text-[8px] mt-0.5 ${ebit >= 0 ? 'text-emerald-400/60' : 'text-red-400/60'}`}>
EBIT: {ebit >= 1000000 ? `${(ebit/1000000).toFixed(1)}M` : `${Math.round(ebit/1000)}k`}
</span>
</div>
)
})}
</div>
<div className="flex justify-center gap-6 mt-3 text-[10px]">
<span className="flex items-center gap-1"><span className="w-3 h-2 bg-emerald-500/60 rounded inline-block" /> {de ? 'Liquidität (positiv)' : 'Cash (positive)'}</span>
<span className="flex items-center gap-1"><span className="w-3 h-2 bg-red-500/60 rounded inline-block" /> {de ? 'Liquidität (negativ)' : 'Cash (negative)'}</span>
</div>
</div>
</FadeInView>
)}