move date functions into utils/date; tabbed DriverForm
This commit is contained in:
@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from "react"
|
||||
import { InputBase, ActionIcon, Popover } from "@mantine/core"
|
||||
import { IconCalendar } from "@tabler/icons-react"
|
||||
import { DatePicker } from "@mantine/dates"
|
||||
import dayjs from "dayjs"
|
||||
import { formatDDMMYYYY, parseDDMMYYYY } from "../utils/date"
|
||||
|
||||
interface MaskedDateInputProps {
|
||||
value?: Date | null
|
||||
@ -14,29 +14,6 @@ interface MaskedDateInputProps {
|
||||
maxDate?: Date | undefined
|
||||
}
|
||||
|
||||
function parseDDMMYYYY(input: string): Date | null {
|
||||
const [dd, mm, yyyy] = input.split(".")
|
||||
const day = parseInt(dd, 10)
|
||||
const month = parseInt(mm, 10)
|
||||
const year = parseInt(yyyy, 10)
|
||||
|
||||
if (
|
||||
isNaN(day) || isNaN(month) || isNaN(year) ||
|
||||
day < 1 || day > 31 ||
|
||||
month < 1 || month > 12 ||
|
||||
year < 1900
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const date = dayjs(`${year}-${month}-${day}`, "YYYY-M-D", true)
|
||||
return date.isValid() ? date.toDate() : null
|
||||
}
|
||||
|
||||
function formatDDMMYYYY(date: Date): string {
|
||||
return dayjs(date).format("DD.MM.YYYY")
|
||||
}
|
||||
|
||||
export default function MaskedDateInput({
|
||||
value,
|
||||
onChange,
|
||||
@ -60,49 +37,49 @@ export default function MaskedDateInput({
|
||||
}, [value])
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const raw = e.target.value;
|
||||
const digits = raw.replace(/\D/g, '').slice(0, 8);
|
||||
const raw = e.target.value
|
||||
const digits = raw.replace(/\D/g, '').slice(0, 8)
|
||||
|
||||
let day = digits.slice(0, 2);
|
||||
let month = digits.slice(2, 4);
|
||||
let year = digits.slice(4, 8);
|
||||
let day = digits.slice(0, 2)
|
||||
let month = digits.slice(2, 4)
|
||||
let year = digits.slice(4, 8)
|
||||
|
||||
// Validate day and month only if they are fully entered (2 digits)
|
||||
if (day.length === 2) {
|
||||
const dayNum = parseInt(day, 10);
|
||||
if (dayNum < 1 || dayNum > 31) return; // Invalid day → block update
|
||||
const dayNum = parseInt(day, 10)
|
||||
if (dayNum < 1 || dayNum > 31) return
|
||||
}
|
||||
|
||||
if (month.length === 2) {
|
||||
const monthNum = parseInt(month, 10);
|
||||
if (monthNum < 1 || monthNum > 12) return; // Invalid month → block update
|
||||
const monthNum = parseInt(month, 10)
|
||||
if (monthNum < 1 || monthNum > 12) return
|
||||
}
|
||||
|
||||
if (year.length === 4) {
|
||||
const yearNum = parseInt(year, 10);
|
||||
if (yearNum < 1900) return; // Invalid year → block update
|
||||
if (yearNum < 1900) return
|
||||
}
|
||||
|
||||
// Format the input as DD.MM.YYYY
|
||||
let formatted = day;
|
||||
if (month.length) formatted += '.' + month;
|
||||
if (year.length) formatted += '.' + year;
|
||||
let formatted = day
|
||||
if (month.length) formatted += '.' + month
|
||||
if (year.length) formatted += '.' + year
|
||||
|
||||
// Smart dot-padding (like "1." → "01.")
|
||||
if (/^\d\.$/.test(raw)) {
|
||||
formatted = '0' + raw;
|
||||
formatted = '0' + raw
|
||||
}
|
||||
|
||||
if (/^\d{2}\.\d\.$/.test(raw)) {
|
||||
formatted = raw.replace(/^(\d{2})\.(\d)\.$/, (_, d, m) => `${d}.0${m}.`);
|
||||
formatted = raw.replace(/^(\d{2})\.(\d)\.$/, (_, d, m) => `${d}.0${m}.`)
|
||||
}
|
||||
|
||||
setInputValue(formatted);
|
||||
setInputValue(formatted)
|
||||
|
||||
// Final parsing only if full date is entered
|
||||
if (day.length === 2 && month.length === 2 && year.length === 4) {
|
||||
const parsed = parseDDMMYYYY(formatted);
|
||||
if (parsed) onChange?.(parsed);
|
||||
const parsed = parseDDMMYYYY(formatted)
|
||||
if (parsed) onChange?.(parsed)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user