AW-491-comp-fields
autocomplete datePicker
This commit is contained in:
parent
89675109f7
commit
ce6ef48549
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useLocale, useTranslations } from "next-intl";
|
import { useLocale, useTranslations } from "next-intl";
|
||||||
|
|
||||||
import { Typography } from "@/components/ui";
|
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.
|
// В реальном приложении здесь лучше использовать данные из next-intl.
|
||||||
const getDateInputLocaleFormat = (locale: string): ("d" | "m" | "y")[] => {
|
const getDateInputLocaleFormat = (locale: string): ("d" | "m" | "y")[] => {
|
||||||
@ -54,11 +68,12 @@ export default function DatePicker({
|
|||||||
const [day, setDay] = useState("");
|
const [day, setDay] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (value && /^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
const parsedDate = parseDateValue(value);
|
||||||
const [y, m, d] = value.split("-");
|
|
||||||
setYear(y);
|
if (parsedDate) {
|
||||||
setMonth(m);
|
setYear(parsedDate.year);
|
||||||
setDay(d);
|
setMonth(parsedDate.month);
|
||||||
|
setDay(parsedDate.day);
|
||||||
} else {
|
} else {
|
||||||
setYear("");
|
setYear("");
|
||||||
setMonth("");
|
setMonth("");
|
||||||
@ -66,6 +81,15 @@ export default function DatePicker({
|
|||||||
}
|
}
|
||||||
}, [value]);
|
}, [value]);
|
||||||
|
|
||||||
|
const updateValue = useCallback(
|
||||||
|
(newValue: string | null) => {
|
||||||
|
if (newValue !== value) {
|
||||||
|
onChange(newValue);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[onChange, value]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const numericYear = Number(year);
|
const numericYear = Number(year);
|
||||||
const numericMonth = Number(month);
|
const numericMonth = Number(month);
|
||||||
@ -73,15 +97,13 @@ export default function DatePicker({
|
|||||||
|
|
||||||
if (isValidDate(numericYear, numericMonth, numericDay)) {
|
if (isValidDate(numericYear, numericMonth, numericDay)) {
|
||||||
const formattedDate = `${year}-${month}-${day}`;
|
const formattedDate = `${year}-${month}-${day}`;
|
||||||
if (formattedDate !== value) {
|
updateValue(formattedDate);
|
||||||
onChange(formattedDate);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (value !== null) {
|
if (year || month || day) {
|
||||||
onChange(null);
|
updateValue(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [year, month, day, onChange, value]);
|
}, [year, month, day, updateValue]);
|
||||||
|
|
||||||
const yearOptions = useMemo(
|
const yearOptions = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -115,12 +137,33 @@ export default function DatePicker({
|
|||||||
[locale]
|
[locale]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleYearChange = useCallback(
|
||||||
|
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
setYear(e.target.value);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleMonthChange = useCallback(
|
||||||
|
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
setMonth(e.target.value);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDayChange = useCallback(
|
||||||
|
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
setDay(e.target.value);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const inputs = {
|
const inputs = {
|
||||||
d: (
|
d: (
|
||||||
<SelectInput
|
<SelectInput
|
||||||
key="d"
|
key="d"
|
||||||
value={day}
|
value={day}
|
||||||
onChange={e => setDay(e.target.value)}
|
onChange={handleDayChange}
|
||||||
options={dayOptions}
|
options={dayOptions}
|
||||||
placeholder={t("day")}
|
placeholder={t("day")}
|
||||||
/>
|
/>
|
||||||
@ -129,7 +172,7 @@ export default function DatePicker({
|
|||||||
<SelectInput
|
<SelectInput
|
||||||
key="m"
|
key="m"
|
||||||
value={month}
|
value={month}
|
||||||
onChange={e => setMonth(e.target.value)}
|
onChange={handleMonthChange}
|
||||||
options={monthOptions}
|
options={monthOptions}
|
||||||
placeholder={t("month")}
|
placeholder={t("month")}
|
||||||
/>
|
/>
|
||||||
@ -138,7 +181,7 @@ export default function DatePicker({
|
|||||||
<SelectInput
|
<SelectInput
|
||||||
key="y"
|
key="y"
|
||||||
value={year}
|
value={year}
|
||||||
onChange={e => setYear(e.target.value)}
|
onChange={handleYearChange}
|
||||||
options={yearOptions}
|
options={yearOptions}
|
||||||
placeholder={t("year")}
|
placeholder={t("year")}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user