'use client'; import { useLocale, useTranslations } from 'next-intl'; import { formatAppInteger, usesPersianCalendar } from '@/lib/i18n/format'; import { formatPersianMonthLabel, getLocalPersianParts, jalaliDaysInMonth, persianPartsToLocalDate, persianYearRange, } from '@/lib/i18n/persianCalendar'; import { startOfLocalDay } from '@/components/appointments/appointmentTime'; import { CompactSelect } from '@/components/ui/shared/CompactSelect'; const MONTH_KEYS = [ 'monthJanuary', 'monthFebruary', 'monthMarch', 'monthApril', 'monthMay', 'monthJune', 'monthJuly', 'monthAugust', 'monthSeptember', 'monthOctober', 'monthNovember', 'monthDecember', ] as const; const COMPACT_SELECT_CLASS = 'text-xs ps-2 pe-8 py-1'; function daysInMonth(year: number, month: number): number { return new Date(year, month + 1, 0).getDate(); } function buildLocalDay(year: number, month: number, day: number): Date { return new Date(year, month, day, 0, 0, 0, 0); } function yearRange(anchor: Date): number[] { const anchorYear = anchor.getFullYear(); const years: number[] = []; for (let y = anchorYear - 10; y <= anchorYear + 2; y += 1) { years.push(y); } return years; } export type CalendarDayPartsPanelProps = { panelId: string; value: Date; onChange: (day: Date) => void; closePanelOnDaySelect?: boolean; onAfterSelect?: (day: Date) => void; }; /** Year / month / day dropdown row — shared by schedule picker and date fields. */ export function CalendarDayPartsPanel({ panelId, value, onChange, closePanelOnDaySelect = false, onAfterSelect, }: CalendarDayPartsPanelProps) { const locale = useLocale(); const t = useTranslations('schedule'); const normalizedValue = startOfLocalDay(value); const persian = usesPersianCalendar(locale); const jalaliParts = persian ? getLocalPersianParts(normalizedValue) : null; const gregorianYear = normalizedValue.getFullYear(); const gregorianMonth = normalizedValue.getMonth(); const gregorianDay = normalizedValue.getDate(); const years = persian && jalaliParts ? persianYearRange(jalaliParts.year) : yearRange(normalizedValue); const selectedYear = jalaliParts?.year ?? gregorianYear; const selectedMonth = jalaliParts?.month ?? gregorianMonth; const selectedDay = jalaliParts?.day ?? gregorianDay; const dayCount = persian ? jalaliDaysInMonth(selectedYear, selectedMonth) : daysInMonth(selectedYear, selectedMonth); function applyParts(year: number, month: number, day: number, closePanel = false) { const maxDay = persian ? jalaliDaysInMonth(year, month) : daysInMonth(year, month); const clampedDay = Math.min(Math.max(1, day), maxDay); onChange( persian ? persianPartsToLocalDate(year, month, clampedDay) : buildLocalDay(year, month, clampedDay), ); if (closePanel) { const nextDay = persian ? persianPartsToLocalDate(year, month, clampedDay) : buildLocalDay(year, month, clampedDay); onAfterSelect?.(nextDay); } } function formatPanelYear(year: number): string { return persian ? formatAppInteger(year, locale) : String(year); } function formatPanelDay(day: number): string { return persian ? formatAppInteger(day, locale) : String(day); } return (