import { useCallback, useState, useEffect } from 'react'; import { Outlet, Link, useLocation } from 'react-router-dom'; import { LayoutDashboard, Users, BarChart3, ChevronLeft, ChevronRight, Package, Loader2, LogOut, Megaphone, Grid3X3, Shield } from 'lucide-react'; import type { DateRange, OrderData, StockData } from '../types'; import { fetchData, fetchStock, isSuperAdmin, logout } from '../dataService'; import { rangeForLastDays } from '../dateRanges'; const Layout = () => { const location = useLocation(); const needsRawData = location.pathname.startsWith('/products'); const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(() => { return localStorage.getItem('graph_sidebar_collapsed') === 'true'; }); const [dateRange, setDateRange] = useState(() => { const saved = localStorage.getItem('nexstar_date_range'); if (saved) { try { const parsed = JSON.parse(saved); return { start: new Date(parsed.start), end: new Date(parsed.end) }; } catch (e) { console.error(e); } } return rangeForLastDays(30); }); const [ordersData, setOrdersData] = useState([]); const [stockData, setStockData] = useState([]); const [isLoading, setIsLoading] = useState(needsRawData); const [refreshInterval, setRefreshInterval] = useState(() => { const saved = localStorage.getItem('nexstar_refresh_interval'); return saved ? Number(saved) : 0; }); const loadData = useCallback(async (showLoading = false) => { if (showLoading) setIsLoading(true); try { const [data, stock] = await Promise.all([fetchData(), fetchStock()]); setOrdersData(data); setStockData(stock); } finally { if (showLoading) setIsLoading(false); } }, []); useEffect(() => { if (!needsRawData) return; // Product pages still depend on raw orders until their API migration is complete. // eslint-disable-next-line react-hooks/set-state-in-effect void loadData(true); }, [loadData, needsRawData]); useEffect(() => { if (refreshInterval === 0 || !needsRawData) return; const intervalId = setInterval(() => { loadData(false); }, refreshInterval); return () => clearInterval(intervalId); }, [loadData, needsRawData, refreshInterval]); useEffect(() => { localStorage.setItem('nexstar_refresh_interval', refreshInterval.toString()); }, [refreshInterval]); useEffect(() => { localStorage.setItem('nexstar_date_range', JSON.stringify({ start: dateRange.start.toISOString(), end: dateRange.end.toISOString() })); }, [dateRange]); const toggleSidebar = () => { const newState = !isSidebarCollapsed; setIsSidebarCollapsed(newState); localStorage.setItem('graph_sidebar_collapsed', String(newState)); }; const appNavigation = [ { name: 'Dashboard', href: '/graph', icon: LayoutDashboard }, { name: 'Produtos', href: '/products', icon: Package }, { name: 'Clientes', href: '/clients', icon: Users }, { name: 'RFV', href: '/rfm', icon: Grid3X3 }, { name: 'Campanhas', href: '/campaigns', icon: Megaphone }, ]; const adminNavigation = isSuperAdmin() ? [{ name: 'Usuários', href: '/admin/users', icon: Shield }] : []; const navigationSections = [ { label: 'Painel', items: appNavigation }, ...(adminNavigation.length ? [{ label: 'Super admin', items: adminNavigation }] : []), ]; return (
{/* Sidebar */} {/* Main Content */}
{/* Header */}

Painel de Análise

{/* Content Area */}
{needsRawData && isLoading && (
Atualizando dados
)}
); }; export default Layout;