"use client" import { parseDate } from "@internationalized/date" import { useEffect } from "react" import { DateInput, DatePicker, Group } from "react-aria-components" import { useController, useFormContext, useWatch } from "react-hook-form" import { useIntl } from "react-intl" import { dt } from "@/lib/dt" import Select from "@/components/TempDesignSystem/Select" import useLang from "@/hooks/useLang" import { getLocalizedMonthName } from "@/utils/dateFormatting" import { rangeArray } from "@/utils/rangeArray" import ErrorMessage from "../ErrorMessage" import { DateName } from "./date" import styles from "./date.module.css" import type { Key } from "react-aria-components" import type { DateProps } from "./date" export default function DateSelect({ name, registerOptions = {} }: DateProps) { const intl = useIntl() const { control, setValue, formState, watch } = useFormContext() const { field, fieldState } = useController({ control, name, rules: registerOptions, }) const currentDateValue = useWatch({ name }) const year = watch(DateName.year) const month = watch(DateName.month) const day = watch(DateName.day) const lang = useLang() const months = rangeArray(1, 12).map((month) => ({ value: month, label: getLocalizedMonthName(month, lang), })) const currentYear = new Date().getFullYear() const years = rangeArray(1900, currentYear - 18) .reverse() .map((year) => ({ value: year, label: year.toString() })) // Calculate available days based on selected year and month const daysInMonth = getDaysInMonth( year ? Number(year) : null, month ? Number(month) - 1 : null ) const days = rangeArray(1, daysInMonth).map((day) => ({ value: day, label: `${day}`, })) const dayLabel = intl.formatMessage({ id: "Day" }) const monthLabel = intl.formatMessage({ id: "Month" }) const yearLabel = intl.formatMessage({ id: "Year" }) useEffect(() => { if (formState.isSubmitting) return if (month && day) { const maxDays = getDaysInMonth( year ? Number(year) : null, Number(month) - 1 ) const adjustedDay = Number(day) > maxDays ? maxDays : Number(day) if (adjustedDay !== Number(day)) { setValue(DateName.day, adjustedDay) } } if (year && month && day) { const newDate = dt() .year(Number(year)) .month(Number(month) - 1) .date(Number(day)) if (newDate.isValid()) { setValue(name, newDate.format("YYYY-MM-DD"), { shouldDirty: true, shouldTouch: true, shouldValidate: true, }) } } }, [year, month, day, setValue, name, formState.isSubmitting]) let dateValue = null try { /** * parseDate throws when its not a valid * date, but we can't check isNan since * we recieve the date as "1999-01-01" */ dateValue = dt(currentDateValue).isValid() ? parseDate(currentDateValue) : null } catch (error) { console.warn("Known error for parse date in DateSelect: ", error) } return ( {(segment) => { switch (segment.type) { case "day": return (
setValue(DateName.month, Number(key)) } placeholder={monthLabel} required tabIndex={2} value={segment.isPlaceholder ? undefined : segment.value} />
) case "year": return (