You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
11 KiB
TypeScript
199 lines
11 KiB
TypeScript
"use client";
|
|
|
|
import { Card, CardHeader, CardTitle, CardContent, CardDescription } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
BarChart3,
|
|
PieChart as PieChartIcon,
|
|
Download,
|
|
Calendar,
|
|
ChevronDown,
|
|
TrendingUp,
|
|
ArrowUpRight,
|
|
FileText,
|
|
Filter
|
|
} from "lucide-react";
|
|
import {
|
|
BarChart,
|
|
Bar,
|
|
XAxis,
|
|
YAxis,
|
|
CartesianGrid,
|
|
Tooltip,
|
|
ResponsiveContainer,
|
|
AreaChart,
|
|
Area,
|
|
PieChart,
|
|
Cell,
|
|
Pie
|
|
} from "recharts";
|
|
|
|
const cashFlowData = [
|
|
{ name: 'Jul', incoming: 45000, outgoing: 32000 },
|
|
{ name: 'Aug', incoming: 52000, outgoing: 38000 },
|
|
{ name: 'Sep', incoming: 48000, outgoing: 41000 },
|
|
{ name: 'Oct', incoming: 61000, outgoing: 45000 },
|
|
{ name: 'Nov', incoming: 55000, outgoing: 42000 },
|
|
{ name: 'Dec', incoming: 67000, outgoing: 48000 },
|
|
{ name: 'Jan', incoming: 72000, outgoing: 51000 },
|
|
{ name: 'Feb', incoming: 69000, outgoing: 55000 },
|
|
];
|
|
|
|
const categoryData = [
|
|
{ name: 'Payroll', value: 45, color: '#4f46e5' },
|
|
{ name: 'Marketing', value: 20, color: '#8b5cf6' },
|
|
{ name: 'Infrastructure', value: 15, color: '#10b981' },
|
|
{ name: 'Operations', value: 12, color: '#f59e0b' },
|
|
{ name: 'Legal/Other', value: 8, color: '#ef4444' },
|
|
];
|
|
|
|
export default function ReportsPage() {
|
|
return (
|
|
<div className="space-y-8 animate-in fade-in slide-in-from-bottom-2 duration-500 pb-12">
|
|
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
|
<div>
|
|
<h2 className="text-3xl font-black tracking-tight italic">Financial Intel</h2>
|
|
<p className="text-neutral-500 mt-1 font-medium text-lg">Detailed P&L and Cash Flow analysis for the current fiscal year.</p>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<Button variant="outline" className="rounded-2xl border-neutral-200 h-14 px-6 gap-2 font-bold group">
|
|
<Calendar className="w-5 h-5 text-neutral-400" />
|
|
FY 2024
|
|
<ChevronDown className="w-4 h-4 text-neutral-400" />
|
|
</Button>
|
|
<Button className="bg-indigo-600 hover:bg-indigo-700 text-white rounded-2xl h-14 px-8 font-black shadow-2xl transition-all active:scale-95 flex items-center gap-2">
|
|
<Download className="w-5 h-5" />
|
|
Executive Summary
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 xl:grid-cols-3 gap-8">
|
|
<Card className="xl:col-span-2 border-none shadow-2xl shadow-black/5 bg-white dark:bg-neutral-900 rounded-[3rem] p-10 overflow-hidden relative">
|
|
<div className="flex justify-between items-start mb-10 relative z-10">
|
|
<div>
|
|
<h3 className="text-2xl font-black tracking-tighter">Net Cash Flow Trajectory</h3>
|
|
<p className="text-neutral-500 font-medium text-sm mt-1">Comparison of gross inflows vs primary outflows</p>
|
|
</div>
|
|
<div className="p-4 bg-emerald-50 dark:bg-emerald-900/20 text-emerald-600 rounded-2xl flex items-center gap-2 font-black text-sm shadow-sm">
|
|
<TrendingUp className="w-4 h-4" />
|
|
+18.4%
|
|
</div>
|
|
</div>
|
|
|
|
<div className="h-[400px] w-full relative z-10">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<AreaChart data={cashFlowData}>
|
|
<defs>
|
|
<linearGradient id="colorInc" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="5%" stopColor="#4f46e5" stopOpacity={0.1} />
|
|
<stop offset="95%" stopColor="#4f46e5" stopOpacity={0} />
|
|
</linearGradient>
|
|
<linearGradient id="colorOut" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="5%" stopColor="#ef4444" stopOpacity={0.05} />
|
|
<stop offset="95%" stopColor="#ef4444" stopOpacity={0} />
|
|
</linearGradient>
|
|
</defs>
|
|
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f0f0f0" />
|
|
<XAxis dataKey="name" axisLine={false} tickLine={false} tick={{ fill: '#a3a3a3', fontSize: 12, fontWeight: 700 }} />
|
|
<YAxis axisLine={false} tickLine={false} tick={{ fill: '#a3a3a3', fontSize: 12, fontWeight: 700 }} tickFormatter={(v) => `$${v / 1000}k`} />
|
|
<Tooltip
|
|
contentStyle={{ borderRadius: '24px', border: 'none', boxShadow: '0 20px 25px -5px rgb(0 0 0 / 0.1)', padding: '20px' }}
|
|
itemStyle={{ fontWeight: 800, fontSize: '14px' }}
|
|
/>
|
|
<Area type="monotone" dataKey="incoming" stroke="#4f46e5" strokeWidth={4} fillOpacity={1} fill="url(#colorInc)" />
|
|
<Area type="monotone" dataKey="outgoing" stroke="#ef4444" strokeWidth={4} fillOpacity={1} fill="url(#colorOut)" strokeDasharray="8 8" />
|
|
</AreaChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
|
|
<div className="absolute top-0 right-0 w-64 h-64 bg-indigo-500/5 blur-[100px] rounded-full -mr-32 -mt-32" />
|
|
</Card>
|
|
|
|
<Card className="border-none shadow-2xl shadow-black/5 bg-white dark:bg-neutral-900 rounded-[3rem] p-10 flex flex-col items-center">
|
|
<h3 className="text-xl font-black mb-8 w-full">Expense Allocation</h3>
|
|
<div className="h-[280px] w-full mb-10">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<PieChart>
|
|
<Pie
|
|
data={categoryData}
|
|
cx="50%"
|
|
cy="50%"
|
|
innerRadius={80}
|
|
outerRadius={120}
|
|
paddingAngle={8}
|
|
dataKey="value"
|
|
stroke="none"
|
|
>
|
|
{categoryData.map((entry, index) => (
|
|
<Cell key={`cell-${index}`} fill={entry.color} />
|
|
))}
|
|
</Pie>
|
|
<Tooltip
|
|
contentStyle={{ borderRadius: '20px', border: 'none', boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1)' }}
|
|
/>
|
|
</PieChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
<div className="w-full space-y-4">
|
|
{categoryData.map((c) => (
|
|
<div key={c.name} className="flex justify-between items-center group cursor-pointer">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-3 h-3 rounded-full" style={{ backgroundColor: c.color }} />
|
|
<span className="font-bold text-sm text-neutral-600 dark:text-neutral-400 group-hover:text-neutral-900 transition-colors">{c.name}</span>
|
|
</div>
|
|
<div className="flex items-center gap-4">
|
|
<span className="font-black text-sm">{c.value}%</span>
|
|
<ChevronDown className="w-4 h-4 text-neutral-200" />
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mt-8">
|
|
{[
|
|
{ label: 'EBITDA', value: '$240k', trend: '+12%', sub: 'Earnings' },
|
|
{ label: 'OPEX', value: '$180k', trend: '-2.4%', sub: 'Operating' },
|
|
{ label: 'LTV/CAC', value: '4.2x', trend: '+0.5x', sub: 'Efficiency' },
|
|
{ label: 'Burn Rate', value: '$45k', trend: 'Stable', sub: 'Monthly' },
|
|
].map((stat, i) => (
|
|
<Card key={i} className="border-none shadow-xl shadow-black/5 bg-white dark:bg-neutral-900 rounded-[2rem] p-8 hover:bg-neutral-50 transition-colors cursor-pointer group">
|
|
<p className="text-[10px] font-black text-neutral-400 uppercase tracking-widest mb-1">{stat.label}</p>
|
|
<p className="text-3xl font-black text-neutral-900 dark:text-neutral-100 group-hover:text-indigo-600 transition-colors">{stat.value}</p>
|
|
<div className="mt-4 flex justify-between items-center">
|
|
<span className="text-xs font-bold text-neutral-500">{stat.sub}</span>
|
|
<span className={`text-xs font-black p-1 px-2 rounded-lg ${stat.trend.startsWith('+') ? 'bg-emerald-50 text-emerald-600' :
|
|
stat.trend.startsWith('-') ? 'bg-rose-50 text-rose-600' : 'bg-neutral-100 text-neutral-400'
|
|
}`}>
|
|
{stat.trend}
|
|
</span>
|
|
</div>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
|
|
<Card className="border-none shadow-2xl shadow-black/5 bg-neutral-900 rounded-[3rem] p-10 text-white mt-8 overflow-hidden relative">
|
|
<div className="relative z-10 flex flex-col lg:flex-row items-center justify-between gap-8">
|
|
<div className="flex-1">
|
|
<h3 className="text-2xl font-black mb-2">Automated P&L Audit</h3>
|
|
<p className="text-neutral-400 font-medium">Generate a comprehensive profit and loss statement for external audit in minutes.</p>
|
|
</div>
|
|
<div className="flex items-center gap-4">
|
|
<Button variant="outline" className="rounded-2xl h-14 px-8 border-white/20 text-white hover:bg-white/10 font-bold">
|
|
<Filter className="w-5 h-5 mr-1" />
|
|
Configure Rules
|
|
</Button>
|
|
<Button className="bg-indigo-600 hover:bg-indigo-500 text-white rounded-2xl h-14 px-10 font-black shadow-2xl shadow-indigo-500/20">
|
|
<FileText className="w-6 h-6 mr-2" />
|
|
Generate P&L
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
<div className="absolute top-1/2 left-0 -translate-y-1/2 -ml-20 w-64 h-64 bg-indigo-500/10 rounded-full blur-[80px]" />
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|