tr]:last:border-b-0",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
+ return (
+
+ )
+}
+
+function TableHead({ className, ...props }: React.ComponentProps<"th">) {
+ return (
+ [role=checkbox]]:translate-y-[2px]",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+function TableCell({ className, ...props }: React.ComponentProps<"td">) {
+ return (
+ | [role=checkbox]]:translate-y-[2px]",
+ className
+ )}
+ {...props}
+ />
+ )
+}
+
+function TableCaption({
+ className,
+ ...props
+}: React.ComponentProps<"caption">) {
+ return (
+
+ )
+}
+
+export {
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
+}
diff --git a/src/views/protocols/ProtocolsDashboard.tsx b/src/views/protocols/ProtocolsDashboard.tsx
new file mode 100644
index 0000000..98b6a50
--- /dev/null
+++ b/src/views/protocols/ProtocolsDashboard.tsx
@@ -0,0 +1,17 @@
+'use client';
+
+import ProtocolsDialog from './ProtocolsDialog';
+
+const statuses = ['Criado', 'Tramitado', 'Recebido', 'Finalizado', 'Cancelado'];
+
+export function ProtocolsDashboard() {
+ return (
+
+ {statuses.map((s) => (
+
+ ))}
+
+ );
+}
+
+export default ProtocolsDashboard;
diff --git a/src/views/protocols/ProtocolsDialog.tsx b/src/views/protocols/ProtocolsDialog.tsx
new file mode 100644
index 0000000..4a27228
--- /dev/null
+++ b/src/views/protocols/ProtocolsDialog.tsx
@@ -0,0 +1,260 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable react-hooks/set-state-in-effect */
+'use client';
+
+import { getCounts, getProtocols } from '@/services/protocolService';
+import { Button } from '@/views/components/ui/button';
+import {
+ Dialog,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from '@/views/components/ui/dialog';
+import {
+ Pagination,
+ PaginationContent,
+ PaginationEllipsis,
+ PaginationItem,
+ PaginationLink,
+ PaginationNext,
+ PaginationPrevious,
+} from '@/views/components/ui/pagination';
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from '@/views/components/ui/table';
+import { useEffect, useState } from 'react';
+
+import type { Protocol } from '@/services/protocolService';
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+} from '../components/ui/card';
+
+type Props = {
+ status: string;
+};
+
+export function ProtocolsDialog({ status }: Props) {
+ const [open, setOpen] = useState(false);
+ const [search, setSearch] = useState('');
+ const [page, setPage] = useState(1);
+ const [pageSize] = useState(10);
+ const [allItems, setAllItems] = useState([]);
+ const [paginatedItems, setPaginatedItems] = useState([]);
+ const [total, setTotal] = useState(0);
+ const [loading, setLoading] = useState(false);
+ const [counts, setCounts] = useState>({ Todos: 0 });
+
+ const label = `${status} (${counts[status] ?? 0})`;
+
+ useEffect(() => {
+ setCounts(getCounts());
+ }, []);
+
+ useEffect(() => {
+ if (!open) return;
+
+ setLoading(true);
+ getProtocols({
+ status: status as any,
+ page: 1,
+ pageSize: 1000,
+ search,
+ }).then((r) => {
+ setAllItems(r.items);
+ setTotal(r.total);
+ setLoading(false);
+ setPage(1); // Reset para primeira página quando buscar
+ });
+ }, [open, search, status]);
+
+ // Efeito para aplicar a paginação local
+ useEffect(() => {
+ if (allItems.length === 0) {
+ setPaginatedItems([]);
+ return;
+ }
+
+ const startIndex = (page - 1) * pageSize;
+ const endIndex = startIndex + pageSize;
+ const itemsForCurrentPage = allItems.slice(startIndex, endIndex);
+
+ setPaginatedItems(itemsForCurrentPage);
+ }, [allItems, page, pageSize]);
+
+ const totalPages = Math.max(1, Math.ceil(total / pageSize));
+
+ function getPageItems(totalPages: number, current: number) {
+ const pages: Array = [];
+ if (totalPages <= 7) {
+ for (let i = 1; i <= totalPages; i++) pages.push(i);
+ return pages;
+ }
+
+ pages.push(1);
+ const left = Math.max(2, current - 1);
+ const right = Math.min(totalPages - 1, current + 1);
+
+ if (left > 2) pages.push('ellipsis');
+
+ for (let i = left; i <= right; i++) pages.push(i);
+
+ if (right < totalPages - 1) pages.push('ellipsis');
+
+ pages.push(totalPages);
+ return pages;
+ }
+
+ const handlePreviousPage = () => {
+ if (page > 1) {
+ setPage(page - 1);
+ }
+ };
+
+ const handleNextPage = () => {
+ if (page < totalPages) {
+ setPage(page + 1);
+ }
+ };
+
+ const handlePageClick = (pageNumber: number) => {
+ setPage(pageNumber);
+ };
+
+ const pageItems = getPageItems(totalPages, page);
+
+ return (
+
+ );
+}
+
+export default ProtocolsDialog;
|