Remove standalone services (ai-compliance-sdk root, developer-portal, dsms-gateway, dsms-node, night-scheduler) and legacy compliance/dsgvo pages. Add new SDK pipeline modules (academy, document-crawler, dsb-portal, incidents, whistleblower, reporting, sso, multi-tenant, industry-templates). Add drafting engine, legal corpus files (AT/CH/DE), pitch-deck, blog and Förderantrag pages. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
86 lines
2.7 KiB
TypeScript
86 lines
2.7 KiB
TypeScript
'use client'
|
|
|
|
import { FMResult } from '@/lib/types'
|
|
import {
|
|
BarChart,
|
|
Bar,
|
|
XAxis,
|
|
YAxis,
|
|
Tooltip,
|
|
ResponsiveContainer,
|
|
ReferenceLine,
|
|
Cell,
|
|
} from 'recharts'
|
|
|
|
interface WaterfallChartProps {
|
|
results: FMResult[]
|
|
lang: 'de' | 'en'
|
|
}
|
|
|
|
export default function WaterfallChart({ results, lang }: WaterfallChartProps) {
|
|
// Sample quarterly data for cleaner display
|
|
const quarterlyData = results.filter((_, i) => i % 3 === 0).map((r) => {
|
|
const netCash = r.revenue_eur - r.total_costs_eur
|
|
return {
|
|
label: `${r.year.toString().slice(2)}/Q${Math.ceil(r.month_in_year / 3)}`,
|
|
month: r.month,
|
|
revenue: Math.round(r.revenue_eur),
|
|
costs: Math.round(-r.total_costs_eur),
|
|
net: Math.round(netCash),
|
|
cashBalance: Math.round(r.cash_balance_eur),
|
|
}
|
|
})
|
|
|
|
const formatValue = (value: number) => {
|
|
if (Math.abs(value) >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`
|
|
if (Math.abs(value) >= 1_000) return `${(value / 1_000).toFixed(0)}k`
|
|
return value.toString()
|
|
}
|
|
|
|
return (
|
|
<div className="w-full h-[220px]">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<BarChart data={quarterlyData} margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>
|
|
<XAxis
|
|
dataKey="label"
|
|
stroke="rgba(255,255,255,0.3)"
|
|
tick={{ fill: 'rgba(255,255,255,0.4)', fontSize: 9 }}
|
|
interval={1}
|
|
/>
|
|
<YAxis
|
|
stroke="rgba(255,255,255,0.1)"
|
|
tick={{ fill: 'rgba(255,255,255,0.4)', fontSize: 10 }}
|
|
tickFormatter={formatValue}
|
|
/>
|
|
<Tooltip
|
|
contentStyle={{
|
|
background: 'rgba(10, 10, 26, 0.95)',
|
|
border: '1px solid rgba(255,255,255,0.1)',
|
|
borderRadius: 12,
|
|
color: '#fff',
|
|
fontSize: 11,
|
|
}}
|
|
formatter={(value: number, name: string) => [
|
|
formatValue(value) + ' EUR',
|
|
name === 'revenue' ? (lang === 'de' ? 'Umsatz' : 'Revenue')
|
|
: name === 'costs' ? (lang === 'de' ? 'Kosten' : 'Costs')
|
|
: 'Net',
|
|
]}
|
|
/>
|
|
<ReferenceLine y={0} stroke="rgba(255,255,255,0.2)" />
|
|
<Bar dataKey="revenue" radius={[3, 3, 0, 0]} barSize={14}>
|
|
{quarterlyData.map((entry, i) => (
|
|
<Cell key={i} fill="rgba(34, 197, 94, 0.7)" />
|
|
))}
|
|
</Bar>
|
|
<Bar dataKey="costs" radius={[0, 0, 3, 3]} barSize={14}>
|
|
{quarterlyData.map((entry, i) => (
|
|
<Cell key={i} fill="rgba(239, 68, 68, 0.5)" />
|
|
))}
|
|
</Bar>
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
)
|
|
}
|