"use client" import { parseDate } from "@internationalized/date" import { useState } 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 { rangeArray } from "@/utils/rangeArray" 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 d = useWatch({ name }) const { control, setValue } = useFormContext() const { field } = useController({ control, name, rules: registerOptions, }) const [dateSegments, setDateSegment] = useState<{ year: number | null month: number | null date: number | null daysInMonth: number }>({ year: null, month: null, date: null, daysInMonth: 31, }) const currentYear = new Date().getFullYear() const months = rangeArray(1, 12).map((month) => ({ value: month, label: `${month}`, })) const years = rangeArray(1900, currentYear - 18) .reverse() .map((year) => ({ value: year, label: `${year}` })) function createOnSelect(selector: DateName) { /** * Months are 0 index based and therefore we * must subtract by 1 to get the selected month */ return (select: Key) => { const value = selector === DateName.month ? Number(select) - 1 : Number(select) const newSegments = { ...dateSegments, [selector]: value } /** * Update daysInMonth when year or month changes * to ensure the user can't select a date that doesn't exist. */ if (selector === DateName.year || selector === DateName.month) { const year = selector === DateName.year ? value : newSegments.year const month = selector === DateName.month ? value : newSegments.month if (year !== null && month !== null) { newSegments.daysInMonth = dt().year(year).month(month).daysInMonth() } } if (Object.values(newSegments).every((val) => val !== null)) { const newDate = dt() .utc() .set("year", newSegments.year!) .set("month", newSegments.month!) .set("date", Math.min(newSegments.date!, newSegments.daysInMonth)) setValue(name, newDate.format("YYYY-MM-DD")) } setDateSegment(newSegments) } } const dayLabel = intl.formatMessage({ id: "Day" }) const monthLabel = intl.formatMessage({ id: "Month" }) const yearLabel = intl.formatMessage({ id: "Year" }) 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(d).isValid() ? parseDate(d) : null } catch (error) { console.error(error) } return ( {(segment) => { switch (segment.type) { case "day": const maxDays = dateSegments.daysInMonth const days = rangeArray(1, maxDays).map((day) => ({ value: day, label: `${day}`, })) return (
) case "year": return (