import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { useToast } from "@/hooks/use-toast"; import Sidebar from "@/components/layout/Sidebar"; import { Plus, DollarSign, TrendingUp, TrendingDown } from "lucide-react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { apiRequest } from "@/lib/queryClient"; export default function FinancesPage() { const { toast } = useToast(); const queryClient = useQueryClient(); const [open, setOpen] = useState(false); const [newRecord, setNewRecord] = useState({ type: "expense", amount: "", description: "", category: "", }); const { data: recordsResponse, isLoading: recordsLoading } = useQuery({ queryKey: ["/api/financial/records"], }); const { data: summaryResponse, isLoading: summaryLoading } = useQuery({ queryKey: ["/api/financial/summary"], }); const records = (recordsResponse as any)?.records || []; const summary = (summaryResponse as any)?.summary || { income: 0, expenses: 0, net: 0 }; const createRecordMutation = useMutation({ mutationFn: async (record: typeof newRecord) => { const response = await fetch("/api/financial/records", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ...record, amount: parseFloat(record.amount), }), credentials: "include", }); if (!response.ok) throw new Error("Failed to create record"); return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/financial/records"] }); queryClient.invalidateQueries({ queryKey: ["/api/financial/summary"] }); setOpen(false); setNewRecord({ type: "expense", amount: "", description: "", category: "" }); toast({ title: "Record created", description: "Your financial record has been successfully created.", }); }, onError: () => { toast({ title: "Error", description: "Failed to create record. Please try again.", variant: "destructive", }); }, }); const handleCreateRecord = (e: React.FormEvent) => { e.preventDefault(); if (!newRecord.amount || isNaN(parseFloat(newRecord.amount))) { toast({ title: "Invalid amount", description: "Please enter a valid amount.", variant: "destructive", }); return; } createRecordMutation.mutate(newRecord); }; const categories = { income: ["Salary", "Freelance", "Investment", "Business", "Other"], expense: ["Food", "Transportation", "Housing", "Entertainment", "Healthcare", "Shopping", "Other"], }; if (recordsLoading || summaryLoading) { return (
{[1, 2, 3].map((i) => (
))}
); } return (

Finances

Track your income, expenses, and financial goals

Add Financial Record Add a new income or expense record.
setNewRecord({ ...newRecord, amount: e.target.value })} required />
setNewRecord({ ...newRecord, description: e.target.value })} />
{/* Summary Cards */}
Total Income
${summary.income.toFixed(2)}
Total Expenses
${summary.expenses.toFixed(2)}
Net Balance
= 0 ? 'text-green-600' : 'text-red-600'}`}> ${summary.net.toFixed(2)}
{/* Records List */} Recent Transactions Your latest financial transactions {records.length === 0 ? (

No records yet

Start tracking your finances by adding your first record.

) : (
{records.map((record: any) => (
{record.type === 'income' ? : }
{record.description || record.category}
{record.category} • {new Date(record.createdAt).toLocaleDateString()}
{record.type === 'income' ? '+' : '-'}${record.amount.toFixed(2)}
{record.type}
))}
)}
); }