Fixed issue where logged-in users couldn't select future time slots

This commit is contained in:
Pramod Mahajan 2025-04-29 11:04:21 +05:30
parent c53aa1ec92
commit 7e45f6c429

View File

@ -4,6 +4,7 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
const [time, setTime] = useState(value || ""); const [time, setTime] = useState(value || "");
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null); const dropdownRef = useRef(null);
const slotRefs = useRef({});
const getCurrentTime = () => { const getCurrentTime = () => {
const now = new Date(); const now = new Date();
@ -27,44 +28,47 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
return `${hoursFormatted}:${minutesFormatted} ${period}`; 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 generateTimeSlots = () => {
const slots = []; const slots = [];
let currentTime = new Date(); const now = new Date();
currentTime.setSeconds(0); now.setSeconds(0);
currentTime.setMilliseconds(0); now.setMilliseconds(0);
const endTime = new Date(currentTime); // current time as upper limit // 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 slotTime = new Date(); let slot = new Date();
slotTime.setHours(0, 0, 0, 0); // start from 00:00 slot.setHours(0, 0, 0, 0); // Start from midnight
while (slotTime <= endTime) { for (let i = 0; i < 144; i++) {
slots.push(formatTime(new Date(slotTime))); const formatted = formatTime(slot);
slotTime.setMinutes(slotTime.getMinutes() + interval); const diffInMinutes = (currentSlot - slot) / 60000;
const isSelectable = diffInMinutes >= 0 && diffInMinutes <= interval * 5;
slots.push({
time: formatted,
isSelectable,
});
slot.setMinutes(slot.getMinutes() + interval);
} }
return slots; return slots;
}; };
const handleSelect = (selectedTime) => { const handleSelect = (selectedTime) => {
setTime(selectedTime); setTime(selectedTime);
if (onChange) onChange(selectedTime); if (onChange) onChange(selectedTime);
setIsOpen(false); setIsOpen(false);
}; };
// Handle click outside the dropdown to close it
useEffect(() => { useEffect(() => {
const handleClickOutside = (event) => { const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@ -75,6 +79,7 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
return () => document.removeEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside);
}, []); }, []);
// If there's no value, set the default time
useEffect(() => { useEffect(() => {
if (!value) { if (!value) {
const defaultTime = formatTime(getCurrentTime()); const defaultTime = formatTime(getCurrentTime());
@ -83,6 +88,17 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
} }
}, [value, interval, onChange]); }, [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 ( return (
<div className="position-relative w-100" ref={dropdownRef}> <div className="position-relative w-100" ref={dropdownRef}>
{label && <label className="form-label">{label}</label>} {label && <label className="form-label">{label}</label>}
@ -114,22 +130,27 @@ const TimePicker = ({ label, onChange, interval = 10, value }) => {
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
gap: "5px", gap: "5px",
maxHeight: "200px", // Adjust max height to fit the container maxHeight: "200px",
overflowY: "auto", // Enables vertical scrolling overflowY: "auto",
}} }}
> >
{generateTimeSlots().map((slot, index) => ( {generateTimeSlots().map(({ time: slotTime, isSelectable }, index) => (
<button <button
key={index} key={index}
className={`dropdown-item px-3 py-1 text-center rounded-1 ${ 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) => { onClick={(event) => {
event.preventDefault(); event.preventDefault();
handleSelect(slot); if (isSelectable) handleSelect(slotTime);
}} }}
disabled={!isSelectable}
style={
!isSelectable ? { opacity: 0.5, cursor: "not-allowed" } : {}
}
> >
{slot} {slotTime}
</button> </button>
))} ))}
</div> </div>