diff --git a/components/CreateEventDialog.vue b/components/CreateEventDialog.vue index 6fdf273..c5dce14 100644 --- a/components/CreateEventDialog.vue +++ b/components/CreateEventDialog.vue @@ -80,13 +80,11 @@ - - (''); const endDate = ref(''); const endTime = ref(''); -// Legacy date model refs for backward compatibility -const startDateModel = ref(null); -const endDateModel = ref(null); - -// Date format for display -const dateTimeFormat = 'dd/MM/yyyy HH:mm (Monaco)'; // Form data const eventData = reactive({ @@ -442,20 +428,6 @@ watch(maxGuestsPerPerson, (newValue) => { } }); -// Fix date picker binding - ensure proper syncing -watch(startDateModel, (newDate) => { - if (newDate instanceof Date) { - eventData.start_datetime = newDate.toISOString(); - console.log('[CreateEventDialog] Start date updated:', eventData.start_datetime); - } -}); - -watch(endDateModel, (newDate) => { - if (newDate instanceof Date) { - eventData.end_datetime = newDate.toISOString(); - console.log('[CreateEventDialog] End date updated:', eventData.end_datetime); - } -}); watch(isRecurring, (newValue) => { eventData.is_recurring = newValue ? 'true' : 'false'; @@ -489,38 +461,26 @@ watch(startDate, (newStartDate) => { } }); -// Watch for separate date and time changes to combine them using robust parsing -watch([startDate, startTime], ([newDate, newTime]) => { - if (newDate && newTime) { - console.log('[CreateEventDialog] Combining start date/time:', { date: newDate, time: newTime }); - - const combinedDateTime = createDateTimeFromParts(newDate, newTime); - - if (!combinedDateTime) { - console.error('[CreateEventDialog] Failed to create start datetime from parts:', { date: newDate, time: newTime }); - return; +// Consolidated watcher for all date/time changes +watch([startDate, startTime, endDate, endTime], ([newStartDate, newStartTime, newEndDate, newEndTime]) => { + // Update start datetime + if (newStartDate && newStartTime) { + const startDateTime = createDateTime(newStartDate, newStartTime); + if (startDateTime) { + eventData.start_datetime = startDateTime.toISOString(); + console.log('[CreateEventDialog] Updated start datetime:', eventData.start_datetime); } - - eventData.start_datetime = combinedDateTime.toISOString(); - console.log('[CreateEventDialog] Combined start datetime:', eventData.start_datetime); } -}); - -watch([endDate, endTime], ([newDate, newTime]) => { - if (newDate && newTime) { - console.log('[CreateEventDialog] Combining end date/time:', { date: newDate, time: newTime }); - - const combinedDateTime = createDateTimeFromParts(newDate, newTime); - - if (!combinedDateTime) { - console.error('[CreateEventDialog] Failed to create end datetime from parts:', { date: newDate, time: newTime }); - return; + + // Update end datetime + if (newEndDate && newEndTime) { + const endDateTime = createDateTime(newEndDate, newEndTime); + if (endDateTime) { + eventData.end_datetime = endDateTime.toISOString(); + console.log('[CreateEventDialog] Updated end datetime:', eventData.end_datetime); } - - eventData.end_datetime = combinedDateTime.toISOString(); - console.log('[CreateEventDialog] Combined end datetime:', eventData.end_datetime); } -}); +}, { deep: true }); // Watch for prefilled dates watch(() => props.prefilledDate, (newDate) => { @@ -547,142 +507,48 @@ watch(() => props.prefilledEndDate, (newEndDate) => { } }, { immediate: true }); -// Date picker handlers -const handleStartDateUpdate = (date: Date | null) => { - if (date) { - eventData.start_datetime = date.toISOString(); - } + +// Simple date/time functions +const createDateTime = (dateStr: string, timeStr: string): Date | null => { + if (!dateStr || !timeStr) return null; + + const combined = new Date(`${dateStr}T${timeStr}:00`); + return isNaN(combined.getTime()) ? null : combined; }; -const handleEndDateUpdate = (date: Date | null) => { - if (date) { - eventData.end_datetime = date.toISOString(); - } +const isValidDateTime = (date: Date | null): boolean => { + return date !== null && !isNaN(date.getTime()); }; -const onDatePickerClosed = () => { - console.log('[CreateEventDialog] Date picker closed'); - // This handler ensures the date picker behaves correctly on mobile and desktop +// Simple end time validation +const validateEndTime = (endTimeValue: string): boolean => { + if (!startDate.value || !endDate.value || !startTime.value || !endTimeValue) return true; + if (startDate.value !== endDate.value) return true; + + const startDateTime = createDateTime(startDate.value, startTime.value); + const endDateTime = createDateTime(endDate.value, endTimeValue); + + if (!startDateTime || !endDateTime) return false; + return endDateTime > startDateTime; }; -// Helper functions -const normalizeTimeFormat = (timeString: string): string => { - // Ensure time is in HH:MM 24-hour format - if (!timeString) return ''; - - // Remove any whitespace - const cleaned = timeString.trim(); - - // If already in HH:MM format, validate and return - if (/^\d{2}:\d{2}$/.test(cleaned)) { - const [hours, minutes] = cleaned.split(':').map(Number); - if (hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59) { - return cleaned; - } - } - - // If in H:MM format, pad with zero - if (/^\d{1}:\d{2}$/.test(cleaned)) { - const [hours, minutes] = cleaned.split(':'); - const paddedHours = hours.padStart(2, '0'); - const numHours = Number(paddedHours); - const numMinutes = Number(minutes); - if (numHours >= 0 && numHours <= 23 && numMinutes >= 0 && numMinutes <= 59) { - return `${paddedHours}:${minutes}`; - } - } - - // Handle seconds format HH:MM:SS by truncating - if (/^\d{2}:\d{2}:\d{2}$/.test(cleaned)) { - const timePart = cleaned.substring(0, 5); - return normalizeTimeFormat(timePart); - } - - console.error('[CreateEventDialog] Invalid time format:', timeString); - return ''; -}; - -const createDateTimeFromParts = (dateString: string, timeString: string): Date | null => { - if (!dateString || !timeString) { - return null; - } - - try { - // Normalize the time format first - const normalizedTime = normalizeTimeFormat(timeString); - if (!normalizedTime) { - console.error('[CreateEventDialog] Failed to normalize time:', timeString); - return null; - } - - // Split time into parts - const [hours, minutes] = normalizedTime.split(':').map(Number); - - // Create date object from date string (YYYY-MM-DD format) - const dateObj = new Date(dateString + 'T00:00:00'); - - if (isNaN(dateObj.getTime())) { - console.error('[CreateEventDialog] Invalid date string:', dateString); - return null; - } - - // Set the time components - dateObj.setHours(hours, minutes, 0, 0); - - // Validate the final result - if (isNaN(dateObj.getTime())) { - console.error('[CreateEventDialog] Invalid combined datetime:', { dateString, timeString, normalizedTime, hours, minutes }); - return null; - } - - return dateObj; - } catch (error) { - console.error('[CreateEventDialog] Error creating datetime:', error, { dateString, timeString }); - return null; - } -}; - -// Validation functions -const validateEndTime = () => { - if (!startDate.value || !endDate.value || !startTime.value || !endTime.value) { - return false; // Return false (no error) if not all fields are filled - } - - console.log('[CreateEventDialog] validateEndTime called with:', { - startDate: startDate.value, - endDate: endDate.value, - startTime: startTime.value, - endTime: endTime.value - }); - - // Only validate if start and end are on the same date - if (startDate.value === endDate.value) { - // Use robust parsing to create datetime objects - const startDateTime = createDateTimeFromParts(startDate.value, startTime.value); - const endDateTime = createDateTimeFromParts(endDate.value, endTime.value); - - // Check if dates are valid - if (!startDateTime || !endDateTime) { - console.error('[CreateEventDialog] Failed to create datetime objects in validation'); - return true; // Return error if dates are invalid - } - - console.log('[CreateEventDialog] Time comparison:', { - startDateTime: startDateTime.toISOString(), - endDateTime: endDateTime.toISOString(), - startTimestamp: startDateTime.getTime(), - endTimestamp: endDateTime.getTime(), - endIsAfterStart: endDateTime.getTime() > startDateTime.getTime() - }); - - // Return true if there's an error (end is NOT after start) - const hasError = endDateTime.getTime() <= startDateTime.getTime(); - console.log('[CreateEventDialog] Validation result - hasError:', hasError); - - return hasError; - } - - return false; // No error if different dates +// Validation rules +const dateValidationRules = { + startDate: [ + (v: string) => !!v || 'Start date is required', + (v: string) => !v || new Date(v).getTime() >= new Date().setHours(0,0,0,0) || 'Start date cannot be in the past' + ], + startTime: [ + (v: string) => !!v || 'Start time is required' + ], + endDate: [ + (v: string) => !!v || 'End date is required', + (v: string) => !v || !startDate.value || new Date(v).getTime() >= new Date(startDate.value).getTime() || 'End date must be same or after start date' + ], + endTime: [ + (v: string) => !!v || 'End time is required', + (v: string) => validateEndTime(v) || 'End time must be after start time when on same date' + ] }; // Methods @@ -705,11 +571,7 @@ const resetForm = () => { eventData.is_recurring = 'false'; eventData.recurrence_pattern = ''; - // Reset date pickers - startDateModel.value = null; - endDateModel.value = null; - - // Reset separate date/time fields + // Reset date/time fields startDate.value = ''; startTime.value = ''; endDate.value = ''; @@ -757,30 +619,18 @@ const handleSubmit = async () => { loading.value = true; try { - // Combine date and time properly using robust parsing - const startDateTime = createDateTimeFromParts(startDate.value, startTime.value); - const endDateTime = createDateTimeFromParts(endDate.value, endTime.value); + // Simple date validation using our new function + const startDateTime = createDateTime(startDate.value, startTime.value); + const endDateTime = createDateTime(endDate.value, endTime.value); - console.log('[CreateEventDialog] DateTime validation:', { - startDate: startDate.value, - startTime: startTime.value, - endDate: endDate.value, - endTime: endTime.value, - startDateTime: startDateTime?.toISOString(), - endDateTime: endDateTime?.toISOString(), - startTimestamp: startDateTime?.getTime(), - endTimestamp: endDateTime?.getTime() - }); - - // Validate dates are valid if (!startDateTime) { - errorMessage.value = 'Invalid start date or time format'; + errorMessage.value = 'Please enter a valid start date and time'; loading.value = false; return; } if (!endDateTime) { - errorMessage.value = 'Invalid end date or time format'; + errorMessage.value = 'Please enter a valid end date and time'; loading.value = false; return; }