import { useState, useCallback, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Wallet, TrendingUp, TrendingDown } from "lucide-react"; import { useDashboard } from "../hooks/useDashboard"; import { PageHelp } from "../components/shared/PageHelp"; import PeriodSelector from "../components/dashboard/PeriodSelector"; import CategoryPieChart from "../components/dashboard/CategoryPieChart"; import CategoriesV1DiscoveryBanner from "../components/dashboard/CategoriesV1DiscoveryBanner"; import CategoryOverTimeChart from "../components/reports/CategoryOverTimeChart"; import BudgetVsActualTable from "../components/reports/BudgetVsActualTable"; import TransactionDetailModal from "../components/shared/TransactionDetailModal"; import type { CategoryBreakdownItem } from "../shared/types"; import { computeDateRange, buildMonthOptions } from "../utils/dateRange"; const fmt = new Intl.NumberFormat("en-CA", { style: "currency", currency: "CAD" }); export default function DashboardPage() { const { t, i18n } = useTranslation(); const { state, setPeriod, setCustomDates, setBudgetMonth } = useDashboard(); const { summary, categoryBreakdown, categoryOverTime, budgetVsActual, period, isLoading } = state; const [hiddenCategories, setHiddenCategories] = useState>(new Set()); const [detailModal, setDetailModal] = useState(null); const toggleHidden = useCallback((name: string) => { setHiddenCategories((prev) => { const next = new Set(prev); if (next.has(name)) next.delete(name); else next.add(name); return next; }); }, []); const showAll = useCallback(() => setHiddenCategories(new Set()), []); const viewDetails = useCallback((item: CategoryBreakdownItem) => { setDetailModal(item); }, []); const balance = summary.totalAmount; const balanceColor = balance > 0 ? "text-[var(--positive)]" : balance < 0 ? "text-[var(--negative)]" : "text-[var(--primary)]"; const cards = [ { labelKey: "dashboard.balance", value: fmt.format(balance), icon: Wallet, color: balanceColor, }, { labelKey: "dashboard.income", value: fmt.format(summary.incomeTotal), icon: TrendingUp, color: "text-[var(--positive)]", }, { labelKey: "dashboard.expenses", value: fmt.format(Math.abs(summary.expenseTotal)), icon: TrendingDown, color: "text-[var(--negative)]", }, ]; const monthOptions = useMemo(() => buildMonthOptions(i18n.language), [i18n.language]); const { dateFrom, dateTo } = computeDateRange(period, state.customDateFrom, state.customDateTo); return (

{t("dashboard.title")}

{cards.map((card) => (
{t(card.labelKey)}

{card.value}

))}

{t("dashboard.expensesByCategory")}

{t("reports.bva.titlePrefix")}

{t("dashboard.expensesOverTime")}

{detailModal && ( setDetailModal(null)} /> )}
); }