diff --git a/app/manager/home/page.tsx b/app/manager/home/page.tsx index afa89ed..fe49726 100644 --- a/app/manager/home/page.tsx +++ b/app/manager/home/page.tsx @@ -6,7 +6,8 @@ import { useRouter } from "next/navigation"; import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react" +import { Input } from "@/components/ui/input" // <--- 1. Importação adicionada +import { Edit, Trash2, Eye, Calendar, Filter, Loader2, Search } from "lucide-react" // <--- Adicionado ícone Search import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog" import { doctorsService } from "services/doctorsApi.mjs"; @@ -56,6 +57,7 @@ export default function DoctorsPage() { const [doctorToDeleteId, setDoctorToDeleteId] = useState(null); // --- Estados para Filtros --- + const [searchTerm, setSearchTerm] = useState(""); // <--- 2. Novo estado para a busca const [specialtyFilter, setSpecialtyFilter] = useState("all"); const [statusFilter, setStatusFilter] = useState("all"); @@ -129,10 +131,21 @@ export default function DoctorsPage() { return [...new Set(specialties)]; }, [doctors]); + // --- 3. Atualização da Lógica de Filtragem --- const filteredDoctors = doctors.filter((doctor) => { const specialtyMatch = specialtyFilter === "all" || doctor.specialty === specialtyFilter; const statusMatch = statusFilter === "all" || doctor.status === statusFilter; - return specialtyMatch && statusMatch; + + // Lógica da barra de pesquisa + const searchLower = searchTerm.toLowerCase(); + const nameMatch = doctor.full_name?.toLowerCase().includes(searchLower); + const phoneMatch = doctor.phone_mobile?.includes(searchLower); + // Opcional: buscar também por CRM se desejar + const crmMatch = doctor.crm?.toLowerCase().includes(searchLower); + + const searchMatch = searchTerm === "" || nameMatch || phoneMatch || crmMatch; + + return specialtyMatch && statusMatch && searchMatch; }); const totalPages = Math.ceil(filteredDoctors.length / itemsPerPage); @@ -189,55 +202,64 @@ export default function DoctorsPage() { - {/* Filtros e Itens por Página */} -
-
- Especialidade - + {/* --- Filtros e Barra de Pesquisa Atualizada --- */} +
+ + {/* Barra de Pesquisa (Estilo similar à foto) */} +
+ + setSearchTerm(e.target.value)} + className="pl-10 w-full bg-gray-50 border-gray-200 focus:bg-white transition-colors" + />
-
- Status - + +
+
+ +
+ +
+ +
+ +
+ +
-
- Itens por página - -
-
{/* Tabela de Médicos (Visível em Telas Médias e Maiores) */} @@ -272,10 +294,20 @@ export default function DoctorsPage() { {currentItems.map((doctor) => ( - {doctor.full_name} + + {doctor.full_name} +
{doctor.phone_mobile}
+ {doctor.crm} {doctor.specialty} - {doctor.status || "N/A"} + + + {doctor.status || "N/A"} + + {(doctor.city || doctor.state) ? `${doctor.city || ""}${doctor.city && doctor.state ? '/' : ''}${doctor.state || ""}` @@ -284,7 +316,7 @@ export default function DoctorsPage() { -
Ações
+
Ações
openDetailsDialog(doctor)}> @@ -335,14 +367,26 @@ export default function DoctorsPage() { ) : (
{currentItems.map((doctor) => ( -
+
{doctor.full_name}
+
{doctor.phone_mobile}
{doctor.specialty}
+
+ + {doctor.status || "N/A"} + +
-
Ações
+
openDetailsDialog(doctor)}> @@ -355,10 +399,6 @@ export default function DoctorsPage() { Editar - - - Marcar consulta - openDeleteDialog(doctor.id)}> Excluir @@ -406,7 +446,7 @@ export default function DoctorsPage() {
)} - {/* Dialogs de Exclusão e Detalhes */} + {/* Dialogs (Exclusão e Detalhes) mantidos igual ao original... */} diff --git a/app/manager/usuario/page.tsx b/app/manager/usuario/page.tsx index 9cc8bbc..df0ece3 100644 --- a/app/manager/usuario/page.tsx +++ b/app/manager/usuario/page.tsx @@ -4,7 +4,8 @@ import React, { useEffect, useState, useCallback } from "react"; import Link from "next/link"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { Plus, Eye, Filter, Loader2 } from "lucide-react"; +import { Input } from "@/components/ui/input"; // <--- 1. Importação Adicionada +import { Plus, Eye, Filter, Loader2, Search } from "lucide-react"; // <--- 1. Ícone Search Adicionado import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; import { api, login } from "services/api.mjs"; import { usersService } from "services/usersApi.mjs"; @@ -34,6 +35,9 @@ export default function UsersPage() { const [userDetails, setUserDetails] = useState( null ); + + // --- Estados de Filtro --- + const [searchTerm, setSearchTerm] = useState(""); // <--- 2. Estado da busca const [selectedRole, setSelectedRole] = useState("all"); // --- Lógica de Paginação INÍCIO --- @@ -118,10 +122,21 @@ export default function UsersPage() { } }; - const filteredUsers = - selectedRole && selectedRole !== "all" - ? users.filter((u) => u.role === selectedRole) - : users; + // --- 3. Lógica de Filtragem Atualizada --- + const filteredUsers = users.filter((u) => { + // Filtro por Papel (Role) + const roleMatch = selectedRole === "all" || u.role === selectedRole; + + // Filtro da Barra de Pesquisa (Nome, Email ou Telefone) + const searchLower = searchTerm.toLowerCase(); + const nameMatch = u.full_name?.toLowerCase().includes(searchLower); + const emailMatch = u.email?.toLowerCase().includes(searchLower); + const phoneMatch = u.phone?.includes(searchLower); + + const searchMatch = !searchTerm || nameMatch || emailMatch || phoneMatch; + + return roleMatch && searchMatch; + }); const indexOfLastItem = currentPage * itemsPerPage; const indexOfFirstItem = indexOfLastItem - itemsPerPage; @@ -180,60 +195,71 @@ export default function UsersPage() {
- {/* Filtro e Itens por Página */} -
+ {/* --- 4. Filtro (Barra de Pesquisa + Selects) --- */} +
- {/* Select de Filtro por Papel - Ajustado para resetar a página */} -
- - Filtrar por papel - - { + setSearchTerm(e.target.value); + setCurrentPage(1); // Reseta a paginação ao pesquisar }} - value={selectedRole}> - - {/* w-full para mobile, w-[180px] para sm+ */} - - - - Todos - Admin - Gestor - Médico - Secretária - Usuário - - + className="pl-10 w-full bg-gray-50 border-gray-200 focus:bg-white transition-colors" + />
- {/* Select de Itens por Página */} -
- - Itens por página - - +
+ {/* Select de Filtro por Papel */} +
+ +
+ + {/* Select de Itens por Página */} +
+ +
+ +
-
- {/* Fim do Filtro e Itens por Página */} + {/* Fim do Filtro */} {/* Tabela/Lista */}
@@ -299,7 +325,10 @@ export default function UsersPage() {
{u.full_name || "—"}
-
+
+ {u.email} +
+
{u.role || "—"}