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
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:
@@ -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>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user