diff --git a/src/lib/dropdown/select/index.tsx b/src/lib/dropdown/select/index.tsx index 8977fb8..47566f0 100644 --- a/src/lib/dropdown/select/index.tsx +++ b/src/lib/dropdown/select/index.tsx @@ -62,7 +62,10 @@ const Select: React.FC = ({ {...{ items, selected }} onChange={(value: IItem["value"]) => { new Promise((resolve) => resolve(callback(value))) - .then(() => setSelected(value)) + .then(() => { + setSelected(value); + setIsOpen(false); + }) .catch((error) => console.error(error)); }} /> diff --git a/src/lib/form/datepicker/day.tsx b/src/lib/form/datepicker/day.tsx index 2e790b9..af7f172 100644 --- a/src/lib/form/datepicker/day.tsx +++ b/src/lib/form/datepicker/day.tsx @@ -4,16 +4,25 @@ import { useDay } from "@datepicker-react/hooks"; import DatepickerContext from "./datepickerContext"; import { button, small } from "../../../styles/common-style"; -const StyledDayNumber = styled.small<{ isSelected: boolean }>` +const StyledDayNumber = styled.small<{ + isSelected: boolean; + disabledDate: boolean; +}>` ${small} color: ${(props) => props.isSelected ? props.theme.klerosUIComponentsWhiteBackground + : props.disabledDate + ? props.theme.klerosUIComponentsStroke : props.theme.klerosUIComponentsSecondaryText} !important; font-weight: 600; + cursor: ${(props) => (props.disabledDate ? "not-allowed" : "pointer")}; `; -const StyledButton = styled.button<{ isSelected: boolean }>` +const StyledButton = styled.button<{ + isSelected: boolean; + disabledDate: boolean; +}>` ${button} height: 24px; width: 24px; @@ -31,11 +40,14 @@ const StyledButton = styled.button<{ isSelected: boolean }>` background-color: ${(props) => props.isSelected ? props.theme.klerosUIComponentsPrimaryBlue + : props.disabledDate + ? props.theme.klerosUIComponentsWhiteBackground : props.theme.klerosUIComponentsSecondaryBlue}; - cursor: pointer; & ${StyledDayNumber} { - color: ${({ theme }) => - theme.klerosUIComponentsWhiteBackground} !important; + color: ${(props) => + props.disabledDate + ? props.theme.klerosUIComponentsStroke + : props.theme.klerosUIComponentsWhiteBackground} !important; } } `; @@ -52,12 +64,32 @@ const Day: React.FC = ({ date, dayLabel }) => { date, ...useContext(DatepickerContext), }); + + const today = new Date(); + today.setHours(0, 0, 0, 0); + const isPastDate = date.getTime() < today.getTime(); + + const handleClick = () => { + if (!isPastDate) { + onClick(); + } + }; + return ( - {dayLabel} + + {dayLabel} + ); }; diff --git a/src/lib/form/datepicker/index.tsx b/src/lib/form/datepicker/index.tsx index 1ad6a86..c027e5e 100644 --- a/src/lib/form/datepicker/index.tsx +++ b/src/lib/form/datepicker/index.tsx @@ -24,17 +24,33 @@ const DatePicker: React.FC = ({ onSelect, time }) => { const [date, setDate] = useState(new Date()); const [hours, setHours] = useState(date.getHours()); const [minutes, setMinutes] = useState(date.getMinutes()); + const today = new Date(); + const lastSelectableDate = new Date(today); + lastSelectableDate.setDate(today.getDate()); + + const updateDateWithTime = (selectedDate: Date) => { + if (selectedDate.toDateString() === lastSelectableDate.toDateString()) { + const now = new Date(); + selectedDate.setHours(now.getHours(), now.getMinutes()); + setHours(now.getHours()); + setMinutes(now.getMinutes()); + } else { + selectedDate.setHours(hours, minutes); + } + setDate(selectedDate); + onSelect(selectedDate); + }; + const { firstDayOfWeek, activeMonths, - isDateSelected, isDateHovered, isFirstOrLastSelectedDate, isDateBlocked, isDateFocused, focusedDate, onDateHover, - onDateSelect, + onDateSelect: handleDateSelect, onDateFocus, goToPreviousMonths, goToNextMonths, @@ -42,26 +58,44 @@ const DatePicker: React.FC = ({ onSelect, time }) => { startDate: date, endDate: date, focusedInput: START_DATE, - onDatesChange: (date) => { - if (date.startDate) { - date.startDate.setHours(hours, minutes); - setDate(date.startDate); + onDatesChange: (data) => { + if (data.startDate) { + updateDateWithTime(new Date(data.startDate)); } }, numberOfMonths: 1, minBookingDays: 1, exactMinBookingDays: true, }); + + const onTimeChange = (newHours: number, newMinutes: number) => { + const newDate = new Date(date); + newDate.setHours(newHours, newMinutes); + setHours(newHours); + setMinutes(newMinutes); + setDate(newDate); + onSelect(newDate); + }; + return ( { + return ( + selectedDate.getDate() === date.getDate() && + selectedDate.getMonth() === date.getMonth() && + selectedDate.getFullYear() === date.getFullYear() + ); + }, isDateHovered, isDateBlocked, isFirstOrLastSelectedDate, - onDateSelect, + onDateSelect: (selectedDate: Date) => { + handleDateSelect(selectedDate); + updateDateWithTime(selectedDate); + }, onDateFocus, onDateHover, }} @@ -79,8 +113,8 @@ const DatePicker: React.FC = ({ onSelect, time }) => { date, hours, minutes, - setHours, - setMinutes, + setHours: (newHours) => onTimeChange(newHours, minutes), + setMinutes: (newMinutes) => onTimeChange(hours, newMinutes), onSelect: () => { date.setHours(hours, minutes); onSelect(date); diff --git a/src/lib/form/datepicker/time-controls.tsx b/src/lib/form/datepicker/time-controls.tsx index ab0c056..f2873f2 100644 --- a/src/lib/form/datepicker/time-controls.tsx +++ b/src/lib/form/datepicker/time-controls.tsx @@ -83,68 +83,92 @@ const TimeControls: React.FC = ({ minutes, setHours, setMinutes, -}) => ( - - - { - const newHours = hours + 1; - setHours(newHours); - date.setHours(newHours, minutes); - }} - disabled={hours === 23} - > - - - { - const newMinutes = minutes + 1; - setMinutes(newMinutes); - date.setHours(hours, newMinutes); - }} - disabled={minutes === 59} - > - - - - - - {hours.toLocaleString("en-US", { - minimumIntegerDigits: 2, - useGrouping: false, - })} - - : - - {minutes.toLocaleString("en-US", { - minimumIntegerDigits: 2, - useGrouping: false, - })} - - - - { - const newHours = hours - 1; - setHours(newHours); - date.setHours(newHours, minutes); - }} - disabled={hours === 0} - > - - - { - const newMinutes = minutes - 1; - setMinutes(newMinutes); - date.setHours(hours, newMinutes); - }} - disabled={minutes === 0} - > - - - - -); +}) => { + const today = new Date(); + + const disableHourUp = hours === 23; + const disableMinuteUp = minutes === 59; + + const isToday = date.toDateString() === today.toDateString(); + const currentTime = today.getTime(); + const checkTime = new Date(date).setHours(hours - 1, minutes); + + const disableHourDown = + hours === 0 || + (isToday && + (hours - 1 < today.getHours() || + (hours - 1 === today.getHours() && minutes <= today.getMinutes()) || + checkTime <= currentTime)); + + const disableMinuteDown = + minutes === 0 || + (isToday && + (hours < today.getHours() || + (hours === today.getHours() && minutes - 1 <= today.getMinutes()))); + + return ( + + + { + const newHours = hours + 1; + setHours(newHours); + date.setHours(newHours, minutes); + }} + disabled={disableHourUp} + > + + + { + const newMinutes = minutes + 1; + setMinutes(newMinutes); + date.setHours(hours, newMinutes); + }} + disabled={disableMinuteUp} + > + + + + + + {hours.toLocaleString("en-US", { + minimumIntegerDigits: 2, + useGrouping: false, + })} + + : + + {minutes.toLocaleString("en-US", { + minimumIntegerDigits: 2, + useGrouping: false, + })} + + + + { + const newHours = hours - 1; + setHours(newHours); + date.setHours(newHours, minutes); + }} + disabled={disableHourDown} + > + + + { + const newMinutes = minutes - 1; + setMinutes(newMinutes); + date.setHours(hours, newMinutes); + }} + disabled={disableMinuteDown} + > + + + + + ); +}; export default TimeControls;