import React, { useState } from 'react'; import { Plus, Search, FileText, Pencil, Printer, Trash2, Loader2 } from 'lucide-react'; import { HybridBackend } from '../services/backend.ts'; import { Contrato } from '../types.ts'; import { useHybridBackend } from '../hooks/useHybridBackend.ts'; import { useToast } from '../contexts/ToastContext.tsx'; import { PageHeader } from '../components/PageHeader.tsx'; import { ContratoModal } from './ContratoModal.tsx'; type StatusFilter = 'TODOS' | 'Ativo' | 'Rascunho' | 'Assinado' | 'Encerrado'; const STATUS_TABS: StatusFilter[] = ['TODOS', 'Ativo', 'Rascunho', 'Assinado', 'Encerrado']; const STATUS_COLORS: Record = { Ativo: 'bg-green-100 text-green-700', Rascunho: 'bg-amber-100 text-amber-700', Assinado: 'bg-blue-100 text-blue-700', Encerrado: 'bg-gray-100 text-gray-600', }; const fmt = (v: number) => v.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' }); export const ContratosView: React.FC = () => { const toast = useToast(); const { data: contratos, isLoading, refresh } = useHybridBackend(HybridBackend.getContratos); const list = contratos ?? []; const [search, setSearch] = useState(''); const [statusFilter, setStatusFilter] = useState('TODOS'); const [modalOpen, setModalOpen] = useState(false); const [editContrato, setEditContrato] = useState(null); const [printContrato, setPrintContrato] = useState(null); const filtered = list.filter(c => { const matchSearch = !search.trim() || c.pacienteNome.toLowerCase().includes(search.toLowerCase()) || c.titulo.toLowerCase().includes(search.toLowerCase()); const matchStatus = statusFilter === 'TODOS' || c.status === statusFilter; return matchSearch && matchStatus; }); const stats = { total: list.length, ativos: list.filter(c => c.status === 'Ativo').length, rascunhos: list.filter(c => c.status === 'Rascunho').length, encerrados: list.filter(c => c.status === 'Encerrado' || c.status === 'Assinado').length, }; const handleDelete = async (id: string, nome: string) => { if (!confirm(`EXCLUIR o contrato de ${nome}?`)) return; try { await HybridBackend.deleteContrato(id); toast.success('CONTRATO EXCLUÍDO.'); refresh(); } catch { toast.error('ERRO AO EXCLUIR CONTRATO.'); } }; const openNew = () => { setEditContrato(null); setModalOpen(true); }; const openEdit = (c: Contrato) => { setEditContrato(c); setModalOpen(true); }; const openPrint = (c: Contrato) => { setPrintContrato(c); setModalOpen(true); }; return (
{/* Stats bar */}
{[ { label: 'Total', value: stats.total, color: 'bg-indigo-50 text-indigo-700' }, { label: 'Ativos', value: stats.ativos, color: 'bg-green-50 text-green-700' }, { label: 'Rascunhos', value: stats.rascunhos, color: 'bg-amber-50 text-amber-700' }, { label: 'Encerrados/Assinados', value: stats.encerrados, color: 'bg-gray-50 text-gray-600' }, ].map(s => (

{s.value}

{s.label}

))}
{/* Search + status filters */}
setSearch(e.target.value)} />
{STATUS_TABS.map(s => ( ))}
{/* Loading */} {isLoading && (
)} {/* Empty state */} {!isLoading && filtered.length === 0 && (

Nenhum contrato encontrado

{search || statusFilter !== 'TODOS' ? 'Tente limpar os filtros.' : 'Clique em "NOVO CONTRATO" para começar.'}

{!search && statusFilter === 'TODOS' && ( )}
)} {/* Grid */} {!isLoading && filtered.length > 0 && (
{filtered.map(c => (
{/* Header row */}

{c.pacienteNome}

{c.status}

{c.titulo}

{c.especialidadeNome && ( {c.especialidadeNome} )} {c.dentistaNome && ( {c.dentistaNome} )}
Valor Total {fmt(c.valorTotal)}
Itens {c.items?.length ?? 0} proc.
{c.dataInicio && (
Início {new Date(c.dataInicio + 'T12:00').toLocaleDateString('pt-BR')}
)} {c.dataFim && (
Fim {new Date(c.dataFim + 'T12:00').toLocaleDateString('pt-BR')}
)}
{/* Actions */}
))}
)} {/* Modal */} {modalOpen && ( { setModalOpen(false); setEditContrato(null); setPrintContrato(null); }} onSaved={refresh} /> )}
); };