'use client'; import { useEffect, useState } from 'react'; import { useTranslations } from 'next-intl'; import { Button } from '@/components/ui/shared/Button'; import { DialogCloseButton } from '@/components/ui/shared/DialogCloseButton'; import { Dropdown } from '@/components/ui/shared/Dropdown'; import type { AppointmentPurpose, AppointmentRecord } from '@/types/appointment'; import { APPOINTMENT_PURPOSES } from '@/types/appointment'; import { getPurposeLabel } from '@/components/ui/appointments/appointmentPurposeStyles'; import type { Patient } from '@/types/patient'; import { combineLocalDateAndTime, compareLocalDayStart, formatTimeForInput, isSameLocalCalendarDay, } from '@/components/appointments/appointmentTime'; interface AppointmentBookingModalProps { open: boolean; scheduleDate: Date; patient: Patient | undefined; providerUserId: string | null; providerName: string; initialStartMinute: number; onClose: () => void; onSubmit: (payload: { patientId: string; providerUserId: string; startAt: string; endAt: string; purpose: AppointmentPurpose; }) => Promise; editingAppointment?: AppointmentRecord | null; loading?: boolean; canDelete?: boolean; onDelete?: () => void | Promise; deleting?: boolean; } const PURPOSE_OPTION_COLORS: Record = { consultation: '#ddd6fe', filling: '#fed7aa', endo: '#fecaca', visit: '#bae6fd', hygiene: '#d9f99d', }; export function AppointmentBookingModal({ open, scheduleDate, patient, providerUserId, providerName, initialStartMinute, onClose, onSubmit, editingAppointment = null, loading = false, canDelete = false, onDelete, deleting = false, }: AppointmentBookingModalProps) { const t = useTranslations('appointments'); const tCommon = useTranslations('common'); const tPatients = useTranslations('patients'); const [startTime, setStartTime] = useState('09:00'); const [endTime, setEndTime] = useState('10:00'); const [purpose, setPurpose] = useState('consultation'); const [error, setError] = useState(''); const purposeTextColor = PURPOSE_OPTION_COLORS[purpose]; useEffect(() => { if (!open) { return; } if (editingAppointment) { const start = new Date(editingAppointment.startAt); const end = new Date(editingAppointment.endAt); setStartTime(formatTimeForInput(start)); setEndTime(formatTimeForInput(end)); setPurpose((editingAppointment.purpose as AppointmentPurpose) ?? 'consultation'); } else { const start = new Date( scheduleDate.getFullYear(), scheduleDate.getMonth(), scheduleDate.getDate(), Math.floor(initialStartMinute / 60), initialStartMinute % 60, 0, 0, ); const endMinute = Math.min(initialStartMinute + 60, 24 * 60 - 1); const end = new Date( scheduleDate.getFullYear(), scheduleDate.getMonth(), scheduleDate.getDate(), Math.floor(endMinute / 60), endMinute % 60, 0, 0, ); setStartTime(formatTimeForInput(start)); setEndTime(formatTimeForInput(end)); setPurpose('consultation'); } setError(''); }, [open, scheduleDate, initialStartMinute, editingAppointment]); if (!open || !providerUserId) { return null; } const inputClass = 'w-full rounded-[var(--radius-md)] border border-border bg-background-secondary/90 text-text-primary px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/35'; async function handleSubmit() { setError(''); if (!providerUserId) { return; } if (!editingAppointment && !patient) { setError(t('errorSelectPatient')); return; } const startAt = combineLocalDateAndTime(scheduleDate, startTime); const endAt = combineLocalDateAndTime(scheduleDate, endTime); if (endAt <= startAt) { setError(t('errorEndAfterStart')); return; } const now = new Date(); if (isSameLocalCalendarDay(scheduleDate, now) && startAt.getTime() < now.getTime()) { setError(t('errorPastSchedule')); return; } const today = new Date(); if (compareLocalDayStart(scheduleDate, today) < 0) { setError(t('errorPastViewOnly')); return; } const effectivePatientId = editingAppointment?.patientId ?? patient?.id; const effectiveProviderId = editingAppointment?.providerUserId ?? providerUserId; if (!effectivePatientId || !effectiveProviderId) { setError(t('errorMissingDetails')); return; } await onSubmit({ patientId: effectivePatientId, providerUserId: effectiveProviderId, startAt: startAt.toISOString(), endAt: endAt.toISOString(), purpose, }); } return (

{editingAppointment ? t('editTitle') : t('newTitle')}

{t('providerLabel')}{' '} {providerName}

{editingAppointment ? `${editingAppointment.patient.firstName} ${editingAppointment.patient.lastName}` : patient ? `${patient.firstName} ${patient.lastName}` : tPatients('emptyValue')}

setStartTime(e.target.value)} />
setEndTime(e.target.value)} />
setPurpose(e.target.value as AppointmentPurpose)} style={{ color: purposeTextColor }} > {APPOINTMENT_PURPOSES.map((purposeOption) => ( ))} {error &&

{error}

}
{editingAppointment && canDelete && onDelete ? ( ) : ( )}
); }