"use client"; // Imports mantidos import { useEffect, useState } from "react"; import dynamic from "next/dynamic"; // --- Imports do EventManager (NOVO) - MANTIDOS --- import { EventManager, type Event } from "@/components/features/general/event-manager"; import { v4 as uuidv4 } from 'uuid'; // Usado para IDs de fallback // Imports mantidos import { Button } from "@/components/ui/button"; import { useAuth } from "@/hooks/useAuth"; import { mockWaitingList } from "@/lib/mocks/appointment-mocks"; import "./index.css"; import { ThreeDWallCalendar, CalendarEvent } from "@/components/ui/three-dwall-calendar"; // Calendário 3D mantido import { PatientRegistrationForm } from "@/components/features/forms/patient-registration-form"; const ListaEspera = dynamic( () => import("@/components/features/agendamento/ListaEspera"), { ssr: false } ); export default function AgendamentoPage() { const { user, token } = useAuth(); const [appointments, setAppointments] = useState([]); const [activeTab, setActiveTab] = useState<"calendar" | "3d">("calendar"); const [threeDEvents, setThreeDEvents] = useState([]); // Padroniza idioma da página para pt-BR (afeta componentes que usam o lang do documento) useEffect(() => { try { // Atributos no document.documentElement.lang = "pt-BR"; document.documentElement.setAttribute("xml:lang", "pt-BR"); document.documentElement.setAttribute("data-lang", "pt-BR"); // Cookie de locale (usado por apps com i18n) const oneYear = 60 * 60 * 24 * 365; document.cookie = `NEXT_LOCALE=pt-BR; Path=/; Max-Age=${oneYear}; SameSite=Lax`; } catch { // ignore } }, []); // --- NOVO ESTADO --- // Estado para alimentar o NOVO EventManager com dados da API const [managerEvents, setManagerEvents] = useState([]); const [managerLoading, setManagerLoading] = useState(true); // Estado para o formulário de registro de paciente const [showPatientForm, setShowPatientForm] = useState(false); useEffect(() => { document.addEventListener("keydown", (event) => { if (event.key === "c") setActiveTab("calendar"); if (event.key === "3") setActiveTab("3d"); }); }, []); useEffect(() => { let mounted = true; (async () => { try { setManagerLoading(true); const api = await import('@/lib/api'); const arr = await api.listarAgendamentos('select=*&order=scheduled_at.desc&limit=500').catch(() => []); if (!mounted) return; if (!arr || !arr.length) { setAppointments([]); setThreeDEvents([]); setManagerEvents([]); // Limpa o novo calendário setManagerLoading(false); return; } const patientIds = Array.from(new Set(arr.map((a: any) => a.patient_id).filter(Boolean))); const patients = (patientIds && patientIds.length) ? await api.buscarPacientesPorIds(patientIds) : []; const patientsById: Record = {}; (patients || []).forEach((p: any) => { if (p && p.id) patientsById[String(p.id)] = p; }); setAppointments(arr || []); // --- LÓGICA DE TRANSFORMAÇÃO PARA O NOVO EVENTMANAGER --- const newManagerEvents: Event[] = (arr || []).map((obj: any) => { const scheduled = obj.scheduled_at || obj.scheduledAt || obj.time || null; const start = scheduled ? new Date(scheduled) : new Date(); const duration = Number(obj.duration_minutes ?? obj.duration ?? 30) || 30; const end = new Date(start.getTime() + duration * 60 * 1000); const patient = (patientsById[String(obj.patient_id)]?.full_name) || obj.patient_name || obj.patient_full_name || obj.patient || 'Paciente'; const title = `${patient}: ${obj.appointment_type ?? obj.type ?? ''}`.trim(); // Mapeamento de cores padronizado: // azul = solicitado; verde = confirmado; laranja = pendente; vermelho = cancelado; azul como fallback const status = String(obj.status || "").toLowerCase(); let color: Event["color"] = "blue"; if (status === "confirmed" || status === "confirmado") color = "green"; else if (status === "pending" || status === "pendente") color = "orange"; else if (status === "canceled" || status === "cancelado" || status === "cancelled") color = "red"; else if (status === "requested" || status === "solicitado") color = "blue"; return { id: obj.id || uuidv4(), title, description: `Agendamento para ${patient}. Status: ${obj.status || 'N/A'}.`, startTime: start, endTime: end, color, }; }); setManagerEvents(newManagerEvents); setManagerLoading(false); // --- FIM DA LÓGICA --- // Convert to 3D calendar events (MANTIDO 100%) const threeDEvents: CalendarEvent[] = (arr || []).map((obj: any) => { const scheduled = obj.scheduled_at || obj.scheduledAt || obj.time || null; const patient = (patientsById[String(obj.patient_id)]?.full_name) || obj.patient_name || obj.patient_full_name || obj.patient || 'Paciente'; const appointmentType = obj.appointment_type ?? obj.type ?? 'Consulta'; const title = `${patient}: ${appointmentType}`.trim(); return { id: obj.id || String(Date.now()), title, date: scheduled ? new Date(scheduled).toISOString() : new Date().toISOString(), status: obj.status || 'pending', patient, type: appointmentType, }; }); setThreeDEvents(threeDEvents); } catch (err) { console.warn('[AgendamentoPage] falha ao carregar agendamentos', err); setAppointments([]); setThreeDEvents([]); setManagerEvents([]); // Limpa o novo calendário setManagerLoading(false); } })(); return () => { mounted = false; }; }, []); // Handlers mantidos const handleSaveAppointment = (appointment: any) => { if (appointment.id) { setAppointments((prev) => prev.map((a) => (a.id === appointment.id ? appointment : a)) ); } else { const newAppointment = { ...appointment, id: Date.now().toString(), }; setAppointments((prev) => [...prev, newAppointment]); } }; const handleAddEvent = (event: CalendarEvent) => { setThreeDEvents((prev) => [...prev, event]); }; const handleRemoveEvent = (id: string) => { setThreeDEvents((prev) => prev.filter((e) => e.id !== id)); }; return (
{/* Todo o cabeçalho foi mantido */}

{activeTab === "calendar" ? "Calendário" : activeTab === "3d" ? "Calendário 3D" : "Lista de Espera"}

Navegue através dos atalhos: Calendário (C), Fila de espera (F) ou 3D (3).

{/* Legenda de status (estilo Google Calendar) */}
Solicitado
Confirmado
{/* --- AQUI ESTÁ A SUBSTITUIÇÃO --- */} {activeTab === "calendar" ? (
{/* mostra loading até managerEvents ser preenchido (API integrada desde a entrada) */}
{managerLoading ? (
Conectando ao calendário — carregando agendamentos...
) : ( // EventManager ocupa a área principal e já recebe events da API
)}
) : activeTab === "3d" ? ( // O calendário 3D (ThreeDWallCalendar) foi MANTIDO 100%
setShowPatientForm(true)} />
) : null}
{/* Formulário de Registro de Paciente */} { console.log('[Calendar] Novo paciente registrado:', newPaciente); setShowPatientForm(false); }} />
); }