From ff7c5713d97b3007899b0bb8580ced280d17628c Mon Sep 17 00:00:00 2001 From: Potenz Date: Thu, 16 Oct 2025 04:10:08 +0530 Subject: [PATCH] fix(date input updated) --- apps/Frontend/src/components/ui/dateInput.tsx | 99 ++++++++++++++++--- 1 file changed, 84 insertions(+), 15 deletions(-) diff --git a/apps/Frontend/src/components/ui/dateInput.tsx b/apps/Frontend/src/components/ui/dateInput.tsx index d5e2624..8ba6d17 100644 --- a/apps/Frontend/src/components/ui/dateInput.tsx +++ b/apps/Frontend/src/components/ui/dateInput.tsx @@ -19,8 +19,6 @@ interface DateInputProps { disablePast?: boolean; } -// THIS COMPONENT IS MADE FOR GENERAL FIELD IN PAGE. -// Here, User can input/paste date in certain format, and also select via calendar export function DateInput({ label, value, @@ -33,30 +31,101 @@ export function DateInput({ ); const [open, setOpen] = useState(false); - // Keep inputValue in sync when parent 'value' changes. - // Only overwrite if different to avoid stomping an in-progress user edit. useEffect(() => { if (value) { const formatted = format(value, "MM/dd/yyyy"); setInputValue((prev) => (prev !== formatted ? formatted : prev)); } else { - // parent cleared the value setInputValue(""); } }, [value]); const handleInputChange = (e: React.ChangeEvent) => { - let val = e.target.value.replace(/\D/g, ""); - if (val.length >= 5) { - val = `${val.slice(0, 2)}/${val.slice(2, 4)}/${val.slice(4, 8)}`; - } else if (val.length >= 3) { - val = `${val.slice(0, 2)}/${val.slice(2, 4)}`; - } - setInputValue(val); + const raw = e.target.value; - if (val.length === 10) { - const [mm, dd, yyyy] = val.split("/") ?? []; - if (mm && dd && yyyy) { + // If the user typed or pasted separators, treat as segmented input. + if (/\D/.test(raw)) { + // Split into digit-groups, ignoring empty groups. + const parts = raw.split(/\D+/).filter(Boolean); // e.g. ["02","12","2003"] or ["02","231996"] + + let mm = ""; + let dd = ""; + let yyyy = ""; + + // month is the first group (max 2 chars) + if (parts.length >= 1) { + mm = (parts[0] ?? "").slice(0, 2); + } + + if (parts.length >= 2) { + const p1 = parts[1] ?? ""; + + if (p1.length <= 2) { + // normal: p1 is day (1-2 digits) + dd = p1.slice(0, 2); + + // if there are more parts, they form the year + if (parts.length >= 3) { + yyyy = parts.slice(2).join("").slice(0, 4); + } + } else { + // overflow: p1 contains day + start-of-year (e.g. "231996") + dd = p1.slice(0, 2); + const rest = p1.slice(2) + parts.slice(2).join(""); + yyyy = rest.slice(0, 4); + } + } + + // Build display string WITHOUT forcing zero-padding or weird heuristics. + // This avoids turning user edits like "10" into "00". + let display = ""; + if (mm) display += mm; + if (dd || raw.includes("/")) { + // add slash if there's a day or user typed a slash + display += "/" + dd; + } + if (yyyy || (raw.match(/\//g) || []).length >= 2) { + // add slash for year if there's a year or user typed two slashes + display += "/" + yyyy; + } + + // Trim trailing slash if nothing after it (keeps behavior clean) + if (display.endsWith("/") && !display.endsWith("//")) { + // keep single trailing slash only if user typed it explicitly (raw ends with '/'), + // otherwise remove it to avoid showing an empty trailing slash. + if (!raw.endsWith("/")) { + display = display.replace(/\/$/, ""); + } + } + + setInputValue(display); + + // Only call onChange when we have mm + dd + 4-digit yyyy and the date is valid. + if (mm.length > 0 && dd.length > 0 && yyyy.length === 4) { + const parsed = new Date(+yyyy, +mm - 1, +dd); + if (!isNaN(parsed.getTime())) { + onChange(parsed); + } + } + + return; + } + + // No separators — free typing digits (incremental) + // Keep simple: mm (2) / dd (2) / yyyy (4) + let val = raw.replace(/\D/g, ""); + + if (val.length <= 2) { + setInputValue(val); + } else if (val.length <= 4) { + setInputValue(`${val.slice(0, 2)}/${val.slice(2)}`); + } else { + const mm = val.slice(0, 2); + const dd = val.slice(2, 4); + const yyyy = val.slice(4, 8); // 0..4 chars + setInputValue(`${mm}/${dd}${yyyy ? `/${yyyy}` : ""}`); + + if (yyyy.length === 4) { const parsed = new Date(+yyyy, +mm - 1, +dd); if (!isNaN(parsed.getTime())) { onChange(parsed);