|
|
|
@ -1,9 +1,10 @@ |
|
|
|
"use client"; |
|
|
|
|
|
|
|
import { useMemo } from "react"; |
|
|
|
import { useEffect, useMemo, useState } from "react"; |
|
|
|
import type { QuestionField } from "@/data/question-data"; |
|
|
|
import { useQuestionAnswers } from "./question-answer-storage"; |
|
|
|
import QuestionTitle from "./question-title"; |
|
|
|
import { useI18n } from "@/translations/provider"; |
|
|
|
|
|
|
|
type QuestionDateProps = { |
|
|
|
question: QuestionField; |
|
|
|
@ -32,28 +33,48 @@ const DAYS = Array.from({ length: 31 }, (_, i) => { |
|
|
|
return { value: val, label: `${num}` }; |
|
|
|
}); |
|
|
|
|
|
|
|
const MIN_AGE = 18; |
|
|
|
const currentYear = new Date().getFullYear(); |
|
|
|
const YEARS = Array.from({ length: 90 }, (_, i) => (currentYear - i).toString()); |
|
|
|
const maxBirthYear = currentYear - MIN_AGE; |
|
|
|
const YEARS = Array.from({ length: 80 }, (_, i) => (maxBirthYear - i).toString()); |
|
|
|
|
|
|
|
export function QuestionDate({ |
|
|
|
question, |
|
|
|
questionIndex, |
|
|
|
disabled, |
|
|
|
}: QuestionDateProps) { |
|
|
|
const { locale } = useI18n(); |
|
|
|
const { getAnswerValue, setAnswerValue } = useQuestionAnswers(); |
|
|
|
const value = getAnswerValue(question, questionIndex); |
|
|
|
const dateValue = typeof value === "string" ? value : ""; |
|
|
|
|
|
|
|
const parts = dateValue ? dateValue.split("-") : []; |
|
|
|
const year = parts[0] || ""; |
|
|
|
const month = parts[1] || ""; |
|
|
|
const day = parts[2] || ""; |
|
|
|
const [selectedYear, setSelectedYear] = useState(() => { |
|
|
|
const parts = dateValue ? dateValue.split("-") : []; |
|
|
|
return parts[0] || ""; |
|
|
|
}); |
|
|
|
const [selectedMonth, setSelectedMonth] = useState(() => { |
|
|
|
const parts = dateValue ? dateValue.split("-") : []; |
|
|
|
return parts[1] || ""; |
|
|
|
}); |
|
|
|
const [selectedDay, setSelectedDay] = useState(() => { |
|
|
|
const parts = dateValue ? dateValue.split("-") : []; |
|
|
|
return parts[2] || ""; |
|
|
|
}); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
const parts = dateValue ? dateValue.split("-") : []; |
|
|
|
if (parts.length === 3) { |
|
|
|
setSelectedYear(parts[0] || ""); |
|
|
|
setSelectedMonth(parts[1] || ""); |
|
|
|
setSelectedDay(parts[2] || ""); |
|
|
|
} |
|
|
|
}, [dateValue]); |
|
|
|
|
|
|
|
const calculatedAge = useMemo(() => { |
|
|
|
if (!year || !month || !day) return null; |
|
|
|
const y = Number.parseInt(year, 10); |
|
|
|
const m = Number.parseInt(month, 10); |
|
|
|
const d = Number.parseInt(day, 10); |
|
|
|
if (!selectedYear || !selectedMonth || !selectedDay) return null; |
|
|
|
const y = Number.parseInt(selectedYear, 10); |
|
|
|
const m = Number.parseInt(selectedMonth, 10); |
|
|
|
const d = Number.parseInt(selectedDay, 10); |
|
|
|
|
|
|
|
if (!y || !m || !d || Number.isNaN(y) || Number.isNaN(m) || Number.isNaN(d)) { |
|
|
|
return null; |
|
|
|
@ -70,19 +91,34 @@ export function QuestionDate({ |
|
|
|
} |
|
|
|
|
|
|
|
return age >= 0 ? age : null; |
|
|
|
}, [year, month, day]); |
|
|
|
}, [selectedYear, selectedMonth, selectedDay]); |
|
|
|
|
|
|
|
const isUnder18 = calculatedAge !== null && calculatedAge < MIN_AGE; |
|
|
|
|
|
|
|
const handleSelectChange = (newYear: string, newMonth: string, newDay: string) => { |
|
|
|
if (!newYear && !newMonth && !newDay) { |
|
|
|
const updateDate = (y: string, m: string, d: string) => { |
|
|
|
setSelectedYear(y); |
|
|
|
setSelectedMonth(m); |
|
|
|
setSelectedDay(d); |
|
|
|
|
|
|
|
if (y && m && d) { |
|
|
|
const formattedMonth = m.padStart(2, "0"); |
|
|
|
const formattedDay = d.padStart(2, "0"); |
|
|
|
setAnswerValue(question, questionIndex, `${y}-${formattedMonth}-${formattedDay}`); |
|
|
|
} else { |
|
|
|
setAnswerValue(question, questionIndex, ""); |
|
|
|
return; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const y = newYear || year || "2000"; |
|
|
|
const m = (newMonth || month || "01").padStart(2, "0"); |
|
|
|
const d = (newDay || day || "01").padStart(2, "0"); |
|
|
|
const handleDayChange = (newDay: string) => { |
|
|
|
updateDate(selectedYear, selectedMonth, newDay); |
|
|
|
}; |
|
|
|
|
|
|
|
const handleMonthChange = (newMonth: string) => { |
|
|
|
updateDate(selectedYear, newMonth, selectedDay); |
|
|
|
}; |
|
|
|
|
|
|
|
setAnswerValue(question, questionIndex, `${y}-${m}-${d}`); |
|
|
|
const handleYearChange = (newYear: string) => { |
|
|
|
updateDate(newYear, selectedMonth, selectedDay); |
|
|
|
}; |
|
|
|
|
|
|
|
return ( |
|
|
|
@ -98,8 +134,8 @@ export function QuestionDate({ |
|
|
|
<div className="grid grid-cols-3 gap-2"> |
|
|
|
{/* Day / روز */} |
|
|
|
<select |
|
|
|
value={day} |
|
|
|
onChange={(e) => handleSelectChange(year, month, e.target.value)} |
|
|
|
value={selectedDay} |
|
|
|
onChange={(e) => handleDayChange(e.target.value)} |
|
|
|
disabled={disabled} |
|
|
|
aria-label="Day" |
|
|
|
className="h-[54px] w-full cursor-pointer rounded-[15px] border border-[#E7D8D5] bg-white px-3 group-12 text-[#181818] outline-none transition-all focus:border-[#6F6F6F]" |
|
|
|
@ -114,8 +150,8 @@ export function QuestionDate({ |
|
|
|
|
|
|
|
{/* Month */} |
|
|
|
<select |
|
|
|
value={month} |
|
|
|
onChange={(e) => handleSelectChange(year, e.target.value, day)} |
|
|
|
value={selectedMonth} |
|
|
|
onChange={(e) => handleMonthChange(e.target.value)} |
|
|
|
disabled={disabled} |
|
|
|
aria-label="Month" |
|
|
|
className="h-[54px] w-full cursor-pointer rounded-[15px] border border-[#E7D8D5] bg-white px-3 group-12 text-[#181818] outline-none transition-all focus:border-[#6F6F6F]" |
|
|
|
@ -130,8 +166,8 @@ export function QuestionDate({ |
|
|
|
|
|
|
|
{/* Year */} |
|
|
|
<select |
|
|
|
value={year} |
|
|
|
onChange={(e) => handleSelectChange(e.target.value, month, day)} |
|
|
|
value={selectedYear} |
|
|
|
onChange={(e) => handleYearChange(e.target.value)} |
|
|
|
disabled={disabled} |
|
|
|
aria-label="Year" |
|
|
|
className="h-[54px] w-full cursor-pointer rounded-[15px] border border-[#E7D8D5] bg-white px-3 group-12 text-[#181818] outline-none transition-all focus:border-[#6F6F6F]" |
|
|
|
@ -155,8 +191,18 @@ export function QuestionDate({ |
|
|
|
disabled |
|
|
|
readOnly |
|
|
|
value={calculatedAge !== null ? calculatedAge : ""} |
|
|
|
className="h-[54px] w-full rounded-[15px] border border-[#E7D8D5] bg-[#F5F2F1] px-4 group-12 font-medium text-[#7C7472] outline-none cursor-not-allowed disabled:bg-[#F5F2F1] disabled:text-[#7C7472]" |
|
|
|
className={[ |
|
|
|
"h-[54px] w-full rounded-[15px] border px-4 group-12 font-medium outline-none cursor-not-allowed disabled:bg-[#F5F2F1] disabled:text-[#7C7472]", |
|
|
|
isUnder18 ? "border-[#F2465F] text-[#F2465F]" : "border-[#E7D8D5] text-[#7C7472]", |
|
|
|
].join(" ")} |
|
|
|
/> |
|
|
|
{isUnder18 ? ( |
|
|
|
<span className="block text-[11px] font-semibold text-[#F2465F]"> |
|
|
|
{locale === "fa" |
|
|
|
? "حداقل سن برای ثبتنام ۱۸ سال میباشد." |
|
|
|
: "Minimum age required for registration is 18 years."} |
|
|
|
</span> |
|
|
|
) : null} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
); |
|
|
|
|