(null);
const saldo = resumo ? resumo.totalReceitas - resumo.totalDespesas - (resumo.totalCartoes || 0) : 0;
const totalGastos = resumo ? resumo.totalDespesas + (resumo.totalCartoes || 0) : 0;
// Calcular economia baseada nas transações do mês
- // Se há receitas, calcular quanto foi economizado (receitas - gastos totais)
- // Se não há receitas, mostrar 0% de economia
const economiaValor = resumo?.totalReceitas ? saldo : 0;
const economiaPercentual = resumo?.totalReceitas && resumo.totalReceitas > 0
? ((economiaValor / resumo.totalReceitas) * 100)
: 0;
+ // Carregar dados do mês anterior para comparação
+ useEffect(() => {
+ const loadPreviousMonthData = async () => {
+ if (!selectedMonth) return;
+
+ try {
+ const [year, month] = selectedMonth.split('-').map(Number);
+ const previousMonth = month === 1 ? 12 : month - 1;
+ const previousYear = month === 1 ? year - 1 : year;
+ const previousMonthFilter = `${previousYear}-${String(previousMonth).padStart(2, '0')}`;
+
+ const data = await getResumoFinanceiro(previousMonthFilter);
+ setResumoAnterior(data);
+ } catch (error) {
+ console.error("Erro ao carregar dados do mês anterior:", error);
+ setResumoAnterior(null);
+ }
+ };
+
+ loadPreviousMonthData();
+ }, [selectedMonth]);
+
+ // Calcular variações percentuais
+ const calcularVariacao = (atual: number, anterior: number) => {
+ if (anterior === 0) return atual > 0 ? 100 : 0;
+ return ((atual - anterior) / anterior) * 100;
+ };
+
+ const variacaoReceitas = resumoAnterior
+ ? calcularVariacao(resumo?.totalReceitas || 0, resumoAnterior.totalReceitas)
+ : 0;
+
+ const variacaoDespesas = resumoAnterior
+ ? calcularVariacao(resumo?.totalDespesas || 0, resumoAnterior.totalDespesas)
+ : 0;
+
return (
{/* Card Receitas - Clicável */}
-
navigateToTransactions('receita')}
- >
-
-
-
-
-
Receitas
-
- {resumo ? formatCurrency(resumo.totalReceitas) : 'R$ 0,00'}
+
+
+
+ navigateToTransactions('receita')}
+ >
+
+
+
+
+ {resumoAnterior && (
+
= 0
+ ? 'bg-green-500 text-white'
+ : 'bg-red-500 text-white'
+ }`}>
+ {variacaoReceitas >= 0 ? '+' : ''}{variacaoReceitas.toFixed(1)}%
+
+ )}
+
+
+
Receitas
+
+ {resumo ? formatCurrency(resumo.totalReceitas) : 'R$ 0,00'}
+
+
Clique para ver detalhes
+
+
+
+
+
+
+ {resumoAnterior
+ ? `Variação em relação ao mês anterior: ${variacaoReceitas >= 0 ? '+' : ''}${variacaoReceitas.toFixed(1)}%`
+ : 'Sem dados do mês anterior para comparação'
+ }
- Clique para ver detalhes
-
-
-
+
+
+
{/* Card Despesas - Clicável */}
-
navigateToTransactions('despesa')}
- >
-
-
-
-
-
Despesas
-
- {resumo ? formatCurrency(resumo.totalDespesas) : 'R$ 0,00'}
+
+
+
+ navigateToTransactions('despesa')}
+ >
+
+
+
+
+ {resumoAnterior && (
+
= 0
+ ? 'bg-red-500 text-white'
+ : 'bg-green-500 text-white'
+ }`}>
+ {variacaoDespesas >= 0 ? '+' : ''}{variacaoDespesas.toFixed(1)}%
+
+ )}
+
+
+
Despesas
+
+ {resumo ? formatCurrency(resumo.totalDespesas) : 'R$ 0,00'}
+
+ {resumo && resumo.totalCartoes && resumo.totalCartoes > 0 && (
+
+
+ Cartões:
+ {formatCurrency(resumo.totalCartoes)}
+
+
+ )}
+
Clique para ver detalhes
+
+
+
+
+
+
+ {resumoAnterior
+ ? `Variação em relação ao mês anterior: ${variacaoDespesas >= 0 ? '+' : ''}${variacaoDespesas.toFixed(1)}%`
+ : 'Sem dados do mês anterior para comparação'
+ }
- {resumo && resumo.totalCartoes && resumo.totalCartoes > 0 && (
-
-
- Cartões:
- {formatCurrency(resumo.totalCartoes)}
-
-
- )}
- Clique para ver detalhes
-
-
-
+
+
+
{/* Card Saldo */}
@@ -105,27 +192,36 @@ const DashboardSummaryCards: React.FC = ({ resumo, f
{/* Card Economia */}
-
-
-
-
-
-
Economia
-
= 0 ? 'text-purple-600' : 'text-red-600'
- }`}>
- {economiaPercentual.toFixed(1)}%
-
-
- {formatCurrency(Math.abs(economiaValor))}
-
-
-
-
+
+
+
+
+
+
+
+
+
Economia
+
= 0 ? 'text-purple-600' : 'text-red-600'
+ }`}>
+ {economiaPercentual.toFixed(1)}%
+
+
+ {formatCurrency(Math.abs(economiaValor))}
+
+
+
+
+
+
+ Percentual de economia: receitas que sobraram após todas as despesas
+
+
+
);
};
diff --git a/src/components/layout/NewModernLayout.tsx b/src/components/layout/NewModernLayout.tsx
index 51029fc..af15af6 100644
--- a/src/components/layout/NewModernLayout.tsx
+++ b/src/components/layout/NewModernLayout.tsx
@@ -15,6 +15,7 @@ import {
SidebarFooter,
SidebarTrigger,
SidebarInset,
+ useSidebar,
} from "@/components/ui/sidebar";
import {
Home,
@@ -24,17 +25,14 @@ import {
Target,
Calendar,
Crown,
- MessageSquareText,
Users,
Settings,
- Bell,
- Shield
+ Bell
} from 'lucide-react';
import OnboardingTour from '@/components/onboarding/OnboardingTour';
import HelpIcon from '@/components/help/HelpIcon';
import UserProfileButton from '@/components/dashboard/UserProfileButton';
import { useOnboardingTour } from '@/hooks/useOnboardingTour';
-import { useAdminSettings } from '@/hooks/useAdminSettings';
import {
Tooltip,
TooltipContent,
@@ -63,7 +61,7 @@ const Logo = () => {
export default function NewModernLayout({ children }: NewModernLayoutProps) {
const location = useLocation();
- const { isAdmin, hideWhatsAppButton } = useAdminSettings();
+ const { toggleSidebar } = useSidebar();
const {
isOpen: tourOpen,
@@ -117,11 +115,6 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) {
];
const whatsappItems = [
- ...(hideWhatsAppButton ? [] : [{
- title: "Conectar WhatsApp",
- url: "/whatsapp",
- icon: MessageSquareText,
- }]),
{
title: "Grupos",
url: "/grupos-whatsapp",
@@ -138,14 +131,6 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) {
}
];
- const adminItems = isAdmin ? [
- {
- title: "Admin",
- url: "/admin",
- icon: Shield,
- }
- ] : [];
-
return (
@@ -198,30 +183,6 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) {
-
- {adminItems.length > 0 && (
-
- Administração
-
-
- {adminItems.map((item) => (
-
-
-
-
- {item.title}
-
-
-
- ))}
-
-
-
- )}
@@ -259,7 +220,12 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) {
- Menu
+
+ Menu
+
diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx
index 3e339f3..e938f86 100644
--- a/src/pages/Index.tsx
+++ b/src/pages/Index.tsx
@@ -94,7 +94,8 @@ const Dashboard = () => {