import { AmountDisplay } from '@/components/ui/amount-display'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { cn } from '@/lib/utils'; import { cashflow } from '@/routes'; import { SharedData } from '@/types'; import { __ } from '@/utils/i18n'; import { Link, usePage } from '@inertiajs/react'; import { endOfMonth, format, startOfMonth } from 'date-fns'; import { ArrowRight, TrendingDown, TrendingUp } from 'lucide-react'; import { useEffect, useState } from 'react'; interface CashflowSummary { income: number; expense: number; net: number; savings_rate: number; } interface CashflowSummaryCardProps { loading?: boolean; } export function CashflowSummaryCard({ loading }: CashflowSummaryCardProps) { const { auth } = usePage().props; const [data, setData] = useState<{ current: CashflowSummary; previous: CashflowSummary; } | null>(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchData = async () => { try { const now = new Date(); const from = format(startOfMonth(now), 'yyyy-MM-dd'); const to = format(endOfMonth(now), 'yyyy-MM-dd'); const params = new URLSearchParams({ from, to }); const response = await fetch( `/api/cashflow/summary?${params.toString()}`, ); const result = await response.json(); setData(result); } catch (error) { console.error('Failed to fetch cashflow summary:', error); } finally { setIsLoading(false); } }; fetchData(); }, []); if (!auth?.user || isLoading || loading) { return ( {__('Cashflow')}
{Array.from({ length: 3 }).map((_, i) => (
))}
); } if (!data) { return null; } const { current } = data; const isPositiveNet = current.net >= 0; return (
{__('Cashflow')} {__('View details')}
{__("This month's income and expenses")}
{/* Income */}

{__('Income')}

{/* Expenses */}

{__('Expenses')}

{/* Net */}

{__('Net')}

{isPositiveNet ? ( ) : ( )}
{/* Savings rate footer */}
{__('Savings rate')} = 20 ? 'text-green-600 dark:text-green-400' : current.savings_rate >= 0 ? 'text-yellow-600 dark:text-yellow-400' : 'text-red-600 dark:text-red-400', )} > {current.savings_rate.toFixed(1)}%
); }