Fixed issue where logged-in users couldn't select future time slots
This commit is contained in:
parent
c53aa1ec92
commit
7e45f6c429
@ -4,6 +4,7 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
|
||||
const [time, setTime] = useState(value || "");
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const dropdownRef = useRef(null);
|
||||
const slotRefs = useRef({});
|
||||
|
||||
const getCurrentTime = () => {
|
||||
const now = new Date();
|
||||
@ -27,37 +28,39 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
|
||||
|
||||
return `${hoursFormatted}:${minutesFormatted} ${period}`;
|
||||
};
|
||||
// all slots
|
||||
// const generateTimeSlots = () => {
|
||||
// const slots = [];
|
||||
// let currentTime = new Date(getCurrentTime());
|
||||
// for (let i = 0; i < 144; i++) { // 24 hours with custom interval
|
||||
// slots.push(formatTime(currentTime));
|
||||
// currentTime.setMinutes(currentTime.getMinutes() + interval);
|
||||
// }
|
||||
// return slots;
|
||||
// };
|
||||
|
||||
// imit slots to current time:
|
||||
const generateTimeSlots = () => {
|
||||
const slots = [];
|
||||
let currentTime = new Date();
|
||||
currentTime.setSeconds(0);
|
||||
currentTime.setMilliseconds(0);
|
||||
|
||||
const endTime = new Date(currentTime); // current time as upper limit
|
||||
|
||||
let slotTime = new Date();
|
||||
slotTime.setHours(0, 0, 0, 0); // start from 00:00
|
||||
|
||||
while (slotTime <= endTime) {
|
||||
slots.push(formatTime(new Date(slotTime)));
|
||||
slotTime.setMinutes(slotTime.getMinutes() + interval);
|
||||
const now = new Date();
|
||||
now.setSeconds(0);
|
||||
now.setMilliseconds(0);
|
||||
|
||||
// Round current time DOWN to nearest interval
|
||||
const currentSlot = new Date();
|
||||
currentSlot.setMinutes(
|
||||
Math.floor(currentSlot.getMinutes() / interval) * interval
|
||||
);
|
||||
currentSlot.setSeconds(0);
|
||||
currentSlot.setMilliseconds(0);
|
||||
|
||||
let slot = new Date();
|
||||
slot.setHours(0, 0, 0, 0); // Start from midnight
|
||||
|
||||
for (let i = 0; i < 144; i++) {
|
||||
const formatted = formatTime(slot);
|
||||
const diffInMinutes = (currentSlot - slot) / 60000;
|
||||
const isSelectable = diffInMinutes >= 0 && diffInMinutes <= interval * 5;
|
||||
|
||||
slots.push({
|
||||
time: formatted,
|
||||
isSelectable,
|
||||
});
|
||||
|
||||
slot.setMinutes(slot.getMinutes() + interval);
|
||||
}
|
||||
|
||||
|
||||
return slots;
|
||||
};
|
||||
|
||||
|
||||
const handleSelect = (selectedTime) => {
|
||||
setTime(selectedTime);
|
||||
@ -65,6 +68,7 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
// Handle click outside the dropdown to close it
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event) => {
|
||||
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
||||
@ -75,14 +79,26 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
|
||||
return () => document.removeEventListener("mousedown", handleClickOutside);
|
||||
}, []);
|
||||
|
||||
// If there's no value, set the default time
|
||||
useEffect(() => {
|
||||
if (!value) {
|
||||
const defaultTime = formatTime(getCurrentTime());
|
||||
setTime(defaultTime);
|
||||
if (onChange) onChange(defaultTime);
|
||||
if (onChange) onChange(defaultTime);
|
||||
}
|
||||
}, [value, interval, onChange]);
|
||||
|
||||
// Scroll to the selected slot when it's open
|
||||
useEffect(() => {
|
||||
if (isOpen && time && slotRefs.current[time]) {
|
||||
const selectedSlot = slotRefs.current[time];
|
||||
selectedSlot.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "center",
|
||||
});
|
||||
}
|
||||
}, [isOpen, time]);
|
||||
|
||||
return (
|
||||
<div className="position-relative w-100" ref={dropdownRef}>
|
||||
{label && <label className="form-label">{label}</label>}
|
||||
@ -114,22 +130,27 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "5px",
|
||||
maxHeight: "200px", // Adjust max height to fit the container
|
||||
overflowY: "auto", // Enables vertical scrolling
|
||||
maxHeight: "200px",
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
{generateTimeSlots().map((slot, index) => (
|
||||
{generateTimeSlots().map(({ time: slotTime, isSelectable }, index) => (
|
||||
<button
|
||||
key={index}
|
||||
className={`dropdown-item px-3 py-1 text-center rounded-1 ${
|
||||
time === slot ? "btn-primary" : ""
|
||||
time === slotTime ? "btn-primary" : ""
|
||||
}`}
|
||||
ref={(el) => (slotRefs.current[slotTime] = el)}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
handleSelect(slot);
|
||||
if (isSelectable) handleSelect(slotTime);
|
||||
}}
|
||||
disabled={!isSelectable}
|
||||
style={
|
||||
!isSelectable ? { opacity: 0.5, cursor: "not-allowed" } : {}
|
||||
}
|
||||
>
|
||||
{slot}
|
||||
{slotTime}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user