'use client'; import type { AppointmentColumnProvider, AppointmentRecord } from '@/types/appointment'; import { formatHourLabel } from '@/lib/appointmentTime'; import { purposeStyle } from '@/components/ui/appointments/appointmentPurposeStyles'; const HOUR_PX = 40; const HOURS = Array.from({ length: 24 }, (_, i) => i); function layoutBlock(apt: AppointmentRecord, day: Date): { top: string; height: string } | null { const dayStart = new Date(day.getFullYear(), day.getMonth(), day.getDate(), 0, 0, 0, 0); const dayEnd = new Date(day.getFullYear(), day.getMonth(), day.getDate() + 1, 0, 0, 0, 0); const start = new Date(apt.startAt); const end = new Date(apt.endAt); const ms = dayEnd.getTime() - dayStart.getTime(); const clipStart = Math.max(start.getTime(), dayStart.getTime()); const clipEnd = Math.min(end.getTime(), dayEnd.getTime()); if (clipEnd <= clipStart) { return null; } const top = ((clipStart - dayStart.getTime()) / ms) * 100; const height = ((clipEnd - clipStart) / ms) * 100; return { top: `${top}%`, height: `${height}%` }; } function appointmentDurationMinutes(apt: AppointmentRecord): number { const start = new Date(apt.startAt).getTime(); const end = new Date(apt.endAt).getTime(); return Math.max(0, Math.round((end - start) / 60_000)); } interface AppointmentScheduleGridProps { day: Date; providers: AppointmentColumnProvider[]; appointments: AppointmentRecord[]; canBook: boolean; onSlotClick: (hour: number, providerUserId: string, providerName: string) => void; onAppointmentClick?: (appointment: AppointmentRecord) => void; } export function AppointmentScheduleGrid({ day, providers, appointments, canBook, onSlotClick, onAppointmentClick, }: AppointmentScheduleGridProps) { const gridHeight = HOURS.length * HOUR_PX; if (providers.length === 0) { return (