81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { useTranslations } from "@/hooks/translations";
|
|
import { FormField } from "@/types";
|
|
import DateInput from "./DateInput";
|
|
import ErrorText from "../ErrorText";
|
|
import { stringify, getCurrentYear } from "./utils";
|
|
import { IDate, getDateAsString } from "@/services/date";
|
|
import { ELocalesPlacement } from "@/locales";
|
|
|
|
export function DatePicker(
|
|
props: FormField<Date | IDate | string>
|
|
): JSX.Element {
|
|
const { translate } = useTranslations(ELocalesPlacement.V1);
|
|
const { name, value, inputClassName, onValid, onInvalid } = props;
|
|
const date = getDateAsString(value);
|
|
const [initYear, initMonth, initDay] = date.split("-");
|
|
const [year, setYear] = useState(initYear);
|
|
const [month, setMonth] = useState(initMonth);
|
|
const [day, setDay] = useState(initDay);
|
|
const [hasError, setHasError] = useState(false);
|
|
const isValid = (value: string) => {
|
|
const date = new Date(value);
|
|
const isCorrectDate = stringify(date) === value;
|
|
const isNotFutureDate = date.getTime() <= Date.now();
|
|
const isNotMinDate = date.getFullYear() >= getCurrentYear() - 200;
|
|
return isCorrectDate && isNotFutureDate && isNotMinDate;
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (year && month && day) {
|
|
const currentValue = `${year}-${month}-${day}`;
|
|
setHasError(!isValid(currentValue));
|
|
isValid(currentValue) ? onValid(currentValue) : onInvalid();
|
|
} else {
|
|
setHasError(false);
|
|
onValid("");
|
|
}
|
|
}, [year, month, day, hasError, onValid, onInvalid]);
|
|
|
|
return (
|
|
<form name={name} className="date-picker">
|
|
<div className="date-picker__container">
|
|
<DateInput
|
|
name="year"
|
|
value={year ? String(parseInt(year, 10)) : ""}
|
|
max={getCurrentYear()}
|
|
maxLength={4}
|
|
label={translate("year")}
|
|
placeholder="YYYY"
|
|
inputClassName={inputClassName}
|
|
onChange={(year: string) => setYear(year)}
|
|
/>
|
|
<DateInput
|
|
name="month"
|
|
value={month}
|
|
max={12}
|
|
maxLength={2}
|
|
label={translate("month")}
|
|
placeholder="MM"
|
|
inputClassName={inputClassName}
|
|
onChange={(month: string) => setMonth(month)}
|
|
/>
|
|
<DateInput
|
|
name="day"
|
|
value={day}
|
|
max={31}
|
|
maxLength={2}
|
|
label={translate("day")}
|
|
placeholder="DD"
|
|
inputClassName={inputClassName}
|
|
onChange={(day: string) => setDay(day)}
|
|
/>
|
|
</div>
|
|
<ErrorText
|
|
isShown={hasError}
|
|
message={translate("invalid_date", undefined, ELocalesPlacement.V0)}
|
|
/>
|
|
</form>
|
|
);
|
|
}
|