diff --git a/src/Components/Common/DateInputV2.tsx b/src/Components/Common/DateInputV2.tsx index da974fbe0e9..76e62c6e1c9 100644 --- a/src/Components/Common/DateInputV2.tsx +++ b/src/Components/Common/DateInputV2.tsx @@ -1,4 +1,4 @@ -import { MutableRefObject, useEffect, useState } from "react"; +import { MutableRefObject, useEffect, useRef, useState } from "react"; import CareIcon from "../../CAREUI/icons/CareIcon"; import { Popover } from "@headlessui/react"; @@ -25,6 +25,7 @@ interface Props { placeholder?: string; isOpen?: boolean; setIsOpen?: (isOpen: boolean) => void; + isDateTime?: boolean; } const DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; @@ -44,6 +45,7 @@ const DateInputV2: React.FC = ({ placeholder, isOpen, setIsOpen, + isDateTime, }) => { const [dayCount, setDayCount] = useState>([]); const [blankDays, setBlankDays] = useState>([]); @@ -52,9 +54,23 @@ const DateInputV2: React.FC = ({ const [type, setType] = useState("date"); const [year, setYear] = useState(new Date()); const [displayValue, setDisplayValue] = useState( - value ? dayjs(value).format("DDMMYYYY") : "" + value + ? isDateTime + ? dayjs(value).format("DDMMYYYYHHmm") + : dayjs(value).format("DDMMYYYY") + : "" ); + const hours = Array.from({ length: 24 }, (_, index) => index); + const minutes = Array.from({ length: 60 }, (_, index) => index); + + const minutesRef = useRef(null); + const hoursRef = useRef(null); + + useEffect(() => { + value && setDatePickerHeaderDate(new Date(value)); + }, [value]); + const decrement = () => { switch (type) { case "date": @@ -99,6 +115,22 @@ const DateInputV2: React.FC = ({ } }; + const isSelectedHour = (hour: number) => { + if (value) { + return value.getHours() == hour; + } + }; + + const isSelectedMinute = (minutes: number) => { + if (value) { + return value.getMinutes() == minutes; + } + }; + + // calling the below functions just for commits + isSelectedHour(60); + isSelectedMinute(20); + type CloseFunction = ( focusableElement?: HTMLElement | MutableRefObject ) => void; @@ -110,7 +142,9 @@ const DateInputV2: React.FC = ({ new Date( datePickerHeaderDate.getFullYear(), datePickerHeaderDate.getMonth(), - date + date, + datePickerHeaderDate.getHours(), + datePickerHeaderDate.getMinutes() ) ); close(); @@ -176,6 +210,30 @@ const DateInputV2: React.FC = ({ setType("date"); }; + const setHourValue = (hour: number) => () => { + setDatePickerHeaderDate( + new Date( + datePickerHeaderDate.getFullYear(), + datePickerHeaderDate.getMonth(), + datePickerHeaderDate.getDate(), + hour, + datePickerHeaderDate.getMinutes() + ) + ); + }; + + const setMinuteValue = (minutes: number) => () => { + setDatePickerHeaderDate( + new Date( + datePickerHeaderDate.getFullYear(), + datePickerHeaderDate.getMonth(), + datePickerHeaderDate.getDate(), + datePickerHeaderDate.getHours(), + minutes + ) + ); + }; + const setYearValue = (year: number) => () => { setDatePickerHeaderDate( new Date( @@ -195,10 +253,6 @@ const DateInputV2: React.FC = ({ getDayCount(datePickerHeaderDate); }, [datePickerHeaderDate]); - useEffect(() => { - value && setDatePickerHeaderDate(new Date(value)); - }, [value]); - const getPosition = () => { switch (position) { case "LEFT": @@ -212,6 +266,29 @@ const DateInputV2: React.FC = ({ } }; + useEffect(() => { + const currMin = datePickerHeaderDate.getMinutes(); + const currHour = datePickerHeaderDate.getHours(); + // console.log(minutesRef.current, "currmin"); + if (minutesRef.current) { + const minuteHeight = minutesRef.current.scrollHeight / 60; + const minuteScrollPosition = currMin * minuteHeight; + minutesRef.current.scrollTop = + minuteScrollPosition - minutesRef.current.clientHeight / 2; + // console.log( + // "msp", + // minuteScrollPosition - minutesRef.current.clientHeight / 2 + // ); + } + + if (hoursRef.current) { + const hourHeight = hoursRef.current.scrollHeight / 24; + const hourScrollPosition = currHour * hourHeight; + hoursRef.current.scrollTop = + hourScrollPosition - hoursRef.current.clientHeight / 2; + } + }, [datePickerHeaderDate, minutesRef, hoursRef.current]); + return (
= ({ disabled={disabled} className={`cui-input-base cursor-pointer disabled:cursor-not-allowed ${className}`} placeholder={placeholder ?? t("select_date")} - value={value && dayjs(value).format("DD/MM/YYYY")} + value={ + value && isDateTime + ? dayjs(value).format("DD/MM/YYYY HH:mm") + : dayjs(value).format("DD/MM/YYYY") + } />
@@ -241,7 +322,8 @@ const DateInputV2: React.FC = ({ @@ -256,11 +338,15 @@ const DateInputV2: React.FC = ({ (_, dd, mm, yyyy) => [dd, mm, yyyy].filter(Boolean).join("/") ) || "" - } // Display the value in DD/MM/YYYY format + } + // Display the value in DD/MM/YYYY format placeholder={t("DD/MM/YYYY")} onChange={(e) => { setDisplayValue(e.target.value.replaceAll("/", "")); - const value = dayjs(e.target.value, "DD/MM/YYYY", true); + const value = isDateTime + ? dayjs(e.target.value, "DD/MM/YYYY HH:mm", true) + : dayjs(e.target.value, "DD/MM/YYYY", true); + if (value.isValid()) { onChange(value.toDate()); close(); @@ -318,65 +404,118 @@ const DateInputV2: React.FC = ({
{type === "date" && ( - <> -
- {DAYS.map((day, i) => ( -
-
- {day} +
+
+
+ {DAYS.map((day, i) => ( +
+
+ {day} +
-
- ))} -
-
- {blankDays.map((_, i) => ( -
- ))} - {dayCount.map((d, i) => { - const withinConstraints = isDateWithinConstraints(d); - const selected = value && isSelectedDate(d); - - const baseClasses = - "flex h-full items-center justify-center rounded text-center text-sm leading-loose transition duration-100 ease-in-out"; - let conditionalClasses = ""; - - if (withinConstraints) { - if (selected) { - conditionalClasses = - "bg-primary-500 font-bold text-white"; + ))} +
+
+ {blankDays.map((_, i) => ( +
+ ))} + {dayCount.map((d, i) => { + const withinConstraints = + isDateWithinConstraints(d); + const selected = value && isSelectedDate(d); + + const baseClasses = + "flex h-full items-center justify-center rounded text-center text-sm leading-loose transition duration-100 ease-in-out"; + let conditionalClasses = ""; + + if (withinConstraints) { + if (selected) { + conditionalClasses = + "bg-primary-500 font-bold text-white"; + } else { + conditionalClasses = + "hover:bg-gray-300 cursor-pointer"; + } } else { conditionalClasses = - "hover:bg-gray-300 cursor-pointer"; + "!cursor-not-allowed !text-gray-400"; } - } else { - conditionalClasses = - "!cursor-not-allowed !text-gray-400"; - } - return ( -
+ return (
- {d} +
+ {d} +
-
- ); - })} + ); + })} +
- + {isDateTime && ( +
+
+ {hours.map((hr) => ( +
+
+ {hr.toString().padStart(2, "0")} +
+
+ ))} +
+
+ {minutes.map((min) => { + return ( +
+
+ {min.toString().padStart(2, "0")} +
+
+ ); + })} +
+
+ )} +
)} + {type === "month" && (
{Array(12) diff --git a/src/Components/Form/FormFields/DateFormField.tsx b/src/Components/Form/FormFields/DateFormField.tsx index adb8c2538ae..b8265235133 100644 --- a/src/Components/Form/FormFields/DateFormField.tsx +++ b/src/Components/Form/FormFields/DateFormField.tsx @@ -12,6 +12,7 @@ type Props = FormFieldBaseProps & { position?: DatePickerPosition; disableFuture?: boolean; disablePast?: boolean; + isDateTime?: boolean; }; /** @@ -48,6 +49,7 @@ const DateFormField = (props: Props) => { min={props.min ?? (props.disablePast ? yesterday() : undefined)} position={props.position ?? "RIGHT"} placeholder={props.placeholder} + isDateTime={props.isDateTime} /> ); diff --git a/src/style/index.css b/src/style/index.css index 8767498e42a..ba837b4656e 100644 --- a/src/style/index.css +++ b/src/style/index.css @@ -1262,3 +1262,8 @@ input[type="number"] { color: #2856ff; font-size: 1rem; } +/* scroll bar for dateInputV2 styling */ +.thinScroll::-webkit-scrollbar{ + width: 0px; +} +