'use client'; import React, { useState, useEffect, Fragment } from 'react'; import { PlusIcon, MagnifyingGlassIcon, FunnelIcon, ShoppingBagIcon, CalendarIcon, CurrencyDollarIcon, UserIcon, CheckCircleIcon, ClockIcon, XMarkIcon, EyeIcon, TrashIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline'; import { ConfirmDialog } from "@/components/ui"; import { erpApi, Order, Entity } from '@/lib/api-erp'; import { formatCurrency } from '@/lib/format'; import { useToast } from '@/components/layout/ToastContext'; import { PageHeader, StatsCard, DataTable, Input, Card, BulkActionBar, } from "@/components/ui"; import { format } from 'date-fns'; export default function OrdersPage() { const toast = useToast(); const [orders, setOrders] = useState([]); const [entities, setEntities] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); const [selectedIds, setSelectedIds] = useState<(string | number)[]>([]); const [confirmOpen, setConfirmOpen] = useState(false); const [bulkConfirmOpen, setBulkConfirmOpen] = useState(false); const [orderToDelete, setOrderToDelete] = useState(null); useEffect(() => { fetchData(); }, []); const fetchData = async (silent = false) => { try { if (!silent) setLoading(true); const [ordersData, entitiesData] = await Promise.all([ erpApi.getOrders(), erpApi.getEntities() ]); setOrders(ordersData || []); setEntities(entitiesData || []); } catch (error) { toast.error('Erro ao carregar', 'Não foi possível carregar os pedidos'); } finally { setLoading(false); setSelectedIds([]); } }; const handleBulkDelete = async () => { if (selectedIds.length === 0) return; setBulkConfirmOpen(true); }; const handleConfirmBulkDelete = async () => { if (selectedIds.length === 0) return; const originalOrders = [...orders]; const idsToDelete = selectedIds.map(String); // Dynamic: remove instantly setOrders(prev => prev.filter(o => !idsToDelete.includes(String(o.id)))); const deletedCount = selectedIds.length; try { await Promise.all(idsToDelete.map(id => erpApi.deleteOrder(id))); toast.success('Exclusão completa', `${deletedCount} pedidos excluídos com sucesso.`); setTimeout(() => fetchData(true), 500); } catch (error) { setOrders(originalOrders); toast.error('Erro ao excluir', 'Ocorreu um erro ao excluir alguns pedidos.'); } finally { setBulkConfirmOpen(false); setSelectedIds([]); } }; const handleDelete = (id: string) => { setOrderToDelete(id); setConfirmOpen(true); }; const handleConfirmDelete = async () => { if (!orderToDelete) return; const originalOrders = [...orders]; const idToDelete = String(orderToDelete); // Dynamic: remove instantly setOrders(prev => prev.filter(o => String(o.id) !== idToDelete)); try { await erpApi.deleteOrder(idToDelete); toast.success('Exclusão completa', 'O pedido foi removido com sucesso.'); setTimeout(() => fetchData(true), 500); } catch (error) { setOrders(originalOrders); toast.error('Erro ao excluir', 'Ocorreu um erro ao excluir o pedido.'); } finally { setConfirmOpen(false); setOrderToDelete(null); } }; const filteredOrders = orders.filter(o => { const entityName = entities.find(e => e.id === o.entity_id)?.name || ''; const searchStr = searchTerm.toLowerCase(); return String(o.id).toLowerCase().includes(searchStr) || entityName.toLowerCase().includes(searchStr); }); const totalRevenue = orders.filter(o => o.status !== 'cancelled').reduce((sum, o) => sum + Number(o.total_amount), 0); const pendingOrders = orders.filter(o => o.status === 'confirmed').length; const completedOrders = orders.filter(o => o.status === 'completed').length; const columns = [ { header: 'Pedido / Data', accessor: (row: Order) => (
#{row.id.slice(0, 8)}
{row.created_at ? format(new Date(row.created_at), 'dd/MM/yyyy HH:mm') : '-'}
) }, { header: 'Cliente', accessor: (row: Order) => (
{entities.find(e => e.id === row.entity_id)?.name || 'Consumidor Final'}
) }, { header: 'Status', accessor: (row: Order) => { const colors = { draft: 'bg-zinc-100 text-zinc-700', confirmed: 'bg-blue-100 text-blue-700', completed: 'bg-emerald-100 text-emerald-700', cancelled: 'bg-rose-100 text-rose-700' }; const labels = { draft: 'Rascunho', confirmed: 'Confirmado', completed: 'Concluído', cancelled: 'Cancelado' }; return ( {labels[row.status as keyof typeof labels]} ); } }, { header: 'Total', className: 'text-right', accessor: (row: Order) => ( {formatCurrency(row.total_amount)} ) }, { header: '', className: 'text-right', accessor: (row: Order) => (
) } ]; return (
, onClick: () => toast.error('Funcionalidade em desenvolvimento') }} />
} /> } /> } /> } />
setSearchTerm(e.target.value)} />
setBulkConfirmOpen(false)} onConfirm={handleConfirmBulkDelete} title="Excluir Pedidos Selecionados" message={`Tem certeza que deseja excluir os ${selectedIds.length} pedidos selecionados? Esta ação não pode ser desfeita.`} confirmText="Excluir Tudo" variant="danger" /> { setConfirmOpen(false); setOrderToDelete(null); }} onConfirm={handleConfirmDelete} title="Excluir Pedido" message="Tem certeza que deseja excluir este pedido? Esta ação não pode ser desfeita." confirmText="Excluir" cancelText="Cancelar" variant="danger" /> setSelectedIds([])} actions={[ { label: "Excluir Selecionados", icon: , onClick: handleBulkDelete, variant: 'danger' } ]} />
); }