import { Head, router } from '@inertiajs/react'; import { useState } from 'react'; import { ArrowRight, ClipboardList, Eye, FileText, LayoutGrid, Palette, Scale, Search, ShieldCheck, Users, PackageCheck, Warehouse, } from 'lucide-react'; import { PageTitle, Panel, Status } from '@/components/procurement'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { money } from '@/types/procurement'; import { previewPaths } from '@/lib/preview-navigation'; import InventoryDemo from './inventory-demo'; import { OperationsDemo } from '../stock/operations'; import { EquipmentDemo } from '../equipment'; // Static examples only: this page never loads or submits business data. const requests = [ { number: 'DEMO-001', title: 'Material de escritório', department: 'Administração', status: 'approved', amount: 1856000, author: 'Utilizador de exemplo A', }, { number: 'DEMO-002', title: 'Peças para manutenção', department: 'Produção', status: 'pending', amount: 6264000, author: 'Utilizador de exemplo B', }, { number: 'DEMO-003', title: 'Equipamento informático', department: 'Tecnologia', status: 'draft', amount: 13920000, author: 'Utilizador de exemplo C', }, ]; const suppliers = [ { name: 'Fornecedor de demonstração A', category: 'Material de escritório', status: 'Activo', review: '2027-01-15', contact: 'contacto-a@example.invalid', }, { name: 'Fornecedor de demonstração B', category: 'Equipamentos e peças', status: 'Pendente de validação', review: '2027-02-20', contact: 'contacto-b@example.invalid', }, { name: 'Fornecedor de demonstração C', category: 'Tecnologia', status: 'Activo', review: '2027-03-10', contact: 'contacto-c@example.invalid', }, ]; const quotes = [ { supplier: 'Fornecedor de demonstração A', amount: 1600000, days: 7, score: '8,65', evaluations: 2, }, { supplier: 'Fornecedor de demonstração B', amount: 1750000, days: 10, score: 'Pendente', evaluations: 1, }, { supplier: 'Fornecedor de demonstração C', amount: 1680000, days: 8, score: '8,12', evaluations: 2, }, ]; const navigation = [ { id: 'overview', title: 'Visão geral', icon: LayoutGrid }, { id: 'requests', title: 'Requisições', icon: ClipboardList }, { id: 'suppliers', title: 'Fornecedores e anexos', icon: Users }, { id: 'quotes', title: 'Cotações', icon: Scale }, { id: 'conflicts', title: 'Conflitos de interesses', icon: ShieldCheck }, { id: 'orders', title: 'Ordens de compra', icon: FileText }, { id: 'receipts', title: 'Recepção e qualidade', icon: PackageCheck }, { id: 'stock', title: 'Stock e movimentos', icon: Warehouse }, { id: 'operations', title: 'Saídas e inventários', icon: Warehouse }, { id: 'equipment', title: 'Equipamentos e peças', icon: Warehouse }, { id: 'invoices', title: 'Facturas e conferência', icon: FileText }, { id: 'bank', title: 'Dados bancários', icon: ShieldCheck }, { id: 'payments', title: 'Pagamentos externos', icon: FileText }, { id: 'reinforcements', title: 'Reforços orçamentais', icon: FileText }, { id: 'investment', title: 'Regras de investimento', icon: ShieldCheck }, { id: 'appearance', title: 'Cores e componentes', icon: Palette }, ]; type Detail = { title: string; subtitle: string; rows: [string, string][] }; export default function Preview({ initialScreen = 'overview', }: { initialScreen?: string; }) { const screen = initialScreen; const [search, setSearch] = useState(''); const [detail, setDetail] = useState(null); const title = navigation.find((n) => n.id === screen)?.title ?? 'Consulta'; function navigate(id: string) { setSearch(''); router.get(previewPaths[id] ?? '/consulta'); } const filteredRequests = requests.filter((r) => `${r.number} ${r.title} ${r.department}` .toLowerCase() .includes(search.toLowerCase()), ); const requestTable = (
{filteredRequests.map((r) => ( ))}
Requisição Departamento Estado Total com IVA Consultar
{r.number}

{r.title}

{r.department} {money(r.amount)}
{!filteredRequests.length && (

Nenhum exemplo corresponde à pesquisa.

)}
); return ( <>
Consulta / {title}
Entrada livre para consulta Exemplos fictícios · sem gravação de dados
{screen === 'overview' && ( <>
{[ [ 'Requisições de exemplo', '3', 'Uma aprovada, uma pendente e um rascunho', ], [ 'A aguardar decisão', '1', 'Exemplo de aprovação por departamento', ], [ 'Fornecedores de exemplo', '3', 'Com estados de validação diferentes', ], [ 'Valor aprovado de exemplo', money(1856000), 'Estimativa em MZN, com IVA', ], ].map(([label, value, note]) => (

{label}

{value}

{note}

))}
{requestTable}
{[ [ 'suppliers', 'Ficha e documentos', 'Consultar identificação, revisão e anexos.', ], [ 'quotes', 'Comparação de propostas', 'Comparar preços, prazos e avaliações.', ], [ 'conflicts', 'Transparência nas decisões', 'Consultar exemplos de declarações pessoais.', ], ].map(([id, label, note]) => ( ))}
)} {screen === 'requests' && (
setSearch(e.target.value) } />
{requestTable}
)} {screen === 'suppliers' && (
{suppliers.map((s) => (
{s.status}

Próxima revisão {s.review}

Contacto fictício {s.contact}

))}
)} {screen === 'quotes' && (
{[ 'Fornecedor', 'Preço sem IVA', 'Prazo', 'Avaliações', 'Pontuação', ].map((h) => ( ))} {quotes.map((q) => ( ))}
{h}
{q.supplier} {money(q.amount)} {q.days} dias {q.evaluations} / 2 {q.score}

Exemplo de comparação incompleta: uma das propostas ainda não tem duas avaliações. A consulta não permite adjudicar.

)} {screen === 'conflicts' && (
Fornecedor de demonstração B Conflito declarado
Autor
Utilizador de exemplo A
Âmbito
Fornecedor em todos os processos
Fundamento fictício
Relação pessoal com o fornecedor.
Efeito
Participação impedida nos processos afectados.

Uma declaração de ausência não anula um conflito registado. A política de levantamento continua por definir.

)} {screen === 'orders' && (

Exemplo visual

Ordem DEMO-OC-001

Sem validade comercial

Fornecedor de demonstração A · Material de escritório

Sem IVA
{money(1600000)}

IVA ilustrativo
{money(256000)}

Total
{money(1856000)}

A emissão real depende das cotações, avaliações, aprovações e verificações de conflito no servidor.

)} {(screen === 'receipts' || screen === 'stock') && ( )} {screen === 'operations' && } {screen === 'equipment' && } {screen === 'investment' && (

A empresa escolhe o tecto por processo, a base com/sem IVA e as datas. Dois administradores distintos do proponente aprovam a versão.

Equipamento exige também validação técnica, Finanças para qualquer valor e reserva em dotação de investimento. O tecto aplica-se ao total do processo que contenha equipamento.

Sem regra vigente, ou acima do tecto, a adjudicação fica bloqueada. A ordem conserva a versão aplicada; alterações posteriores não reescrevem documentos emitidos.

Aprovação adicional, agregação por projecto e detecção automática de fraccionamento não fazem parte desta etapa.

)} {screen === 'reinforcements' && (

Dotação inicial fictícia de 1.000,00 MZN, com 300,00 MZN utilizados: disponível de 700,00 MZN.

Um reforço proposto de 400,00 MZN fica pendente. Só depois da aprovação por outra pessoa a dotação acumulada passa a 1.400,00 MZN e o disponível a 1.100,00 MZN.

O valor inicial, a base de IVA, o centro de custo e o exercício são preservados. Repetir uma aprovação não duplica a verba. Rejeições ficam no histórico sem alterar o saldo.

)} {screen === 'payments' && (

Factura fictícia de 1.000,00 MZN. Um pagamento externo de 600,00 MZN é registado com referência e evidência.

Enquanto pendente de conferência, o saldo continua em 1.000,00 MZN. Após confirmação por outra pessoa de Finanças, fica em 400,00 MZN.

A versão bancária e as duas validações são novamente verificadas. Repetir a confirmação não duplica a liquidação; o orçamento não é consumido outra vez.

Os valores são apenas exemplos. Cada empresa tem as suas facturas e montantes; o SGC não efectua a operação no banco.

)} {screen === 'bank' && (

Procurement propõe uma versão com evidência. Finanças A confere e aprova; Finanças B confere de forma independente.

Uma aprovação: pendente. Duas pessoas distintas: duplamente validado. Repetir a decisão da mesma pessoa não conta duas vezes.

Nova versão: disponibilidade anterior substituída e duas novas validações obrigatórias. Rejeição, conflito ou perda de elegibilidade bloqueiam o estado.

Cada empresa mantém os seus fornecedores e dados. Não autoriza transferências nem confirma titularidade junto do banco.

)} {screen === 'invoices' && (

FT-DEMO-01 · Fornecedor fictício · OC-DEMO-01 · Validada por uma segunda pessoa de Finanças.

Quantidade autorizada e aceite
10 unidades
Quantidade facturada
6 unidades
Valor desta factura
600,00 MZN (exemplo sem IVA)
Compromisso antes da conferência
1.000,00 MZN
Consumo após validação
600,00 MZN
Compromisso remanescente
400,00 MZN

O disponível não aumenta: o compromisso converte-se em consumo. Preço, unidade, IVA e quantidades são novamente conferidos no servidor. Sem compromisso aprovado, a factura permanece pendente. Não autoriza pagamentos.

)} {screen === 'appearance' && ( <>
{[ ['Principal', 'bg-teal-700'], ['Aprovação', 'bg-teal-100'], ['Atenção', 'bg-amber-100'], ['Impedimento', 'bg-rose-100'], ].map(([label, color]) => (

{label}

))}
)}
{ if (!open) setDetail(null); }} > {detail?.title} {detail?.subtitle}
{detail?.rows.map(([label, value]) => (
{label}
{value}
))}

Consulta livre · dados fictícios · nenhuma operação de compra é efectuada.

); }