diff --git a/susconecta/components/features/forms/calendar-registration-form.tsx b/susconecta/components/features/forms/calendar-registration-form.tsx index 8243412..0eacf75 100644 --- a/susconecta/components/features/forms/calendar-registration-form.tsx +++ b/susconecta/components/features/forms/calendar-registration-form.tsx @@ -19,6 +19,7 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@/components/ui/select"; +import { Calendar as CalendarComponent } from "@/components/ui/calendar"; import { Calendar, Search, ChevronDown, X } from "lucide-react"; interface FormData { @@ -91,6 +92,7 @@ export function CalendarRegistrationForm({ formData, onFormChange, createMode = const [lockedDurationFromSlot, setLockedDurationFromSlot] = useState(false); const [exceptionDialogOpen, setExceptionDialogOpen] = useState(false); const [exceptionDialogMessage, setExceptionDialogMessage] = useState(null); + const [showDatePicker, setShowDatePicker] = useState(false); // Helpers to convert between ISO (server) and input[type=datetime-local] value const isoToDatetimeLocal = (iso?: string | null) => { @@ -554,6 +556,42 @@ export function CalendarRegistrationForm({ formData, onFormChange, createMode = // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + // Filter available slots: if date is today, only show future times + const filteredAvailableSlots = (() => { + try { + const now = new Date(); + const todayStr = now.toISOString().split('T')[0]; + const selectedDateStr = (formData as any).appointmentDate || null; + const currentHours = now.getHours(); + const currentMinutes = now.getMinutes(); + const currentTimeInMinutes = currentHours * 60 + currentMinutes; + + if (selectedDateStr === todayStr) { + // Today: filter out past times (add 30-minute buffer for admin to schedule) + return (availableSlots || []).filter((s) => { + try { + const slotDate = new Date(s.datetime); + const slotHours = slotDate.getHours(); + const slotMinutes = slotDate.getMinutes(); + const slotTimeInMinutes = slotHours * 60 + slotMinutes; + // Keep slots that are at least 30 minutes in the future + return slotTimeInMinutes >= currentTimeInMinutes + 30; + } catch (e) { + return true; + } + }); + } else if (selectedDateStr && selectedDateStr > todayStr) { + // Future date: show all slots + return availableSlots || []; + } else { + // Past date: no slots + return []; + } + } catch (e) { + return availableSlots || []; + } + })(); + const handleChange = (event: React.ChangeEvent) => { const { name, value } = event.target; @@ -684,6 +722,9 @@ export function CalendarRegistrationForm({ formData, onFormChange, createMode = } catch (e) {} + // ref to the appointment date input + const appointmentDateRef = useRef(null); + return (
{/* Exception dialog shown when a blocking exception exists for selected date */} @@ -863,10 +904,50 @@ export function CalendarRegistrationForm({ formData, onFormChange, createMode =
- +
+ + +
- - + { + try { + const [y, m, d] = String(formData.appointmentDate).split('-'); + return `${d}/${m}/${y}`; + } catch (e) { + return ''; + } + })() : ''} + readOnly + /> + {showDatePicker && ( +
+ { + if (date) { + const dateStr = date.toISOString().split('T')[0]; + onFormChange({ ...formData, appointmentDate: dateStr }); + setShowDatePicker(false); + } + }} + disabled={(date) => date < new Date(new Date().toISOString().split('T')[0] + 'T00:00:00')} + /> +
+ )}
@@ -1011,8 +1092,8 @@ export function CalendarRegistrationForm({ formData, onFormChange, createMode =
{loadingSlots ? (
Carregando horĂ¡rios...
- ) : availableSlots && availableSlots.length ? ( - availableSlots.map((s) => { + ) : filteredAvailableSlots && filteredAvailableSlots.length ? ( + filteredAvailableSlots.map((s) => { const dt = new Date(s.datetime); const hh = String(dt.getHours()).padStart(2, '0'); const mm = String(dt.getMinutes()).padStart(2, '0');