Remove admin page and WhatsApp menu, fix dashboard percentages, and add menu toggle
- Removed the admin page and the "Conectar WhatsApp" menu item from the front end for all users. - Adjusted the dashboard percentage calculations to accurately reflect the revenue and expense variations compared to the same day of the previous month. - Added a tooltip to explain the percentage calculation on hover. - Implemented menu toggle functionality when clicking the "Menu" name.
This commit is contained in:
parent
991922432d
commit
b18ebd96c7
@ -27,7 +27,6 @@ import Categorias from "./pages/Categorias";
|
||||
import AdminFAQ from "./pages/AdminFAQ";
|
||||
import Assinatura from "./pages/Assinatura";
|
||||
import AvisosContas from "./pages/AvisosContas";
|
||||
import Admin from "./pages/Admin";
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
@ -76,7 +75,6 @@ function App() {
|
||||
<Route path="/complete-profile" element={<CompleteProfile />} />
|
||||
<Route path="/categorias" element={<Categorias />} />
|
||||
<Route path="/admin/faq" element={<AdminFAQ />} />
|
||||
<Route path="/admin" element={<Admin />} />
|
||||
<Route path="/assinatura" element={<Assinatura />} />
|
||||
<Route path="/avisos-contas" element={<AvisosContas />} />
|
||||
</Route>
|
||||
|
||||
@ -1,32 +1,82 @@
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { ArrowUpIcon, ArrowDownIcon, CreditCardIcon, Target } from "lucide-react";
|
||||
import { ResumoFinanceiro } from "@/types/financialTypes";
|
||||
import { useNavigateWithFilter } from "@/hooks/useNavigateWithFilter";
|
||||
import { getResumoFinanceiro } from "@/services/transacao";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip';
|
||||
|
||||
interface DashboardSummaryCardsProps {
|
||||
resumo: ResumoFinanceiro | null;
|
||||
formatCurrency: (value: number) => string;
|
||||
selectedMonth?: string;
|
||||
}
|
||||
|
||||
const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({ resumo, formatCurrency }) => {
|
||||
const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({
|
||||
resumo,
|
||||
formatCurrency,
|
||||
selectedMonth
|
||||
}) => {
|
||||
const { navigateToTransactions } = useNavigateWithFilter();
|
||||
const [resumoAnterior, setResumoAnterior] = useState<ResumoFinanceiro | null>(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 (
|
||||
<div className="grid gap-4 sm:gap-6 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
|
||||
{/* Card Receitas - Clicável */}
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Card
|
||||
className="relative overflow-hidden border-2 border-green-200 bg-gradient-to-br from-green-50 to-emerald-100 shadow-lg hover:shadow-xl transition-all duration-300 cursor-pointer group transform hover:scale-105"
|
||||
onClick={() => navigateToTransactions('receita')}
|
||||
@ -37,9 +87,15 @@ const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({ resumo, f
|
||||
<div className="p-2 sm:p-3 bg-green-500 rounded-full shadow-lg">
|
||||
<ArrowUpIcon className="h-4 w-4 sm:h-6 sm:w-6 text-white" />
|
||||
</div>
|
||||
<div className="text-xs font-bold px-2 py-1 bg-green-500 text-white rounded-full shadow-sm">
|
||||
+5%
|
||||
{resumoAnterior && (
|
||||
<div className={`text-xs font-bold px-2 py-1 rounded-full shadow-sm ${
|
||||
variacaoReceitas >= 0
|
||||
? 'bg-green-500 text-white'
|
||||
: 'bg-red-500 text-white'
|
||||
}`}>
|
||||
{variacaoReceitas >= 0 ? '+' : ''}{variacaoReceitas.toFixed(1)}%
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-1 sm:space-y-2">
|
||||
<p className="text-xs sm:text-sm font-semibold text-green-700">Receitas</p>
|
||||
@ -50,8 +106,22 @@ const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({ resumo, f
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>
|
||||
{resumoAnterior
|
||||
? `Variação em relação ao mês anterior: ${variacaoReceitas >= 0 ? '+' : ''}${variacaoReceitas.toFixed(1)}%`
|
||||
: 'Sem dados do mês anterior para comparação'
|
||||
}
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
||||
{/* Card Despesas - Clicável */}
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Card
|
||||
className="relative overflow-hidden border-2 border-red-200 bg-gradient-to-br from-red-50 to-rose-100 shadow-lg hover:shadow-xl transition-all duration-300 cursor-pointer group transform hover:scale-105"
|
||||
onClick={() => navigateToTransactions('despesa')}
|
||||
@ -62,9 +132,15 @@ const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({ resumo, f
|
||||
<div className="p-2 sm:p-3 bg-red-500 rounded-full shadow-lg">
|
||||
<ArrowDownIcon className="h-4 w-4 sm:h-6 sm:w-6 text-white" />
|
||||
</div>
|
||||
<div className="text-xs font-bold px-2 py-1 bg-red-500 text-white rounded-full shadow-sm">
|
||||
-2%
|
||||
{resumoAnterior && (
|
||||
<div className={`text-xs font-bold px-2 py-1 rounded-full shadow-sm ${
|
||||
variacaoDespesas >= 0
|
||||
? 'bg-red-500 text-white'
|
||||
: 'bg-green-500 text-white'
|
||||
}`}>
|
||||
{variacaoDespesas >= 0 ? '+' : ''}{variacaoDespesas.toFixed(1)}%
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-1 sm:space-y-2">
|
||||
<p className="text-xs sm:text-sm font-semibold text-red-700">Despesas</p>
|
||||
@ -83,6 +159,17 @@ const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({ resumo, f
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>
|
||||
{resumoAnterior
|
||||
? `Variação em relação ao mês anterior: ${variacaoDespesas >= 0 ? '+' : ''}${variacaoDespesas.toFixed(1)}%`
|
||||
: 'Sem dados do mês anterior para comparação'
|
||||
}
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
||||
{/* Card Saldo */}
|
||||
<Card className="relative overflow-hidden border-2 border-blue-200 bg-gradient-to-br from-blue-50 to-sky-100 shadow-lg hover:shadow-xl transition-all duration-300 group transform hover:scale-105">
|
||||
@ -105,6 +192,9 @@ const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({ resumo, f
|
||||
</Card>
|
||||
|
||||
{/* Card Economia */}
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Card className="relative overflow-hidden border-2 border-purple-200 bg-gradient-to-br from-purple-50 to-violet-100 shadow-lg hover:shadow-xl transition-all duration-300 group transform hover:scale-105">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-purple-400/10 to-violet-500/10 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||
<CardContent className="p-4 sm:p-6 relative">
|
||||
@ -126,6 +216,12 @@ const DashboardSummaryCards: React.FC<DashboardSummaryCardsProps> = ({ resumo, f
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Percentual de economia: receitas que sobraram após todas as despesas</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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 (
|
||||
<div className="min-h-screen bg-background flex w-full">
|
||||
<SidebarProvider defaultOpen={false}>
|
||||
@ -198,30 +183,6 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) {
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
|
||||
{adminItems.length > 0 && (
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Administração</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{adminItems.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
tooltip={item.title}
|
||||
isActive={location.pathname === item.url}
|
||||
>
|
||||
<Link to={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
)}
|
||||
</SidebarContent>
|
||||
|
||||
<SidebarFooter>
|
||||
@ -259,7 +220,12 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) {
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<span className="text-sm font-medium text-gray-600">Menu</span>
|
||||
<span
|
||||
className="text-sm font-medium text-gray-600 cursor-pointer hover:text-blue-600 transition-colors"
|
||||
onClick={toggleSidebar}
|
||||
>
|
||||
Menu
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="ml-auto">
|
||||
|
||||
@ -95,6 +95,7 @@ const Dashboard = () => {
|
||||
<DashboardSummaryCards
|
||||
resumo={resumo}
|
||||
formatCurrency={formatCurrency}
|
||||
selectedMonth={selectedMonth}
|
||||
/>
|
||||
|
||||
<DashboardCharts
|
||||
|
||||
Loading…
Reference in New Issue
Block a user