at main 4.9 kB view raw
1'use client' 2 3import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts' 4import { FundingHistory } from '@/lib/types' 5 6interface FundingChartProps { 7 fundingHistory: FundingHistory[] 8 sustainableRevenuePercent: number 9} 10 11export default function FundingChart({ fundingHistory, sustainableRevenuePercent }: FundingChartProps) { 12 // Process funding history for time series 13 const timeSeriesData = fundingHistory.map(item => ({ 14 date: new Date(item.date).toLocaleDateString('en-US', { month: 'short', year: 'numeric' }), 15 amount: item.amount / 1000000, // Convert to millions 16 type: item.type 17 })) 18 19 // Prepare pie chart data 20 const pieData = [ 21 { name: 'Sustainable Revenue', value: sustainableRevenuePercent, color: '#64748b' }, 22 { name: 'Grants & Investments', value: 100 - sustainableRevenuePercent, color: '#e2e8f0' } 23 ] 24 25 return ( 26 <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6"> 27 {/* Funding Timeline */} 28 <div className="bg-surface p-4 sm:p-6 border-subtle shadow-card"> 29 <h3 className="text-lg sm:text-2xl font-serif font-medium text-primary tracking-tight mb-4 sm:mb-6">Funding Timeline</h3> 30 <div className="h-64 sm:h-80"> 31 <ResponsiveContainer width="100%" height="100%"> 32 <LineChart data={timeSeriesData}> 33 <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" /> 34 <XAxis dataKey="date" tick={{ fill: 'var(--text-secondary)', fontSize: '12px' }} /> 35 <YAxis 36 label={{ value: 'Amount ($M)', angle: -90, position: 'insideLeft', fill: 'var(--text-secondary)', fontSize: '12px' }} 37 tick={{ fill: 'var(--text-secondary)', fontSize: '12px' }} 38 /> 39 <Tooltip 40 formatter={(value: number) => [`$${value.toFixed(1)}M`]} 41 labelFormatter={(label) => `${label}`} 42 contentStyle={{ 43 backgroundColor: 'var(--surface)', 44 border: '1px solid var(--border)', 45 borderRadius: '6px', 46 color: 'var(--text-primary)', 47 fontSize: '12px' 48 }} 49 labelStyle={{ color: 'var(--text-secondary)' }} 50 /> 51 <Line 52 type="monotone" 53 dataKey="amount" 54 stroke="var(--accent)" 55 strokeWidth={2} 56 dot={{ fill: 'var(--accent)', strokeWidth: 2, r: 3 }} 57 /> 58 </LineChart> 59 </ResponsiveContainer> 60 </div> 61 </div> 62 63 {/* Revenue Sustainability */} 64 <div className="bg-surface p-4 sm:p-6 border-subtle shadow-card"> 65 <h3 className="text-lg sm:text-2xl font-serif font-medium text-primary tracking-tight mb-4 sm:mb-6">Revenue Sustainability</h3> 66 <div className="h-48 sm:h-64 flex items-center justify-center"> 67 <ResponsiveContainer width="100%" height="100%"> 68 <PieChart> 69 <Pie 70 data={pieData} 71 cx="50%" 72 cy="50%" 73 innerRadius={40} 74 outerRadius={80} 75 paddingAngle={5} 76 dataKey="value" 77 > 78 {pieData.map((entry, index) => ( 79 <Cell key={`cell-${index}`} fill={entry.color} /> 80 ))} 81 </Pie> 82 <Tooltip 83 formatter={(value: number) => `${value}%`} 84 contentStyle={{ 85 backgroundColor: 'var(--surface)', 86 border: '1px solid var(--border)', 87 borderRadius: '6px', 88 color: 'var(--text-primary)', 89 fontSize: '12px' 90 }} 91 labelStyle={{ color: 'var(--text-secondary)' }} 92 /> 93 </PieChart> 94 </ResponsiveContainer> 95 </div> 96 <div className="mt-4 sm:mt-6 space-y-2 sm:space-y-3"> 97 <div className="flex items-center justify-between"> 98 <div className="flex items-center space-x-2 sm:space-x-3"> 99 <div className="w-3 h-3 rounded-full bg-accent"></div> 100 <span className="text-xs sm:text-sm text-secondary">Sustainable Revenue</span> 101 </div> 102 <span className="text-xs sm:text-sm font-medium text-primary">{sustainableRevenuePercent}%</span> 103 </div> 104 <div className="flex items-center justify-between"> 105 <div className="flex items-center space-x-2 sm:space-x-3"> 106 <div className="w-3 h-3 rounded-full bg-border"></div> 107 <span className="text-xs sm:text-sm text-secondary">Grants & Investments</span> 108 </div> 109 <span className="text-xs sm:text-sm font-medium text-primary">{100 - sustainableRevenuePercent}%</span> 110 </div> 111 </div> 112 </div> 113 </div> 114 ) 115}