import { addDays, addMonths, addWeeks, endOfWeek, format, startOfWeek, subDays, subMonths, subWeeks, } from 'date-fns' import { ptBR } from 'date-fns/locale' import { useState } from 'react' import { AgendaDailyView } from '../components/calendar/AgendaDailyView.jsx' import { AgendaMonthlyView } from '../components/calendar/AgendaMonthlyView.jsx' import { AgendaWeeklyView } from '../components/calendar/AgendaWeeklyView.jsx' import { useAgenda } from '../hooks/useAgenda.js' import { formatLocalDateInput, parseLocalDate } from '../utils/agendaDate.js' const statusFilters = [ { label: 'Todos', value: 'Todos' }, { label: 'Confirmadas', value: 'Confirmada' }, { label: 'Em triagem', value: 'Em triagem' }, { label: 'Aguardando', value: 'Aguardando' }, { label: 'Canceladas', value: 'Cancelada' }, ] const viewFilters = [ { label: 'Dia', value: 'Dia' }, { label: 'Semana', value: 'Semana' }, { label: 'Mês', value: 'Mes' }, ] const appointmentTypeOptions = ['Retorno', 'Primeira consulta', 'Exame', 'Avaliação pre-op'] const appointmentStatusOptions = ['Confirmada', 'Em triagem', 'Aguardando'] export function AgendaPage() { const [modalPatientSearch, setModalPatientSearch] = useState('') const [modalDoctorSearch, setModalDoctorSearch] = useState('') const { patients, professionals, currentProfessional, viewerProfile, agendaScope, loading, error, canCreateAppointment, activeView, setActiveView, baseDate, setBaseDate, status, setStatus, setDoctorFilter, doctorSearch, setDoctorSearch, unitFilter, setUnitFilter, modalOpen, editingAppointment, form, updateForm, openCreateModal, openAppointmentModal, closeAppointmentModal, handleSubmitAppointment, handleCancelAppointment, visibleAppointments, availableSlots, slotsLoading, slotsError, } = useAgenda() if (loading) { return (

Carregando agenda...

) } const weekStart = startOfWeek(baseDate, { weekStartsOn: 0 }) const weekEnd = endOfWeek(baseDate, { weekStartsOn: 0 }) const isDoctorScope = agendaScope === 'doctor' const unitOptions = [ ...new Set(professionals.map((professional) => professional.unit).filter(Boolean)), ].sort((a, b) => a.localeCompare(b, 'pt-BR')) const filteredPatients = filterBySearch(patients, modalPatientSearch, (patient) => [ patient.name, patient.full_name, patient.nome, patient.cpf, patient.email, ]) const filteredProfessionals = filterBySearch(professionals, modalDoctorSearch, (professional) => [ professional.name, professional.email, professional.unit, ]) const selectedPatient = patients.find((patient) => String(patient.id) === String(form.patientId)) const selectedProfessional = professionals.find((professional) => String(professional.id) === String(form.professionalId)) const timeOptions = getTimeOptions(form.time, availableSlots) function openCreate(options = {}) { setModalPatientSearch('') setModalDoctorSearch('') openCreateModal(options) } function openManage(appointment) { setModalPatientSearch('') setModalDoctorSearch('') openAppointmentModal(appointment) } function closeModal() { setModalPatientSearch('') setModalDoctorSearch('') closeAppointmentModal() } return (

Agenda

Perfil atual: {viewerProfile?.role || (isDoctorScope ? 'Médico' : 'Usuário')}

{activeView === 'Dia' && format(baseDate, "dd 'de' MMM", { locale: ptBR })} {activeView === 'Semana' && `${format(weekStart, 'dd MMM', { locale: ptBR })} - ${format(weekEnd, 'dd MMM', { locale: ptBR })}`} {activeView === 'Mes' && format(baseDate, 'MMMM yyyy', { locale: ptBR })}
{error ? (

Não foi possível liberar a agenda

{error}

Enquanto esse vínculo não existir na API, a tela fica bloqueada para evitar exibir consultas de outro médico.

) : (

{format(baseDate, "EEEE, dd 'de' MMMM", { locale: ptBR })}

Visualização: {activeView.toLowerCase()} | {visibleAppointments.length} registros visíveis

{viewFilters.map((view) => ( ))}
{statusFilters.map((filter) => ( ))}
{!isDoctorScope ? (
) : null}
{!isDoctorScope && (
Perfil atual: {viewerProfile?.role || 'Administrador'}
)}
{activeView === 'Semana' && ( )} {activeView === 'Mes' && ( { setBaseDate(day) setActiveView('Dia') }} /> )} {activeView === 'Dia' && ( openCreate({ time })} /> )}
)}
{ setModalPatientSearch(event.target.value) updateForm('patientId', '') }} placeholder="Pesquisar paciente" type="search" value={modalPatientSearch || getPatientLabel(selectedPatient)} /> { updateForm('patientId', patient.id) setModalPatientSearch(getPatientLabel(patient)) }} selectedId={form.patientId} /> {isDoctorScope ? ( ) : ( <> { setModalDoctorSearch(event.target.value) updateForm('professionalId', '') }} placeholder="Pesquisar médico" type="search" value={modalDoctorSearch || selectedProfessional?.name || ''} /> professional.unit || professional.email} getLabel={(professional) => professional.name} items={filteredProfessionals.slice(0, 5)} onSelect={(professional) => { updateForm('professionalId', professional.id) setModalDoctorSearch(professional.name) }} selectedId={form.professionalId} /> )}
{ const parsedDate = parseLocalDate(event.target.value) if (parsedDate) setBaseDate(parsedDate) }} type="date" value={formatLocalDateInput(baseDate)} /> {timeOptions.length ? ( ) : ( updateForm('time', event.target.value)} type="time" value={form.time} /> )} {slotsLoading ? Calculando horários... : null} {slotsError ? {slotsError} : null}