import { useQuery } from '@tanstack/react-query'; import { TrendingUp, ShoppingCart, Users, CreditCard, Package, AlertCircle, Loader2, } from 'lucide-react'; import { dashboardApi, ordersApi, inventoryApi, exportsApi, downloadBlob } from '../lib/api'; import { ExportButton } from '../components/ExportButton'; interface DashboardStats { salesToday: number; ordersCount: number; customersCount: number; pendingFiado: number; salesChange: string; ordersChange: string; customersChange: string; fiadoChange: string; } interface Order { id: string; customer: { name: string } | null; total: number; status: string; createdAt: string; } interface LowStockProduct { id: string; name: string; stock: number; minStock: number; } const statusColors: Record = { pending: 'bg-yellow-100 text-yellow-800', preparing: 'bg-blue-100 text-blue-800', ready: 'bg-green-100 text-green-800', completed: 'bg-gray-100 text-gray-800', }; const statusLabels: Record = { pending: 'Pendiente', preparing: 'Preparando', ready: 'Listo', completed: 'Completado', }; function formatCurrency(amount: number): string { return new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN', }).format(amount); } function LoadingSpinner() { return (
); } function ErrorMessage({ message }: { message: string }) { return (
{message}
); } export function Dashboard() { // Fetch dashboard stats const { data: statsData, isLoading: statsLoading, error: statsError, } = useQuery({ queryKey: ['dashboard-stats'], queryFn: async () => { const response = await dashboardApi.getStats(); return response.data as DashboardStats; }, }); // Fetch recent orders const { data: ordersData, isLoading: ordersLoading, error: ordersError, } = useQuery({ queryKey: ['recent-orders'], queryFn: async () => { const response = await ordersApi.getAll({ status: undefined }); return (response.data as Order[]).slice(0, 5); }, }); // Fetch low stock products const { data: lowStockData, isLoading: lowStockLoading, error: lowStockError, } = useQuery({ queryKey: ['low-stock'], queryFn: async () => { const response = await inventoryApi.getLowStock(); return response.data as LowStockProduct[]; }, }); // Build stats array from API data const stats = statsData ? [ { name: 'Ventas Hoy', value: formatCurrency(statsData.salesToday), change: statsData.salesChange, icon: TrendingUp, color: 'green', }, { name: 'Pedidos', value: String(statsData.ordersCount), change: statsData.ordersChange, icon: ShoppingCart, color: 'blue', }, { name: 'Clientes', value: String(statsData.customersCount), change: statsData.customersChange, icon: Users, color: 'purple', }, { name: 'Fiados Pendientes', value: formatCurrency(statsData.pendingFiado), change: statsData.fiadoChange, icon: CreditCard, color: 'orange', }, ] : []; // Get today's date for export filename const today = new Date().toISOString().split('T')[0]; const handleExportSalesPdf = async () => { const response = await exportsApi.sales('pdf', { startDate: today, endDate: today }); downloadBlob(response.data, `ventas-${today}.pdf`); }; const handleExportSalesExcel = async () => { const response = await exportsApi.sales('xlsx', { startDate: today, endDate: today }); downloadBlob(response.data, `ventas-${today}.xlsx`); }; return (

Dashboard

Bienvenido a MiChangarrito

{/* Stats Grid */} {statsLoading ? ( ) : statsError ? ( ) : (
{stats.map((stat) => (

{stat.name}

{stat.value}

{stat.change}

))}
)}
{/* Recent Orders */}

Pedidos Recientes

Ver todos
{ordersLoading ? ( ) : ordersError ? ( ) : ordersData && ordersData.length > 0 ? (
{ordersData.map((order) => (

{order.id.slice(0, 8).toUpperCase()}

{order.customer?.name || 'Cliente General'}

{formatCurrency(order.total)}

{statusLabels[order.status] || order.status}
))}
) : (

No hay pedidos recientes

)}
{/* Low Stock Alert */}

Stock Bajo

Ver inventario
{lowStockLoading ? ( ) : lowStockError ? ( ) : lowStockData && lowStockData.length > 0 ? (
{lowStockData.map((product) => (

{product.name}

{product.stock} unidades

Min: {product.minStock}

))}
) : (

No hay productos con stock bajo

)}
); }