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:
parent
afb53c1429
commit
04ed74ac61
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
|
||||
|
||||
@ -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: [] };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user