From 4af7c35f7302fbf9b6cecfb762d3cc749f7e8fd6 Mon Sep 17 00:00:00 2001 From: Lucas Rodrigues Date: Tue, 7 Oct 2025 22:59:00 -0300 Subject: [PATCH] =?UTF-8?q?cirando=20p=C3=A1gina=20de=20consultas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/doctor/medicos/consultas/page.tsx | 202 ++++++++++++++++++++++++++ components/doctor-layout.tsx | 4 +- 2 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 app/doctor/medicos/consultas/page.tsx diff --git a/app/doctor/medicos/consultas/page.tsx b/app/doctor/medicos/consultas/page.tsx new file mode 100644 index 0000000..ed91ae3 --- /dev/null +++ b/app/doctor/medicos/consultas/page.tsx @@ -0,0 +1,202 @@ +"use client"; + +import type React from "react"; +import { useState, useEffect } from "react"; +import DoctorLayout from "@/components/doctor-layout"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Clock, Calendar, MapPin, Phone, User, X, RefreshCw } from "lucide-react"; +import { Badge } from "@/components/ui/badge"; +import { toast } from "sonner"; + +const APPOINTMENTS_STORAGE_KEY = "clinic-appointments"; + +// --- TIPAGEM DA CONSULTA SALVA NO LOCALSTORAGE --- +// Reflete a estrutura salva pelo secretarypage.tsx +interface LocalStorageAppointment { + id: number; // ID único simples (timestamp) + patientName: string; + doctor: string; // Nome completo do médico (para filtrar) + specialty: string; + date: string; // Data no formato YYYY-MM-DD + time: string; // Hora no formato HH:MM + status: "agendada" | "confirmada" | "cancelada" | "realizada"; + location: string; + phone: string; +} + +// --- SIMULAÇÃO DO MÉDICO LOGADO --- +// **IMPORTANTE**: Em um ambiente real, este valor viria do seu sistema de autenticação. +// Use um nome que corresponda a um médico que você cadastrou e usou para agendar. +const LOGGED_IN_DOCTOR_NAME = "Dr. João Silva"; // <--- AJUSTE ESTE NOME PARA TESTAR + +// --- COMPONENTE PRINCIPAL --- + +export default function DoctorAppointmentsPage() { + const [appointments, setAppointments] = useState([]); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + loadAppointments(); + }, []); + + const loadAppointments = () => { + setIsLoading(true); + try { + const storedAppointmentsRaw = localStorage.getItem(APPOINTMENTS_STORAGE_KEY); + const allAppointments: LocalStorageAppointment[] = storedAppointmentsRaw ? JSON.parse(storedAppointmentsRaw) : []; + + // 1. FILTRAGEM CRÍTICA: Apenas as consultas para o médico logado + const filteredAppointments = allAppointments.filter( + (app) => app.doctor === LOGGED_IN_DOCTOR_NAME + ); + + // 2. Ordena por Data e Hora + filteredAppointments.sort((a, b) => { + const dateTimeA = new Date(`${a.date}T${a.time}:00`); + const dateTimeB = new Date(`${b.date}T${b.time}:00`); + return dateTimeA.getTime() - dateTimeB.getTime(); + }); + + setAppointments(filteredAppointments); + toast.success("Agenda atualizada com sucesso!"); + } catch (error) { + console.error("Erro ao carregar a agenda do LocalStorage:", error); + toast.error("Não foi possível carregar sua agenda."); + } finally { + setIsLoading(false); + } + }; + + // Função utilitária para mapear o status para a cor da Badge + const getStatusVariant = (status: LocalStorageAppointment['status']) => { + switch (status) { + case "confirmada": + case "agendada": + return "default"; + case "realizada": + return "secondary"; + case "cancelada": + return "destructive"; + default: + return "outline"; + } + }; + + const handleCancel = (id: number) => { + // Lógica para CANCELAR a consulta no LocalStorage + const storedAppointmentsRaw = localStorage.getItem(APPOINTMENTS_STORAGE_KEY); + const allAppointments: LocalStorageAppointment[] = storedAppointmentsRaw ? JSON.parse(storedAppointmentsRaw) : []; + + const updatedAppointments = allAppointments.map(app => + app.id === id ? { ...app, status: "cancelada" as const } : app + ); + + localStorage.setItem(APPOINTMENTS_STORAGE_KEY, JSON.stringify(updatedAppointments)); + loadAppointments(); // Recarrega a lista filtrada + toast.info(`Consulta cancelada com sucesso.`); + }; + + const handleReSchedule = (id: number) => { + // Aqui você navegaria para a tela de agendamento passando o ID para pré-preencher + toast.info(`Reagendamento da Consulta ID: ${id}. Navegar para a página de agendamento.`); + }; + + return ( + +
+
+

Minhas Consultas

+

Agenda atual ({LOGGED_IN_DOCTOR_NAME}) e histórico de atendimentos

+
+ +
+ +
+ +
+ {isLoading ? ( +

Carregando a agenda...

+ ) : appointments.length === 0 ? ( +

Nenhuma consulta agendada para você (Médico: {LOGGED_IN_DOCTOR_NAME}).

+ ) : ( + appointments.map((appointment) => { + // Formatação de data e hora + const showActions = appointment.status === "agendada" || appointment.status === "confirmada"; + + return ( + + + {/* NOME DO PACIENTE */} + + + {appointment.patientName} + + {/* STATUS DA CONSULTA */} + + {appointment.status} + + + + + {/* COLUNA 1: Data e Hora */} +
+
+ + {new Date(appointment.date).toLocaleDateString("pt-BR", { timeZone: "UTC" })} +
+
+ + {appointment.time} +
+
+ + {/* COLUNA 2: Local e Contato */} +
+
+ + {appointment.location} +
+
+ + {/* Note: O telefone do paciente não está salvo no LocalStorage no seu código atual, usando um valor fixo */} + {(appointment.phone || "(11) 9XXXX-YYYY")} +
+
+ + {/* COLUNA 3: Ações (Botões) */} +
+ {showActions && ( +
+ + +
+ )} +
+
+
+ ); + }) + )} +
+
+
+ ); +} \ No newline at end of file diff --git a/components/doctor-layout.tsx b/components/doctor-layout.tsx index b8b2fc0..a73448e 100644 --- a/components/doctor-layout.tsx +++ b/components/doctor-layout.tsx @@ -88,7 +88,7 @@ useEffect(() => { // Botão para o dashboard do médico }, { - href: "#", + href: "/doctor/medicos/consultas", icon: Calendar, label: "Consultas", // Botão para página de consultas marcadas do médico atual @@ -331,4 +331,4 @@ useEffect(() => { ); -} \ No newline at end of file +}