Fix: WhatsApp instance refresh and expense summary

- Fixed an issue where the "Atualizar Lista" button in the WhatsApp connect menu was not correctly displaying created instances.
- Implemented the display of credit card expenses in the transaction and dashboard summaries. The summaries now include the total expenses for each credit card, aggregated with other transaction expenses.
This commit is contained in:
gpt-engineer-app[bot] 2025-05-20 23:26:56 +00:00
parent afb53c1429
commit 04ed74ac61
6 changed files with 78 additions and 15 deletions

View File

@ -1,20 +1,26 @@
import React from 'react';
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ArrowDown, CreditCard, Wallet } from 'lucide-react';
interface TransactionSummaryCardsProps {
totalReceitas: number;
totalDespesas: number;
totalCartoes: number;
formatCurrency: (value: number) => string;
}
export const TransactionSummaryCards = ({
totalReceitas,
totalDespesas,
totalCartoes,
formatCurrency
}: TransactionSummaryCardsProps) => {
// Calculate the grand total of all expenses
const totalGeral = totalDespesas + totalCartoes;
return (
<div className="grid gap-4 md:grid-cols-2">
<div className="grid gap-4 md:grid-cols-3">
<Card>
<CardHeader className="pb-2 bg-green-50">
<CardTitle className="text-finance-green flex items-center">
@ -31,6 +37,7 @@ export const TransactionSummaryCards = ({
<Card>
<CardHeader className="pb-2 bg-red-50">
<CardTitle className="text-finance-red flex items-center">
<ArrowDown className="h-4 w-4 mr-2" />
Gastos do mês
</CardTitle>
</CardHeader>
@ -40,6 +47,24 @@ export const TransactionSummaryCards = ({
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2 bg-blue-50">
<CardTitle className="text-finance-blue flex items-center">
<CreditCard className="h-4 w-4 mr-2" />
Gastos em cartões
</CardTitle>
</CardHeader>
<CardContent className="pt-4 space-y-1">
<p className="text-2xl font-bold text-finance-blue">
{formatCurrency(totalCartoes)}
</p>
<div className="flex items-center justify-between pt-2 text-sm border-t">
<span className="text-muted-foreground">Total geral:</span>
<span className="font-medium text-finance-red">{formatCurrency(totalGeral)}</span>
</div>
</CardContent>
</Card>
</div>
);
};

View File

@ -113,6 +113,9 @@ export const useTransactions = () => {
// Calcular totais
const totalReceitas = receitas.reduce((sum, t) => sum + Math.abs(t.valor), 0);
const totalDespesas = despesas.reduce((sum, t) => sum + Math.abs(t.valor), 0);
// Calcular total de despesas de cartão
const totalCartoes = cartoes.reduce((sum, cartao) => sum + (cartao.total_despesas || 0), 0);
const formatCurrency = (value: number) => {
return new Intl.NumberFormat('pt-BR', {
@ -132,6 +135,7 @@ export const useTransactions = () => {
cartoes,
totalReceitas,
totalDespesas,
totalCartoes,
formatCurrency,
handleTransactionSuccess,
handleDespesaCartaoSuccess,

View File

@ -33,13 +33,20 @@ export const useInstanceRefresh = (
const savedInstanceName = localStorage.getItem(`whatsapp_instance_name_${currentUserId}`);
console.log("Saved instance name for current user:", savedInstanceName);
// Filtra as instâncias pelo nome criado pelo usuário
// Filtra as instâncias pelo nome criado pelo usuário, se houver um nome salvo
// Senão, usa todas as instâncias retornadas pela API
const filteredInstances = savedInstanceName
? response.instances.filter(instance => instance.instanceName === savedInstanceName)
: response.instances;
if (filteredInstances.length > 0) {
console.log(`Found ${filteredInstances.length} instances matching saved name:`, filteredInstances);
} else {
console.log("No instances found matching saved name, using all instances:", response.instances);
}
// Mapeia as instâncias do servidor para o formato correto com userId
const serverInstances: WhatsAppInstance[] = filteredInstances
const serverInstances: WhatsAppInstance[] = (filteredInstances.length > 0 ? filteredInstances : response.instances)
.map(serverInstance => {
// Ensure we convert server state to valid connectionState
let connectionState: 'open' | 'closed' | 'connecting';
@ -62,22 +69,22 @@ export const useInstanceRefresh = (
};
});
console.log("Filtered server instances for this user:", serverInstances);
console.log("Parsed server instances for this user:", serverInstances);
if (serverInstances.length > 0) {
setInstances(serverInstances);
toast({
title: "Sucesso",
description: `${serverInstances.length} instância(s) encontrada(s) para este usuário`,
description: `${serverInstances.length} instância(s) encontrada(s)`,
});
} else {
// Clear instances if none found for this user
// Clear instances if none found
setInstances([]);
toast({
title: "Aviso",
description: "Nenhuma instância encontrada para este usuário",
description: "Nenhuma instância encontrada. Você pode criar uma nova instância agora.",
});
}
} else {

View File

@ -5,17 +5,18 @@ import SummaryCard from '@/components/dashboard/SummaryCard';
import TransactionsTable from '@/components/dashboard/TransactionsTable';
import CategoryChart from '@/components/dashboard/CategoryChart';
import MonthlyChart from '@/components/dashboard/MonthlyChart';
import { Wallet, ArrowUp, ArrowDown, PiggyBank } from 'lucide-react';
import { Wallet, ArrowUp, ArrowDown, PiggyBank, CreditCard } from 'lucide-react';
import { Transaction, CategorySummary, MonthlyData } from '@/types/financialTypes';
import { useToast } from "@/components/ui/use-toast";
import { getTransacoes, getTransactionSummary, getCategorySummary, getMonthlyData } from '@/services/transacaoService';
import { getCartoes } from '@/services/cartaoCreditoService';
const Dashboard = () => {
const [isLoading, setIsLoading] = useState(true);
const [transactions, setTransactions] = useState<Transaction[]>([]);
const [categories, setCategories] = useState<CategorySummary[]>([]);
const [monthlyData, setMonthlyData] = useState<MonthlyData[]>([]);
const [totals, setTotals] = useState({ receitas: 0, despesas: 0, saldo: 0 });
const [totals, setTotals] = useState({ receitas: 0, despesas: 0, saldo: 0, cartoes: 0 });
const { toast } = useToast();
// Use useCallback to ensure this function doesn't change on every render
@ -44,22 +45,33 @@ const Dashboard = () => {
console.log("Iniciando carregamento de dados...");
// Buscar todos os dados necessários
const [transacoesData, totalsData, categoriesData, monthlyDataResult] = await Promise.all([
const [transacoesData, totalsData, categoriesData, monthlyDataResult, cartoesData] = await Promise.all([
getTransacoes(),
getTransactionSummary(),
getCategorySummary(),
getMonthlyData()
getMonthlyData(),
getCartoes()
]);
// Calcular total dos cartões
const totalCartoes = cartoesData.reduce((sum, cartao) => sum + (cartao.total_despesas || 0), 0);
console.log("Dados obtidos com sucesso:", {
transacoes: transacoesData.length,
totals: totalsData,
categories: categoriesData.length,
monthlyData: monthlyDataResult.length
monthlyData: monthlyDataResult.length,
cartoes: cartoesData.length,
totalCartoes: totalCartoes
});
setTransactions(transacoesData);
setTotals(totalsData);
setTotals({
...totalsData,
cartoes: totalCartoes,
// Atualiza o saldo incluindo despesas de cartão
saldo: totalsData.receitas - totalsData.despesas - totalCartoes
});
setCategories(categoriesData);
setMonthlyData(monthlyDataResult);
@ -91,6 +103,9 @@ const Dashboard = () => {
}).format(value);
};
// Calculate total of all expenses (regular + credit cards)
const totalDespesasGeral = totals.despesas + totals.cartoes;
return (
<Layout>
<div className="space-y-6">
@ -112,7 +127,8 @@ const Dashboard = () => {
/>
<SummaryCard
title="Despesas"
value={formatCurrency(totals.despesas)}
value={formatCurrency(totalDespesasGeral)}
secondaryValue={`Cartões: ${formatCurrency(totals.cartoes)}`}
icon={<ArrowDown size={20} className="text-finance-red" />}
trend={-2}
iconClass="bg-finance-red/10"

View File

@ -19,6 +19,7 @@ const TransacoesPage = () => {
cartoes,
totalReceitas,
totalDespesas,
totalCartoes,
formatCurrency,
handleTransactionSuccess,
handleDespesaCartaoSuccess,
@ -42,6 +43,7 @@ const TransacoesPage = () => {
<TransactionSummaryCards
totalReceitas={totalReceitas}
totalDespesas={totalDespesas}
totalCartoes={totalCartoes}
formatCurrency={formatCurrency}
/>

View File

@ -84,10 +84,19 @@ export const fetchAllInstances = async (): Promise<any> => {
const data = await makeRequest('/instance/fetchInstances', 'GET');
console.log('All instances response:', data);
// Make sure we're returning data in the expected format
if (!data || !data.instances || !Array.isArray(data.instances)) {
console.error("Invalid response format from fetchInstances API:", data);
// Return a standardized empty response rather than throwing an error
return { instances: [] };
}
return data;
} catch (error) {
console.error("Error fetching all instances:", error);
throw error;
// Return a standardized empty response on error
return { instances: [] };
}
};