From 74a7fa91dede17576edb8ff9886cb3a0d4d7ef6f Mon Sep 17 00:00:00 2001 From: Jhony Date: Mon, 24 Nov 2025 20:07:38 -0300 Subject: [PATCH 1/2] pequenos ajustes --- .../[id]/laudos/[laudoId]/editar/page.tsx | 4 - app/doctor/medicos/[id]/laudos/novo/page.tsx | 7 +- app/doctor/medicos/page.tsx | 15 +- app/manager/home/page.tsx | 6 +- app/manager/pacientes/page.tsx | 6 +- app/secretary/appointments/page.tsx | 2 +- app/secretary/pacientes/page.tsx | 147 +++++++++--------- components/doctor-layout.tsx | 6 - components/ui/button.tsx | 39 ++--- 9 files changed, 111 insertions(+), 121 deletions(-) diff --git a/app/doctor/medicos/[id]/laudos/[laudoId]/editar/page.tsx b/app/doctor/medicos/[id]/laudos/[laudoId]/editar/page.tsx index 02f1e6c..7257b53 100644 --- a/app/doctor/medicos/[id]/laudos/[laudoId]/editar/page.tsx +++ b/app/doctor/medicos/[id]/laudos/[laudoId]/editar/page.tsx @@ -144,10 +144,6 @@ export default function EditarLaudoPage() {
-
- - -
diff --git a/app/doctor/medicos/[id]/laudos/novo/page.tsx b/app/doctor/medicos/[id]/laudos/novo/page.tsx index 215d3a6..57371ba 100644 --- a/app/doctor/medicos/[id]/laudos/novo/page.tsx +++ b/app/doctor/medicos/[id]/laudos/novo/page.tsx @@ -1,5 +1,4 @@ - -"use client"; + "use client"; import { useParams, useRouter } from "next/navigation"; import { useState } from "react"; @@ -106,10 +105,6 @@ export default function NovoLaudoPage() {
-
- - -
diff --git a/app/doctor/medicos/page.tsx b/app/doctor/medicos/page.tsx index bc18221..ae26555 100644 --- a/app/doctor/medicos/page.tsx +++ b/app/doctor/medicos/page.tsx @@ -10,7 +10,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; -import { Eye, Edit, Calendar, Trash2, Loader2 } from "lucide-react"; +import { Eye, Edit, Calendar, Trash2, Loader2, MoreVertical } from "lucide-react"; import { api } from "@/services/api.mjs"; import { PatientDetailsModal } from "@/components/ui/patient-details-modal"; import { @@ -272,9 +272,10 @@ export default function PacientesPage() { - + handleOpenModal(p)}> @@ -282,15 +283,11 @@ export default function PacientesPage() { Ver detalhes - + Laudos - alert(`Agenda para paciente ID: ${p.id}`)}> - - Ver agenda - { // Simulação de exclusão (A exclusão real deve ser feita via API) diff --git a/app/manager/home/page.tsx b/app/manager/home/page.tsx index 03b64a5..6711ef6 100644 --- a/app/manager/home/page.tsx +++ b/app/manager/home/page.tsx @@ -7,7 +7,7 @@ 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 { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react" +import { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2, MoreVertical } from "lucide-react" import { AlertDialog, AlertDialogAction, @@ -308,7 +308,9 @@ export default function DoctorsPage() { {/* ===== INÍCIO DA ALTERAÇÃO ===== */} -
Ações
+
+ +
openDetailsDialog(doctor)}> diff --git a/app/manager/pacientes/page.tsx b/app/manager/pacientes/page.tsx index 5fb159b..e13e7b1 100644 --- a/app/manager/pacientes/page.tsx +++ b/app/manager/pacientes/page.tsx @@ -6,7 +6,7 @@ import Link from "next/link"; 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 { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react"; +import { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2, MoreVertical } from "lucide-react"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; import { patientsService } from "@/services/patientsApi.mjs"; import ManagerLayout from "@/components/manager-layout"; @@ -267,7 +267,9 @@ export default function PacientesPage() { -
Ações
+
+ +
openDetailsDialog(String(patient.id))}> diff --git a/app/secretary/appointments/page.tsx b/app/secretary/appointments/page.tsx index 679ba8e..274b217 100644 --- a/app/secretary/appointments/page.tsx +++ b/app/secretary/appointments/page.tsx @@ -204,7 +204,7 @@ export default function SecretaryAppointments() {
diff --git a/app/secretary/pacientes/page.tsx b/app/secretary/pacientes/page.tsx index 623a966..3445b39 100644 --- a/app/secretary/pacientes/page.tsx +++ b/app/secretary/pacientes/page.tsx @@ -6,44 +6,44 @@ import Link from "next/link"; 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 { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react"; +import { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2, MoreVertical } from "lucide-react"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; import SecretaryLayout from "@/components/secretary-layout"; import { patientsService } from "@/services/patientsApi.mjs"; // Defina o tamanho da página. -const PAGE_SIZE = 5; +const PAGE_SIZE = 5; export default function PacientesPage() { // --- ESTADOS DE DADOS E GERAL --- const [searchTerm, setSearchTerm] = useState(""); const [convenioFilter, setConvenioFilter] = useState("all"); const [vipFilter, setVipFilter] = useState("all"); - - // Lista completa, carregada da API uma única vez - const [allPatients, setAllPatients] = useState([]); - // Lista após a aplicação dos filtros (base para a paginação) - const [filteredPatients, setFilteredPatients] = useState([]); - const [loading, setLoading] = useState(true); + // Lista completa, carregada da API uma única vez + const [allPatients, setAllPatients] = useState([]); + // Lista após a aplicação dos filtros (base para a paginação) + const [filteredPatients, setFilteredPatients] = useState([]); + + const [loading, setLoading] = useState(true); const [error, setError] = useState(null); - + // --- ESTADOS DE PAGINAÇÃO --- const [page, setPage] = useState(1); - + // CÁLCULO DA PAGINAÇÃO const totalPages = Math.ceil(filteredPatients.length / PAGE_SIZE); const startIndex = (page - 1) * PAGE_SIZE; const endIndex = startIndex + PAGE_SIZE; // Pacientes a serem exibidos na tabela (aplicando a paginação) - const currentPatients = filteredPatients.slice(startIndex, endIndex); + const currentPatients = filteredPatients.slice(startIndex, endIndex); // --- ESTADOS DE DIALOGS --- const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [patientToDelete, setPatientToDelete] = useState(null); const [detailsDialogOpen, setDetailsDialogOpen] = useState(false); const [patientDetails, setPatientDetails] = useState(null); - + // --- FUNÇÕES DE LÓGICA --- // 1. Função para carregar TODOS os pacientes da API @@ -54,7 +54,7 @@ export default function PacientesPage() { try { // Como o backend retorna um array, chamamos sem paginação const res = await patientsService.list(); - + const mapped = res.map((p: any) => ({ id: String(p.id ?? ""), nome: p.full_name ?? "—", @@ -62,7 +62,7 @@ export default function PacientesPage() { cidade: p.city ?? "—", estado: p.state ?? "—", // Formate as datas se necessário, aqui usamos como string - ultimoAtendimento: p.last_visit_at?.split('T')[0] ?? "—", + ultimoAtendimento: p.last_visit_at?.split('T')[0] ?? "—", proximoAtendimento: p.next_appointment_at?.split('T')[0] ?? "—", vip: Boolean(p.vip ?? false), convenio: p.convenio ?? "Particular", // Define um valor padrão @@ -84,27 +84,27 @@ export default function PacientesPage() { useEffect(() => { const filtered = allPatients.filter((patient) => { // Filtro por termo de busca (Nome ou Telefone) - const matchesSearch = - patient.nome?.toLowerCase().includes(searchTerm.toLowerCase()) || + const matchesSearch = + patient.nome?.toLowerCase().includes(searchTerm.toLowerCase()) || patient.telefone?.includes(searchTerm); - + // Filtro por Convênio - const matchesConvenio = - convenioFilter === "all" || + const matchesConvenio = + convenioFilter === "all" || patient.convenio === convenioFilter; - + // Filtro por VIP - const matchesVip = - vipFilter === "all" || - (vipFilter === "vip" && patient.vip) || + const matchesVip = + vipFilter === "all" || + (vipFilter === "vip" && patient.vip) || (vipFilter === "regular" && !patient.vip); return matchesSearch && matchesConvenio && matchesVip; }); - + setFilteredPatients(filtered); // Garante que a página atual seja válida após a filtragem - setPage(1); + setPage(1); }, [allPatients, searchTerm, convenioFilter, vipFilter]); // 3. Efeito inicial para buscar os pacientes @@ -115,7 +115,7 @@ export default function PacientesPage() { // --- LÓGICA DE AÇÕES (DELETAR / VER DETALHES) --- - + const openDetailsDialog = async (patientId: string) => { setDetailsDialogOpen(true); setPatientDetails(null); @@ -166,7 +166,7 @@ export default function PacientesPage() { {/* Bloco de Filtros (Responsividade APLICADA) */}
- + {/* Busca - Ocupa 100% no mobile, depois cresce */}
- + {/* Aniversariantes - Vai para a linha de baixo no mobile, ocupando 100% */}
) : ( // min-w ajustado para responsividade - +
@@ -271,11 +271,14 @@ export default function PacientesPage() { - + + + )))} + +
Nome{patient.convenio} {patient.ultimoAtendimento} {patient.proximoAtendimento} -
Ações
+
openDetailsDialog(String(patient.id))}> @@ -351,7 +354,7 @@ export default function PacientesPage() { )} - + {/* AlertDialogs (Permanecem os mesmos) */} {/* ... (AlertDialog de Exclusão) ... */} @@ -386,65 +389,65 @@ export default function PacientesPage() {
-

Nome Completo

-

{patientDetails.full_name}

+

Nome Completo

+

{patientDetails.full_name}

-

Email

-

{patientDetails.email}

+

Email

+

{patientDetails.email}

-

Telefone

-

{patientDetails.phone_mobile}

+

Telefone

+

{patientDetails.phone_mobile}

-

Data de Nascimento

-

{patientDetails.birth_date}

+

Data de Nascimento

+

{patientDetails.birth_date}

-

CPF

-

{patientDetails.cpf}

+

CPF

+

{patientDetails.cpf}

-

Tipo Sanguíneo

-

{patientDetails.blood_type}

+

Tipo Sanguíneo

+

{patientDetails.blood_type}

-

Peso (kg)

-

{patientDetails.weight_kg}

+

Peso (kg)

+

{patientDetails.weight_kg}

-

Altura (m)

-

{patientDetails.height_m}

+

Altura (m)

+

{patientDetails.height_m}

Endereço

-
-

Rua

-

{`${patientDetails.street}, ${patientDetails.number}`}

-
-
-

Complemento

-

{patientDetails.complement}

-
-
-

Bairro

-

{patientDetails.neighborhood}

-
-
-

Cidade

-

{patientDetails.cidade}

-
-
-

Estado

-

{patientDetails.estado}

-
-
-

CEP

-

{patientDetails.cep}

-
+
+

Rua

+

{`${patientDetails.street}, ${patientDetails.number}`}

+
+
+

Complemento

+

{patientDetails.complement}

+
+
+

Bairro

+

{patientDetails.neighborhood}

+
+
+

Cidade

+

{patientDetails.cidade}

+
+
+

Estado

+

{patientDetails.estado}

+
+
+

CEP

+

{patientDetails.cep}

+
diff --git a/components/doctor-layout.tsx b/components/doctor-layout.tsx index 2ce2884..21fdf44 100644 --- a/components/doctor-layout.tsx +++ b/components/doctor-layout.tsx @@ -147,12 +147,6 @@ export default function DoctorLayout({ children }: PatientLayoutProps) { label: "Consultas", // Botão para página de consultas marcadas do médico atual }, - { - href: "/doctor/medicos/editorlaudo", - icon: Clock, - label: "Editor de Laudo", - // Botão para página do editor de laudo - }, { href: "/doctor/medicos", icon: User, diff --git a/components/ui/button.tsx b/components/ui/button.tsx index 815443b..2bc4400 100644 --- a/components/ui/button.tsx +++ b/components/ui/button.tsx @@ -35,25 +35,26 @@ const buttonVariants = cva( }, ) -function Button({ - className, - variant, - size, - asChild = false, - ...props -}: React.ComponentProps<'button'> & - VariantProps & { - asChild?: boolean - }) { - const Comp = asChild ? Slot : 'button' - - return ( - - ) +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean } +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : 'button' + + return ( + + ) + } +) +Button.displayName = 'Button' + export { Button, buttonVariants } From 71963064e0ef2e1b8487ba2987a5d94497e58ff2 Mon Sep 17 00:00:00 2001 From: StsDanilo Date: Wed, 26 Nov 2025 19:36:20 -0300 Subject: [PATCH 2/2] Ajuste de fechamentos --- app/manager/pacientes/page.tsx | 44 ++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/app/manager/pacientes/page.tsx b/app/manager/pacientes/page.tsx index 5b2a6d9..e6886f3 100644 --- a/app/manager/pacientes/page.tsx +++ b/app/manager/pacientes/page.tsx @@ -280,28 +280,30 @@ export default function PacientesPage() { Ver detalhes
+ + + + Editar + + - - - - Editar - - - - - - Marcar consulta - - openDeleteDialog(String(patient.id))}> - - Excluir - -
-
- - ))} - - )} + + + Marcar consulta + + openDeleteDialog(String(patient.id))}> + + Excluir + + + +
+ )} +
{/* Paginação */}