'use client' import type { ReactNode } from 'react' import type { Control } from 'react-hook-form' import { useState } from 'react' import { jalaaliMonthLength } from 'jalaali-js' import Picker from 'react-mobile-picker' import { Controller } from 'react-hook-form' import Button from '@/components/formElements/Button' import CalendarIcon from '@/components/icons/CalendarIcon' import ConsumerModal from '@/components/consumer/ConsumerModal' import { buildOutsideLabel } from '@/components/formElements/input/inputUtils' import { PERSIAN_MONTHS, birthDateYears, clampJalaliDateParts, defaultBirthDateParts, isoDateToJalaliParts, jalaliPartsToIsoDate, type JalaliDateParts, } from '@/lib/birthDate' import { cn } from '@/lib/cn' import { texts } from '@/texts' type Variant = 'flat' | 'bordered' | 'faded' | 'underlined' interface Props { className?: string control: Control description?: ReactNode disabled?: boolean label?: string name: string placeholder?: string readonly?: boolean required?: boolean size?: 'sm' | 'md' | 'lg' variant: Variant } const MONTHS = Array.from({ length: 12 }, (_, index) => String(index + 1)) const YEARS = birthDateYears() const toPersianNumber = (value: number | string) => Number(value).toLocaleString('fa-IR', { useGrouping: false }) function WheelItem({ value, label }: { value: string; label: string }) { return ( {({ selected }) => ( {label} )} ) } function WheelFrame({ children }: { children: ReactNode }) { return (
{children}
) } function BirthDateWheel({ value, onChange }: { value: JalaliDateParts; onChange: (value: JalaliDateParts) => void }) { const days = Array.from({ length: jalaaliMonthLength(Number(value.year), Number(value.month)) }, (_, index) => String(index + 1)) return (
{texts.common.day} {texts.common.month} {texts.common.year}
{ onChange(clampJalaliDateParts(nextValue)) }} > {days.map((day) => ( ))} {MONTHS.map((month) => ( ))} {YEARS.map((year) => ( ))}
) } function triggerClasses(size: Props['size'], variant: Variant, invalid: boolean) { return cn( 'flex w-full items-center justify-between gap-3 px-3 text-right text-sm font-normal outline-none transition', size === 'sm' ? 'h-9' : size === 'lg' ? 'h-12' : 'h-10', variant === 'underlined' ? 'rounded-none border-b bg-transparent' : 'rounded-xl', variant === 'bordered' && 'border bg-transparent', variant === 'faded' && 'border bg-default-100', variant === 'flat' && 'bg-default-100', invalid ? 'border-fourth-900 text-fourth-900' : 'border-default-200 text-text-main', 'disabled:cursor-not-allowed disabled:opacity-50' ) } function formatSelectedLabel(value: JalaliDateParts) { return `${toPersianNumber(value.day)} ${PERSIAN_MONTHS[Number(value.month) - 1]} ${toPersianNumber(value.year)}` } export default function JalaliBirthDateFieldControl(props: Props) { const [isOpen, setIsOpen] = useState(false) const [draft, setDraft] = useState(defaultBirthDateParts()) return ( { const selected = isoDateToJalaliParts(field.value) const displayValue = selected ? formatSelectedLabel(selected) : '' const openPicker = () => { if (props.disabled || props.readonly) return setDraft(selected ?? defaultBirthDateParts()) setIsOpen(true) } const accept = () => { field.onChange(jalaliPartsToIsoDate(draft)) field.onBlur() setIsOpen(false) } return (
{buildOutsideLabel(props.label, , props.required, 0)}
{error ?

{error.message}

: null} {props.description ?

{props.description}

: null} { setIsOpen(false) }} >
) }} /> ) }