From ce6ef485495f8a44981829fdac75c47fe3fb0262 Mon Sep 17 00:00:00 2001 From: gofnnp Date: Tue, 1 Jul 2025 20:47:14 +0400 Subject: [PATCH] AW-491-comp-fields autocomplete datePicker --- .../widgets/DatePicker/DatePicker.tsx | 73 +++++++++++++++---- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/src/components/widgets/DatePicker/DatePicker.tsx b/src/components/widgets/DatePicker/DatePicker.tsx index 6219e15..e2add09 100644 --- a/src/components/widgets/DatePicker/DatePicker.tsx +++ b/src/components/widgets/DatePicker/DatePicker.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { useLocale, useTranslations } from "next-intl"; import { Typography } from "@/components/ui"; @@ -18,6 +18,20 @@ const isValidDate = (year: number, month: number, day: number) => { ); }; +const parseDateValue = ( + value: string | null +): { year: string; month: string; day: string } | null => { + if (!value) return null; + + // Поддерживаем форматы: "2003-04-09" и "2003-04-09 12:00" + const dateMatch = value.match(/^(\d{4})-(\d{2})-(\d{2})(?:\s+\d{2}:\d{2})?$/); + + if (!dateMatch) return null; + + const [, year, month, day] = dateMatch; + return { year, month, day }; +}; + // Упрощенное определение порядка полей даты на основе локали. // В реальном приложении здесь лучше использовать данные из next-intl. const getDateInputLocaleFormat = (locale: string): ("d" | "m" | "y")[] => { @@ -54,11 +68,12 @@ export default function DatePicker({ const [day, setDay] = useState(""); useEffect(() => { - if (value && /^\d{4}-\d{2}-\d{2}$/.test(value)) { - const [y, m, d] = value.split("-"); - setYear(y); - setMonth(m); - setDay(d); + const parsedDate = parseDateValue(value); + + if (parsedDate) { + setYear(parsedDate.year); + setMonth(parsedDate.month); + setDay(parsedDate.day); } else { setYear(""); setMonth(""); @@ -66,6 +81,15 @@ export default function DatePicker({ } }, [value]); + const updateValue = useCallback( + (newValue: string | null) => { + if (newValue !== value) { + onChange(newValue); + } + }, + [onChange, value] + ); + useEffect(() => { const numericYear = Number(year); const numericMonth = Number(month); @@ -73,15 +97,13 @@ export default function DatePicker({ if (isValidDate(numericYear, numericMonth, numericDay)) { const formattedDate = `${year}-${month}-${day}`; - if (formattedDate !== value) { - onChange(formattedDate); - } + updateValue(formattedDate); } else { - if (value !== null) { - onChange(null); + if (year || month || day) { + updateValue(null); } } - }, [year, month, day, onChange, value]); + }, [year, month, day, updateValue]); const yearOptions = useMemo( () => @@ -115,12 +137,33 @@ export default function DatePicker({ [locale] ); + const handleYearChange = useCallback( + (e: React.ChangeEvent) => { + setYear(e.target.value); + }, + [] + ); + + const handleMonthChange = useCallback( + (e: React.ChangeEvent) => { + setMonth(e.target.value); + }, + [] + ); + + const handleDayChange = useCallback( + (e: React.ChangeEvent) => { + setDay(e.target.value); + }, + [] + ); + const inputs = { d: ( setDay(e.target.value)} + onChange={handleDayChange} options={dayOptions} placeholder={t("day")} /> @@ -129,7 +172,7 @@ export default function DatePicker({ setMonth(e.target.value)} + onChange={handleMonthChange} options={monthOptions} placeholder={t("month")} /> @@ -138,7 +181,7 @@ export default function DatePicker({ setYear(e.target.value)} + onChange={handleYearChange} options={yearOptions} placeholder={t("year")} />