feat(protocols): adicionar lógica de contagem e filtragem de protocolos por status

main
guilherme 2025-11-26 09:31:14 -03:00
parent a6fe2ccc85
commit 5e133d02e2
1 changed files with 114 additions and 33 deletions

View File

@ -1,5 +1,5 @@
import { Dialog, DialogTrigger } from '@/views/components/ui/dialog'; import { Dialog, DialogTrigger } from '@/views/components/ui/dialog';
import { useState } from 'react'; import { useMemo, useState } from 'react';
import type { Protocol } from '@/services/protocolService'; import type { Protocol } from '@/services/protocolService';
import { InfoIcon } from '@phosphor-icons/react'; import { InfoIcon } from '@phosphor-icons/react';
@ -14,43 +14,124 @@ import {
const statuses = ['Criado', 'Tramitado', 'Recebido', 'Finalizado', 'Cancelado']; const statuses = ['Criado', 'Tramitado', 'Recebido', 'Finalizado', 'Cancelado'];
const sampleProtocols: Protocol[] = [
{
id: 'P-2025-001',
title: 'Solicitação de compra - materiais de escritório',
date: '2025-11-01',
sender: 'João Silva',
location: 'Almoxarifado',
status: 'Criado',
},
{
id: 'P-2025-002',
title: 'Requisição de manutenção - ar-condicionado',
date: '2025-10-28',
sender: 'Maria Oliveira',
location: 'Prédio A',
status: 'Tramitado',
},
{
id: 'P-2025-003',
title: 'Entrega de documento - processo X',
date: '2025-11-10',
sender: 'Gustavo Pereira',
location: 'Protocolo Central',
status: 'Recebido',
},
{
id: 'P-2025-004',
title: 'Encaminhamento para setor jurídico',
date: '2025-09-15',
sender: 'Setor RH',
location: 'Jurídico',
status: 'Finalizado',
},
{
id: 'P-2025-005',
title: 'Cancelamento de protocolo teste',
date: '2025-08-20',
sender: 'Teste',
location: 'Arquivo',
status: 'Cancelado',
},
{
id: 'P-2025-006',
title: 'Solicitação de acesso à sala de reunião',
date: '2025-11-12',
sender: 'Carla Dias',
location: 'Recepção',
status: 'Recebido',
},
{
id: 'P-2025-007',
title: 'Pedido de correção de dados cadastrais',
date: '2025-11-20',
sender: 'Paulo Costa',
location: 'Cadastro',
status: 'Finalizado',
},
{
id: 'P-2025-008',
title: 'Requisição de treinamento',
date: '2025-11-22',
sender: 'Equipe TI',
location: 'Sala 3',
status: 'Criado',
},
];
export function ProtocolsDashboard() { export function ProtocolsDashboard() {
const [open, setOpen] = useState(false); const [openStatus, setOpenStatus] = useState<string | null>(null);
const [paginatedItems] = useState<Protocol[]>([]); const [paginatedItems] = useState<Protocol[]>(sampleProtocols);
const [counts] = useState<Record<string, number>>({ Todos: 0 });
const counts = useMemo(() => {
const acc: Record<string, number> = { Todos: paginatedItems.length };
for (const s of statuses) acc[s] = 0;
for (const p of paginatedItems) {
const st = (p as any).status as string;
if (st && acc[st] !== undefined) acc[st] += 1;
}
return acc;
}, [paginatedItems]);
return ( return (
<div className="grid gap-4 sm:grid-cols-2 md:grid-cols-5 lg:grid-cols-5"> <div className="grid gap-4 sm:grid-cols-2 md:grid-cols-5 lg:grid-cols-5">
{statuses.map((status) => ( {statuses.map((status) => {
<Dialog const itemsForStatus = paginatedItems.filter(
open={open} (p) => (p as any).status === status,
onOpenChange={(v) => { );
setOpen(v);
}}>
<DialogTrigger asChild>
<Card className="cursor-pointer hover:shadow-md transition-shadow bg-muted/50">
<CardHeader className="pb-2">
<CardDescription className="flex items-center gap-1">
{`Protocolos ${status.toLowerCase()}`}
<span title="Informações sobre os protocolos">
<InfoIcon size={14} />
</span>
</CardDescription>
<CardTitle className="text-3xl">
{counts[status] ?? 0}
</CardTitle>
</CardHeader>
<CardContent></CardContent>
</Card>
</DialogTrigger>
<ProtocolsTable return (
tasks={paginatedItems} <Dialog
title={`Protocolos ${status.toLowerCase()}`} key={status}
description={`Lista de protocolos com status ${status.toLowerCase()}.`} open={openStatus === status}
/> onOpenChange={(v) => setOpenStatus(v ? status : null)}>
</Dialog> <DialogTrigger asChild>
))} <Card className="cursor-pointer hover:shadow-md transition-shadow bg-muted/50">
<CardHeader className="pb-2">
<CardDescription className="flex items-center gap-1">
{`Protocolos ${status.toLowerCase()}`}
<span title="Informações sobre os protocolos">
<InfoIcon size={14} />
</span>
</CardDescription>
<CardTitle className="text-3xl">
{counts[status] ?? 0}
</CardTitle>
</CardHeader>
<CardContent></CardContent>
</Card>
</DialogTrigger>
<ProtocolsTable
tasks={itemsForStatus}
title={`Protocolos ${status.toLowerCase()}`}
description={`Lista de protocolos com status ${status.toLowerCase()}.`}
/>
</Dialog>
);
})}
</div> </div>
); );
} }