budget-view-finance/src/pages/Index.tsx
gpt-engineer-app[bot] 2990ab9d30 Fix type and import errors
Fixes import errors in `src/pages/Index.tsx` and `src/pages/Metas.tsx`. Addresses missing properties and incorrect function calls.
2025-06-24 18:07:54 +00:00

185 lines
6.8 KiB
TypeScript

import { useState, useEffect } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { useToast } from "@/hooks/use-toast";
import { ArrowUpIcon, ArrowDownIcon, CreditCardIcon, Target } from "lucide-react";
import { getResumoFinanceiro, getCategorySummary } from "@/services/transacao";
import { ResumoFinanceiro, CategorySummary } from "@/types/financialTypes";
import TransactionsTable from "@/components/dashboard/TransactionsTable";
import { useTransactions } from "@/hooks/useTransactions";
import CategoryChart from "@/components/dashboard/CategoryChart";
const Dashboard = () => {
const [resumo, setResumo] = useState<ResumoFinanceiro | null>(null);
const [categories, setCategories] = useState<CategorySummary[]>([]);
const [isLoading, setIsLoading] = useState(true);
const { toast } = useToast();
const getCurrentMonth = () => {
const now = new Date();
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
};
const {
transactions,
isLoading: transactionsLoading,
formatCurrency
} = useTransactions({ monthFilter: getCurrentMonth() });
useEffect(() => {
const storedUserId = localStorage.getItem('userId');
const finDashUser = localStorage.getItem('finDashUser');
if (!storedUserId && finDashUser) {
localStorage.setItem('userId', finDashUser);
} else if (!storedUserId && !finDashUser) {
const defaultId = '9f267008-9128-4a2f-b730-de0a0b5602a9';
localStorage.setItem('userId', defaultId);
}
}, []);
const loadResumo = async () => {
try {
setIsLoading(true);
console.log("Carregando resumo financeiro...");
const data = await getResumoFinanceiro();
console.log("Resumo carregado:", data);
setResumo(data);
// Load categories for chart
const categoriesData = await getCategorySummary('despesa');
setCategories(categoriesData);
} catch (error) {
console.error("Erro ao carregar resumo:", error);
toast({
title: "Erro ao carregar resumo",
description: "Não foi possível obter os dados do Supabase",
variant: "destructive"
});
} finally {
setIsLoading(false);
}
};
useEffect(() => {
loadResumo();
}, [toast]);
if (isLoading) {
return (
<div className="space-y-6">
<div className="grid gap-4 md:grid-cols-4">
{[1, 2, 3, 4].map((i) => (
<Card key={i}>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<div className="h-4 bg-muted rounded w-1/2 animate-pulse"></div>
<div className="h-4 w-4 bg-muted rounded animate-pulse"></div>
</CardHeader>
<CardContent>
<div className="h-8 bg-muted rounded w-3/4 mb-2 animate-pulse"></div>
<div className="h-3 bg-muted rounded w-1/2 animate-pulse"></div>
</CardContent>
</Card>
))}
</div>
</div>
);
}
return (
<div className="space-y-6" data-tour="dashboard-content">
<div className="flex items-center justify-between">
<h1 className="text-2xl font-bold tracking-tight">Dashboard</h1>
</div>
<div className="grid gap-4 md:grid-cols-4">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Total Receitas</CardTitle>
<ArrowUpIcon className="h-4 w-4 text-green-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-green-600">
{resumo ? formatCurrency(resumo.totalReceitas) : 'R$ 0,00'}
</div>
<p className="text-xs text-muted-foreground">Entradas do mês</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Total Despesas</CardTitle>
<ArrowDownIcon className="h-4 w-4 text-red-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-red-600">
{resumo ? formatCurrency(resumo.totalDespesas) : 'R$ 0,00'}
</div>
<p className="text-xs text-muted-foreground">Saídas do mês</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Cartões de Crédito</CardTitle>
<CreditCardIcon className="h-4 w-4 text-blue-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-blue-600">
{resumo ? formatCurrency(resumo.totalCartoes || 0) : 'R$ 0,00'}
</div>
<p className="text-xs text-muted-foreground">Gastos nos cartões</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Saldo</CardTitle>
<Target className="h-4 w-4 text-purple-600" />
</CardHeader>
<CardContent>
<div className={`text-2xl font-bold ${
resumo && (resumo.totalReceitas - resumo.totalDespesas - (resumo.totalCartoes || 0)) >= 0
? 'text-green-600'
: 'text-red-600'
}`}>
{resumo ? formatCurrency(resumo.totalReceitas - resumo.totalDespesas - (resumo.totalCartoes || 0)) : 'R$ 0,00'}
</div>
<p className="text-xs text-muted-foreground">Resultado do mês</p>
</CardContent>
</Card>
</div>
<div className="grid gap-6 md:grid-cols-2">
<Card className="md:col-span-1">
<CardHeader>
<CardTitle>Despesas por Categoria</CardTitle>
<CardDescription>Distribuição dos seus gastos</CardDescription>
</CardHeader>
<CardContent>
<CategoryChart categories={categories} isLoading={isLoading} />
</CardContent>
</Card>
<Card className="md:col-span-1">
<CardHeader>
<CardTitle>Últimas Transações</CardTitle>
<CardDescription>Suas transações mais recentes</CardDescription>
</CardHeader>
<CardContent>
<TransactionsTable
transactions={transactions.slice(0, 5)}
isLoading={transactionsLoading}
showPagination={false}
onEdit={() => {}}
onDelete={() => {}}
/>
</CardContent>
</Card>
</div>
</div>
);
};
export default Dashboard;