From 6b997c4c8c659afcbba4ef5f2cac948c4fda0c87 Mon Sep 17 00:00:00 2001 From: guilherme Date: Tue, 25 Nov 2025 17:18:54 -0300 Subject: [PATCH] feat(protocols): implement ProtocolsDashboard and ProtocolsDialog with pagination and search functionality --- src/App.tsx | 58 +---- src/services/protocolService.ts | 90 +++++++ src/views/components/ui/pagination.tsx | 120 ++++++++++ src/views/components/ui/table.tsx | 114 +++++++++ src/views/protocols/ProtocolsDashboard.tsx | 17 ++ src/views/protocols/ProtocolsDialog.tsx | 260 +++++++++++++++++++++ 6 files changed, 605 insertions(+), 54 deletions(-) create mode 100644 src/services/protocolService.ts create mode 100644 src/views/components/ui/pagination.tsx create mode 100644 src/views/components/ui/table.tsx create mode 100644 src/views/protocols/ProtocolsDashboard.tsx create mode 100644 src/views/protocols/ProtocolsDialog.tsx diff --git a/src/App.tsx b/src/App.tsx index af04a7d..133c02e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,48 +11,17 @@ import { ChartTooltip, ChartTooltipContent, } from '@/views/components/ui/chart'; -import { Progress } from '@/views/components/ui/progress'; import { TrendingUp } from 'lucide-react'; import { Bar, BarChart, CartesianGrid, Pie, PieChart, XAxis } from 'recharts'; import { Header } from './views/components/header'; import type { ChartConfig } from './views/components/ui/chart'; +import ProtocolsDashboard from './views/protocols/ProtocolsDashboard'; export const description = 'A stacked bar chart with a legend'; export function App() { - const stats = [ - { - title: 'Protocolos criados', - value: 'R$ 0,00', - description: '', - progress: 44.6, - }, - { - title: 'Protocolos tramitados', - value: '0 KM', - description: '', - progress: 30.6, - }, - { - title: 'Protocolos recebidos', - value: '0', - description: '', - progress: 24.8, - }, - { - title: 'Protocolos finalizados', - value: '0', - description: '', - progress: 67.2, - }, - { - title: 'Protocolos cancelados', - value: '0', - description: '', - progress: 67.2, - }, - ]; + // dashboard now uses ProtocolsDashboard for protocol status cards const bestPricesConfig = { price: { @@ -98,26 +67,7 @@ export function App() {
-
- {stats.map((stat) => ( - - - - {stat.title} - -
{stat.value}
-
- -

- {stat.description} -

- -
-
- ))} -
+
@@ -157,7 +107,7 @@ export function App() { + className="[&_.recharts-pie-label-text]:fill-foreground mx-auto aspect-square max-h-80 pb-0"> } /> { + const status = statuses[i % statuses.length]; + return { + id: String(1000 + i), + title: `NOTA FISCAL ${1000 + i}`, + date: new Date(Date.now() - i * 1000 * 60 * 60 * 24) + .toISOString() + .split('T')[0], + sender: `PREFEITURA ${i % 10}`, + location: ['Sala do financeiro', 'Protocolo Central', 'Expediente'][i % 3], + status, + }; +}); + +export type ProtocolsPage = { + items: Protocol[]; + total: number; +}; + +export function getProtocols({ + status, + page = 1, + pageSize = 10, + search = '', +}: { + status?: ProtocolStatus | 'Todos'; + page?: number; + pageSize?: number; + search?: string; +}): Promise { + return new Promise((resolve) => { + setTimeout(() => { + let items = protocols.slice(); + if (status && status !== 'Todos') { + items = items.filter((p) => p.status === status); + } + if (search) { + const q = search.toLowerCase(); + items = items.filter( + (p) => + p.title.toLowerCase().includes(q) || + p.sender.toLowerCase().includes(q), + ); + } + const total = items.length; + const start = (page - 1) * pageSize; + const paged = items.slice(start, start + pageSize); + resolve({ items: paged, total }); + }, 250); + }); +} + +export function getCounts() { + const counts: Record = { Todos: protocols.length }; + for (const s of statuses) { + counts[s] = protocols.filter((p) => p.status === s).length; + } + return counts; +} diff --git a/src/views/components/ui/pagination.tsx b/src/views/components/ui/pagination.tsx new file mode 100644 index 0000000..38b93f8 --- /dev/null +++ b/src/views/components/ui/pagination.tsx @@ -0,0 +1,120 @@ +import { cn } from '@/app/utils'; +import { Button, buttonVariants } from '@/views/components/ui/button'; +import { CaretLeftIcon, CaretRightIcon } from '@phosphor-icons/react'; +import { MoreHorizontalIcon } from 'lucide-react'; +import * as React from 'react'; + +function Pagination({ className, ...props }: React.ComponentProps<'nav'>) { + return ( +