From 86b59c756f2cf8371c7ca315c86e42c78c587004 Mon Sep 17 00:00:00 2001 From: dwindown Date: Wed, 31 Dec 2025 18:11:41 +0700 Subject: [PATCH] Fix time slot picker bugs for past dates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed issues: - Added isAvailable parameter to handleSlotClick to prevent clicks on unavailable slots - Added validation to prevent selecting past dates in date picker - Added validation in handlePreviousDay to block navigating to past dates - Added warning message when trying to view past dates - Prevents the "slot is not defined" error when clicking disabled slots Now the modal properly: - Blocks selecting dates before today - Shows clear error messages for past dates - Prevents clicks on unavailable time slots - Handles edge cases like passed sessions being rescheduled 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/components/admin/TimeSlotPickerModal.tsx | 23 ++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/components/admin/TimeSlotPickerModal.tsx b/src/components/admin/TimeSlotPickerModal.tsx index 97456f7..b5ca961 100644 --- a/src/components/admin/TimeSlotPickerModal.tsx +++ b/src/components/admin/TimeSlotPickerModal.tsx @@ -120,6 +120,10 @@ export function TimeSlotPickerModal({ // Date navigation handlers const handlePreviousDay = () => { const newDate = addDays(currentDate, -1); + // Prevent going to past dates + if (isPast(newDate) && !isToday(newDate)) { + return; + } setCurrentDate(newDate); }; @@ -131,6 +135,10 @@ export function TimeSlotPickerModal({ const handleDateChange = (e: React.ChangeEvent) => { const newDate = parse(e.target.value, 'yyyy-MM-dd', new Date()); if (!isNaN(newDate.getTime())) { + // Prevent selecting past dates + if (isPast(newDate) && !isToday(newDate)) { + return; + } setCurrentDate(newDate); } }; @@ -208,8 +216,9 @@ export function TimeSlotPickerModal({ const totalBlocks = getSlotsInRange().length; const totalDuration = totalBlocks * (settings?.consulting_block_duration_minutes || 30); - const handleSlotClick = (slotStart: string) => { - if (!slot.available) return; + const handleSlotClick = (slotStart: string, isAvailable: boolean) => { + // Prevent clicking on unavailable slots + if (!isAvailable) return; // No selection yet → Set as pending if (!selectedRange.start) { @@ -327,7 +336,13 @@ export function TimeSlotPickerModal({ {/* Info */} - {isToday(currentDate) && timeSlots.length === 0 ? ( + {isPast(currentDate) && !isToday(currentDate) ? ( +
+

+ Tidak dapat memilih tanggal yang sudah lewat. Silakan pilih tanggal hari ini atau tanggal yang akan datang. +

+
+ ) : isToday(currentDate) && timeSlots.length === 0 ? (

Tidak ada slot tersedia untuk sisa hari ini. Silakan pilih tanggal lain. @@ -367,7 +382,7 @@ export function TimeSlotPickerModal({ !slot.available ? 'opacity-30 cursor-not-allowed' : '' }`} disabled={!slot.available} - onClick={() => handleSlotClick(slot.start)} + onClick={() => handleSlotClick(slot.start, slot.available)} > {slot.start}