From 603eceb4067a4e4e60c875d8a52b147603740b67 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Mon, 25 Nov 2024 17:09:30 +0530 Subject: [PATCH 1/6] Disallowing out of date range --- src/components/Common/DateInputV2.tsx | 268 +++++++++++++++++++------- 1 file changed, 199 insertions(+), 69 deletions(-) diff --git a/src/components/Common/DateInputV2.tsx b/src/components/Common/DateInputV2.tsx index 20027a004d2..f5a6a6b7f31 100644 --- a/src/components/Common/DateInputV2.tsx +++ b/src/components/Common/DateInputV2.tsx @@ -89,15 +89,16 @@ const DateInputV2: React.FC = ({ ); break; case "month": - setDatePickerHeaderDate((prev) => - dayjs(prev).subtract(1, "year").toDate(), - ); + if (!min || datePickerHeaderDate.getFullYear() > min.getFullYear()) { + setDatePickerHeaderDate((prev) => + dayjs(prev).subtract(1, "year").toDate(), + ); + } break; case "year": - setDatePickerHeaderDate((prev) => - dayjs(prev).subtract(1, "year").toDate(), - ); - setYear((prev) => dayjs(prev).subtract(10, "year").toDate()); + if (!min || year.getFullYear() - 10 >= min.getFullYear()) { + setYear((prev) => dayjs(prev).subtract(10, "year").toDate()); + } break; } }; @@ -108,11 +109,18 @@ const DateInputV2: React.FC = ({ setDatePickerHeaderDate((prev) => dayjs(prev).add(1, "month").toDate()); break; case "month": - setDatePickerHeaderDate((prev) => dayjs(prev).add(1, "year").toDate()); + if ( + datePickerHeaderDate.getFullYear() < (max?.getFullYear() ?? -Infinity) + ) { + setDatePickerHeaderDate((prev) => + dayjs(prev).add(1, "year").toDate(), + ); + } break; case "year": - setDatePickerHeaderDate((prev) => dayjs(prev).add(1, "year").toDate()); - setYear((prev) => dayjs(prev).add(10, "year").toDate()); + if (!max || year.getFullYear() + 10 >= max.getFullYear()) { + setYear((prev) => dayjs(prev).add(10, "year").toDate()); + } break; } }; @@ -209,6 +217,34 @@ const DateInputV2: React.FC = ({ return true; }; + const isMonthWithinConstraints = (month: number) => { + const year = datePickerHeaderDate.getFullYear(); + + if (min && year < min.getFullYear()) return false; + if (max && year > max.getFullYear()) return false; + + const date = new Date(year, month, 1); + if (min && date < new Date(min.getFullYear(), min.getMonth(), 1)) + return false; + if (max && date > new Date(max.getFullYear(), max.getMonth(), 1)) + return false; + + return true; + }; + + const isYearWithinConstraints = (year: number) => { + if (min && year < min.getFullYear()) return false; + if (max && year > max.getFullYear()) return false; + + const yearStart = new Date(year, 0, 1); + const yearEnd = new Date(year, 11, 31); + + if (min && yearEnd < min) return false; + if (max && yearStart > max) return false; + + return true; + }; + const isSelectedMonth = (month: number) => month === datePickerHeaderDate.getMonth(); @@ -216,25 +252,37 @@ const DateInputV2: React.FC = ({ year === datePickerHeaderDate.getFullYear(); const setMonthValue = (month: number) => () => { - setDatePickerHeaderDate( - new Date( - datePickerHeaderDate.getFullYear(), - month, - datePickerHeaderDate.getDate(), - ), - ); - setType("date"); + if (isMonthWithinConstraints(month)) { + setDatePickerHeaderDate( + new Date( + datePickerHeaderDate.getFullYear(), + month, + datePickerHeaderDate.getDate(), + ), + ); + setType("date"); + } else { + Notification.Error({ + msg: outOfLimitsErrorMessage ?? "Cannot select month out of range", + }); + } }; const setYearValue = (year: number) => () => { - setDatePickerHeaderDate( - new Date( - year, - datePickerHeaderDate.getMonth(), - datePickerHeaderDate.getDate(), - ), - ); - setType("date"); + if (isYearWithinConstraints(year)) { + setDatePickerHeaderDate( + new Date( + year, + datePickerHeaderDate.getMonth(), + datePickerHeaderDate.getDate(), + ), + ); + setType("date"); + } else { + Notification.Error({ + msg: outOfLimitsErrorMessage ?? "Cannot select year out of range", + }); + } }; useEffect(() => { @@ -371,23 +419,62 @@ const DateInputV2: React.FC = ({
- + {type === "date" && ( + + )} + {type === "month" && ( + + )} + + {type === "year" && ( + + )}
{type === "date" && ( @@ -411,23 +498,62 @@ const DateInputV2: React.FC = ({

- + {type === "date" && ( + + )} + {type === "month" && ( + + )} + + {type === "year" && ( + + )}
{type === "date" && ( @@ -510,10 +636,12 @@ const DateInputV2: React.FC = ({ key={i} id={`month-${i}`} className={classNames( - "w-1/4 cursor-pointer rounded-lg px-2 py-4 text-center text-sm font-semibold", - value && isSelectedMonth(i) - ? "bg-primary-500 text-white" - : "text-secondary-700 hover:bg-secondary-300", + "w-1/4 rounded-lg px-2 py-4 text-center text-sm font-semibold", + isSelectedMonth(i) + ? "bg-primary-500 text-white cursor-pointer" + : isMonthWithinConstraints(i) + ? "text-secondary-700 hover:bg-secondary-300 cursor-pointer" + : "!text-secondary-400 !cursor-not-allowed", )} onClick={setMonthValue(i)} > @@ -533,16 +661,18 @@ const DateInputV2: React.FC = ({ {Array(12) .fill(null) .map((_, i) => { - const y = year.getFullYear() - 11 + i; + const y = year.getFullYear() - 10 + i; return (
From 8ade83897a5031c22baccd5f2365309a1e5cfbee Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Mon, 25 Nov 2024 17:24:31 +0530 Subject: [PATCH 2/6] Refactor the code --- src/components/Common/DateInputV2.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Common/DateInputV2.tsx b/src/components/Common/DateInputV2.tsx index f5a6a6b7f31..39c152bc6ef 100644 --- a/src/components/Common/DateInputV2.tsx +++ b/src/components/Common/DateInputV2.tsx @@ -109,9 +109,7 @@ const DateInputV2: React.FC = ({ setDatePickerHeaderDate((prev) => dayjs(prev).add(1, "month").toDate()); break; case "month": - if ( - datePickerHeaderDate.getFullYear() < (max?.getFullYear() ?? -Infinity) - ) { + if (!max || datePickerHeaderDate.getFullYear() < max.getFullYear()) { setDatePickerHeaderDate((prev) => dayjs(prev).add(1, "year").toDate(), ); From c7b7f85f03a0c6d3c14820155702e0fd3eb492a5 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Thu, 28 Nov 2024 22:31:59 +0530 Subject: [PATCH 3/6] Added changes to the date disallowing --- src/components/Common/DateInputV2.tsx | 30 ++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/components/Common/DateInputV2.tsx b/src/components/Common/DateInputV2.tsx index 39c152bc6ef..86e5be8cbac 100644 --- a/src/components/Common/DateInputV2.tsx +++ b/src/components/Common/DateInputV2.tsx @@ -89,7 +89,12 @@ const DateInputV2: React.FC = ({ ); break; case "month": - if (!min || datePickerHeaderDate.getFullYear() > min.getFullYear()) { + if ( + !min || + datePickerHeaderDate.getFullYear() > min.getFullYear() || + (datePickerHeaderDate.getFullYear() === min.getFullYear() && + datePickerHeaderDate.getMonth() > min.getMonth()) + ) { setDatePickerHeaderDate((prev) => dayjs(prev).subtract(1, "year").toDate(), ); @@ -116,7 +121,7 @@ const DateInputV2: React.FC = ({ } break; case "year": - if (!max || year.getFullYear() + 10 >= max.getFullYear()) { + if (!max || year.getFullYear() + 10 <= max.getFullYear()) { setYear((prev) => dayjs(prev).add(10, "year").toDate()); } break; @@ -221,11 +226,10 @@ const DateInputV2: React.FC = ({ if (min && year < min.getFullYear()) return false; if (max && year > max.getFullYear()) return false; - const date = new Date(year, month, 1); - if (min && date < new Date(min.getFullYear(), min.getMonth(), 1)) - return false; - if (max && date > new Date(max.getFullYear(), max.getMonth(), 1)) - return false; + const firstDay = new Date(year, month, 1); + const lastDay = new Date(year, month + 1, 0); + if (min && lastDay < min) return false; + if (max && firstDay > max) return false; return true; }; @@ -251,12 +255,14 @@ const DateInputV2: React.FC = ({ const setMonthValue = (month: number) => () => { if (isMonthWithinConstraints(month)) { + const lastDayOfMonth = new Date( + datePickerHeaderDate.getFullYear(), + month + 1, + 0, + ).getDate(); + const newDate = Math.min(datePickerHeaderDate.getDate(), lastDayOfMonth); setDatePickerHeaderDate( - new Date( - datePickerHeaderDate.getFullYear(), - month, - datePickerHeaderDate.getDate(), - ), + new Date(datePickerHeaderDate.getFullYear(), month, newDate), ); setType("date"); } else { From eb7348961e1f9dcd6aaeb20af0d938e6bc36b2e2 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Mon, 2 Dec 2024 18:15:20 +0530 Subject: [PATCH 4/6] Updated month logic for both increment and decrement --- src/components/Common/DateInputV2.tsx | 29 +++++++++++++-------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/components/Common/DateInputV2.tsx b/src/components/Common/DateInputV2.tsx index 86e5be8cbac..4e28bfb6bff 100644 --- a/src/components/Common/DateInputV2.tsx +++ b/src/components/Common/DateInputV2.tsx @@ -89,16 +89,13 @@ const DateInputV2: React.FC = ({ ); break; case "month": - if ( - !min || - datePickerHeaderDate.getFullYear() > min.getFullYear() || - (datePickerHeaderDate.getFullYear() === min.getFullYear() && - datePickerHeaderDate.getMonth() > min.getMonth()) - ) { - setDatePickerHeaderDate((prev) => - dayjs(prev).subtract(1, "year").toDate(), - ); - } + setDatePickerHeaderDate((prev) => { + const newDate = dayjs(prev).subtract(1, "year").toDate(); + if (min && newDate < min) { + return new Date(min.getFullYear(), min.getMonth(), 1); + } + return newDate; + }); break; case "year": if (!min || year.getFullYear() - 10 >= min.getFullYear()) { @@ -114,11 +111,13 @@ const DateInputV2: React.FC = ({ setDatePickerHeaderDate((prev) => dayjs(prev).add(1, "month").toDate()); break; case "month": - if (!max || datePickerHeaderDate.getFullYear() < max.getFullYear()) { - setDatePickerHeaderDate((prev) => - dayjs(prev).add(1, "year").toDate(), - ); - } + setDatePickerHeaderDate((prev) => { + const newDate = dayjs(prev).add(1, "year").toDate(); + if (max && newDate > max) { + return new Date(max.getFullYear(), max.getMonth(), 1); + } + return newDate; + }); break; case "year": if (!max || year.getFullYear() + 10 <= max.getFullYear()) { From a52b0a2140e24c7b1d918c45542e6ddfd186d5d6 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Thu, 5 Dec 2024 14:02:44 +0530 Subject: [PATCH 5/6] Ensured that selecting a year with invalid month ranges adjusts to the corresponding min month --- src/components/Common/DateInputV2.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/Common/DateInputV2.tsx b/src/components/Common/DateInputV2.tsx index 4e28bfb6bff..45cd8ca6be4 100644 --- a/src/components/Common/DateInputV2.tsx +++ b/src/components/Common/DateInputV2.tsx @@ -273,13 +273,16 @@ const DateInputV2: React.FC = ({ const setYearValue = (year: number) => () => { if (isYearWithinConstraints(year)) { - setDatePickerHeaderDate( - new Date( - year, - datePickerHeaderDate.getMonth(), - datePickerHeaderDate.getDate(), - ), + const newDate = new Date( + year, + datePickerHeaderDate.getMonth(), + datePickerHeaderDate.getDate(), ); + if (min && year === min.getFullYear() && newDate < min) { + setDatePickerHeaderDate(new Date(min.getFullYear(), min.getMonth(), 1)); + } else { + setDatePickerHeaderDate(newDate); + } setType("date"); } else { Notification.Error({ From 9d3e0d26fec4d444fb19760f4c0519d0b4763001 Mon Sep 17 00:00:00 2001 From: Rishith25 Date: Mon, 6 Jan 2025 21:32:19 +0530 Subject: [PATCH 6/6] Max and min Handled correctly --- src/components/Common/DateInputV2.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/Common/DateInputV2.tsx b/src/components/Common/DateInputV2.tsx index 45cd8ca6be4..d41eaddf588 100644 --- a/src/components/Common/DateInputV2.tsx +++ b/src/components/Common/DateInputV2.tsx @@ -279,7 +279,13 @@ const DateInputV2: React.FC = ({ datePickerHeaderDate.getDate(), ); if (min && year === min.getFullYear() && newDate < min) { - setDatePickerHeaderDate(new Date(min.getFullYear(), min.getMonth(), 1)); + setDatePickerHeaderDate( + new Date(min.getFullYear(), min.getMonth(), min.getDate()), + ); + } else if (max && year === max.getFullYear() && newDate > max) { + setDatePickerHeaderDate( + new Date(max.getFullYear(), max.getMonth(), max.getDate()), + ); } else { setDatePickerHeaderDate(newDate); }