From 1b5c2a156ce519d6e65075247104d150335cf604 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sat, 28 Mar 2026 23:17:31 +0100 Subject: [PATCH] feat: KPIs + Grafiken Reiter im Finanzplan + ROI korrigiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KPIs Tab: 15 Kennzahlen pro Jahr (2026-2030) MRR, ARR, Kunden, ARPU, Mitarbeiter, Umsatz/MA, Personalkosten, EBIT, EBIT-Marge, Steuern, Jahresüberschuss, Serverkosten/Kunde, Bruttomarge, Burn Rate, Runway Grafiken Tab: - MRR & Kundenentwicklung (Balkendiagramm, 5 Jahre) - EBIT (Rot/Grün je nach Verlust/Gewinn) - Personalaufbau (Balkendiagramm 5→35) ROI korrigiert (Ersparnis ÷ Preis): KMU: 3,5x, Mittelstand: 7,5x, Konzern: 20,8x Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/slides/FinanzplanSlide.tsx | 187 +++++++++++++++++- pitch-deck/components/slides/SavingsSlide.tsx | 6 +- 2 files changed, 185 insertions(+), 8 deletions(-) diff --git a/pitch-deck/components/slides/FinanzplanSlide.tsx b/pitch-deck/components/slides/FinanzplanSlide.tsx index a4a1771..4beb6e0 100644 --- a/pitch-deck/components/slides/FinanzplanSlide.tsx +++ b/pitch-deck/components/slides/FinanzplanSlide.tsx @@ -6,7 +6,7 @@ import { t } from '@/lib/i18n' import GradientText from '../ui/GradientText' import FadeInView from '../ui/FadeInView' import GlassCard from '../ui/GlassCard' -import { RefreshCw, Download, ChevronLeft, ChevronRight } from 'lucide-react' +import { RefreshCw, Download, ChevronLeft, ChevronRight, BarChart3, Target } from 'lucide-react' interface FinanzplanSlideProps { lang: Language @@ -140,6 +140,25 @@ export default function FinanzplanSlide({ lang }: FinanzplanSlideProps) { {s.rows > 0 && ({s.rows})} ))} + {/* KPIs + Grafiken Tabs */} + | + {[ + { id: 'kpis', label: 'KPIs', icon: Target }, + { id: 'charts', label: de ? 'Grafiken' : 'Charts', icon: BarChart3 }, + ].map(tab => ( + + ))}
- {/* Year Navigation — not for GuV (annual view) */} - {activeSheet !== 'guv' && ( + {/* === KPIs Tab === */} + {activeSheet === 'kpis' && ( + +

{de ? 'Wichtige Kennzahlen (pro Jahr)' : 'Key Metrics (per year)'}

+ + + + + {[2026, 2027, 2028, 2029, 2030].map(y => ( + + ))} + + + + {(() => { + // Compute KPIs from loaded data — we need liquidität and umsatz data + // These are approximate since we don't have all sheets loaded simultaneously + const kpiRows = [ + { label: 'MRR (Dez)', values: [6100, 84450, 267950, 517650, 834750], unit: '€', bold: true }, + { label: 'ARR', values: [73200, 1013400, 3215400, 6211800, 10017000], unit: '€', bold: true }, + { label: de ? 'Kunden (Dez)' : 'Customers (Dec)', values: [14, 117, 370, 726, 1200], unit: '', bold: false }, + { label: 'ARPU (MRR/Kunden)', values: [436, 722, 724, 713, 696], unit: '€', bold: false }, + { label: de ? 'Mitarbeiter' : 'Employees', values: [5, 10, 17, 25, 35], unit: '', bold: false }, + { label: de ? 'Umsatz/Mitarbeiter' : 'Revenue/Employee', values: [14640, 101340, 189141, 248472, 286200], unit: '€', bold: false }, + { label: de ? 'Personalkosten' : 'Personnel Costs', values: [58768, 740968, 1353764, 2154301, 3129479], unit: '€', bold: false }, + { label: 'EBIT', values: [-95099, -566293, -4019, 1315689, 3144137], unit: '€', bold: true }, + { label: de ? 'EBIT-Marge' : 'EBIT Margin', values: [-130, -56, -1, 21, 31], unit: '%', bold: false }, + { label: de ? 'Steuern' : 'Taxes', values: [0, 0, 0, 182565, 882717], unit: '€', bold: false }, + { label: de ? 'Jahresüberschuss' : 'Net Income', values: [-95099, -566293, -4019, 1133124, 2261420], unit: '€', bold: true }, + { label: de ? 'Serverkosten/Kunde' : 'Server Cost/Customer', values: [100, 100, 100, 100, 100], unit: '€', bold: false }, + { label: de ? 'Bruttomarge' : 'Gross Margin', values: [100, 100, 92, 90, 88], unit: '%', bold: false }, + { label: 'Burn Rate (Dez)', values: [44734, 28364, 0, 0, 0], unit: '€/Mo', bold: false }, + { label: de ? 'Runway (Monate)' : 'Runway (months)', values: [19, 4, '∞', '∞', '∞'], unit: '', bold: false }, + ] + return kpiRows.map((row, idx) => ( + + + {row.values.map((v, i) => { + const num = typeof v === 'number' ? v : 0 + const display = typeof v === 'string' ? v : ( + row.unit === '%' ? `${v}%` : + row.unit === '€/Mo' ? formatCell(num) + '/Mo' : + formatCell(num) + ) + return ( + + ) + })} + + )) + })()} + +
KPI{y}
{row.label} + {display} +
+
+ )} + + {/* === Charts Tab === */} + {activeSheet === 'charts' && ( +
+ {/* MRR + Kunden Chart */} + +

{de ? 'MRR & Kundenentwicklung' : 'MRR & Customer Growth'}

+
+ {[ + { year: '2026', mrr: 6100, cust: 14, max_mrr: 834750, max_cust: 1200 }, + { year: '2027', mrr: 84450, cust: 117, max_mrr: 834750, max_cust: 1200 }, + { year: '2028', mrr: 267950, cust: 370, max_mrr: 834750, max_cust: 1200 }, + { year: '2029', mrr: 517650, cust: 726, max_mrr: 834750, max_cust: 1200 }, + { year: '2030', mrr: 834750, cust: 1200, max_mrr: 834750, max_cust: 1200 }, + ].map((d, idx) => ( +
+
+ {/* MRR bar */} +
+
+ {d.mrr >= 100000 ? `${Math.round(d.mrr/1000)}k` : d.mrr.toLocaleString('de-DE')} +
+
+ {/* Kunden bar */} +
+
{d.cust}
+
+
+ {d.year} +
+ ))} +
+
+ MRR (€) + {de ? 'Kunden' : 'Customers'} +
+
+ + {/* EBIT + Cash Chart */} +
+ +

EBIT

+
+ {[ + { year: '2026', val: -95099 }, + { year: '2027', val: -566293 }, + { year: '2028', val: -4019 }, + { year: '2029', val: 1315689 }, + { year: '2030', val: 3144137 }, + ].map((d, idx) => { + const maxAbs = 3144137 + const h = Math.abs(d.val) / maxAbs * 100 + return ( +
+
+ {d.val >= 0 ? ( +
+
{Math.round(d.val/1000)}k
+
+ ) : ( +
+
+
{Math.round(d.val/1000)}k
+
+
+ )} +
+ {d.year} +
+ ) + })} +
+
+ + +

{de ? 'Personalaufbau' : 'Headcount'}

+
+ {[ + { year: '2026', val: 5 }, + { year: '2027', val: 10 }, + { year: '2028', val: 17 }, + { year: '2029', val: 25 }, + { year: '2030', val: 35 }, + ].map((d, idx) => ( +
+
+
+
{d.val}
+
+
+ {d.year} +
+ ))} +
+
+
+
+ )} + + {/* Year Navigation — not for GuV, KPIs, Charts (annual views) */} + {!['guv', 'kpis', 'charts'].includes(activeSheet) && (
)} - {/* Data Grid */} + {/* Data Grid — not shown for KPIs and Charts */} + {!['kpis', 'charts'].includes(activeSheet) && ( {loading ? (
{de ? 'Lade...' : 'Loading...'}
@@ -330,10 +506,11 @@ export default function FinanzplanSlide({ lang }: FinanzplanSlideProps) { )}
+ )}

{de - ? 'Doppelklick auf blaue Zellen zum Bearbeiten · Gruendung: 01.08.2026' + ? 'Doppelklick auf blaue Zellen zum Bearbeiten · Gründung: 01.08.2026' : 'Double-click blue cells to edit · Founding: 01.08.2026'}

diff --git a/pitch-deck/components/slides/SavingsSlide.tsx b/pitch-deck/components/slides/SavingsSlide.tsx index 7fcb3df..8f5432c 100644 --- a/pitch-deck/components/slides/SavingsSlide.tsx +++ b/pitch-deck/components/slides/SavingsSlide.tsx @@ -32,7 +32,7 @@ export default function SavingsSlide({ lang }: SavingsSlideProps) { totalWithout: '97.750', totalWith: '44.530', totalSave: '53.220', - roi: '9,1x', + roi: '3,5x', }, { icon: Factory, @@ -52,7 +52,7 @@ export default function SavingsSlide({ lang }: SavingsSlideProps) { totalWithout: '419.500', totalWith: '193.880', totalSave: '225.620', - roi: '12,6x', + roi: '7,5x', }, { icon: Building, @@ -72,7 +72,7 @@ export default function SavingsSlide({ lang }: SavingsSlideProps) { totalWithout: '2.113.500', totalWith: '1.074.080', totalSave: '1.039.420', - roi: '17,4x', + roi: '20,8x', }, ]