'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 (
)
}
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)
}}
>
)
}}
/>
)
}