import { ref, reactive, computed, watch, defineComponent, PropType } from 'vue'; import type { Recurrence, RecurrenceType } from '../../types'; import { DAYS_OF_WEEK, RECURRENCE_TYPE_OPTIONS } from '../../types'; export default defineComponent({ name: 'RecurrenceSelector', props: { modelValue: { type: Object as PropType, default: () => ({ type: 'once' }) } }, emits: ['update:modelValue'], setup(props, { emit }) { // State const localRecurrence = reactive({ type: 'once', daysOfWeek: [], customDates: [], startDate: '', endDate: '', excludedDates: [] }); const selectedDates = ref([]); const excludedDates = ref([]); // Opzioni const recurrenceTypes = RECURRENCE_TYPE_OPTIONS.map(opt => ({ label: opt.label, value: opt.value, icon: opt.icon })); const daysOfWeek = DAYS_OF_WEEK; // Watch per sincronizzare con modelValue watch(() => props.modelValue, (newVal) => { if (newVal) { Object.assign(localRecurrence, newVal); if (newVal.customDates) { selectedDates.value = newVal.customDates.map(d => typeof d === 'string' ? d : new Date(d).toISOString().split('T')[0] ); } if (newVal.excludedDates) { excludedDates.value = newVal.excludedDates.map(d => typeof d === 'string' ? d : new Date(d).toISOString().split('T')[0] ); } } }, { immediate: true, deep: true }); // Watch per emettere update watch([localRecurrence, selectedDates, excludedDates], () => { const result: Recurrence = { type: localRecurrence.type }; if (localRecurrence.type !== 'once') { result.startDate = localRecurrence.startDate; result.endDate = localRecurrence.endDate; if (excludedDates.value.length > 0) { result.excludedDates = excludedDates.value; } } if (localRecurrence.type === 'weekly' || localRecurrence.type === 'custom_days') { result.daysOfWeek = localRecurrence.daysOfWeek; } if (localRecurrence.type === 'custom_dates') { result.customDates = selectedDates.value; } emit('update:modelValue', result); }, { deep: true }); // Methods const isDaySelected = (day: number): boolean => { return localRecurrence.daysOfWeek?.includes(day) || false; }; const toggleDay = (day: number) => { if (!localRecurrence.daysOfWeek) { localRecurrence.daysOfWeek = []; } const index = localRecurrence.daysOfWeek.indexOf(day); if (index === -1) { localRecurrence.daysOfWeek.push(day); } else { localRecurrence.daysOfWeek.splice(index, 1); } // Ordina i giorni localRecurrence.daysOfWeek.sort((a, b) => a - b); }; const removeDate = (index: number) => { selectedDates.value.splice(index, 1); }; const removeExcludedDate = (index: number) => { excludedDates.value.splice(index, 1); }; const formatDate = (dateStr: string): string => { const date = new Date(dateStr); return date.toLocaleDateString('it-IT', { weekday: 'short', day: 'numeric', month: 'short' }); }; // Date options (solo date future) const dateOptions = (date: string): boolean => { const today = new Date(); today.setHours(0, 0, 0, 0); const checkDate = new Date(date); return checkDate >= today; }; const exclusionDateOptions = (date: string): boolean => { if (!localRecurrence.startDate || !localRecurrence.endDate) { return dateOptions(date); } const checkDate = new Date(date); const start = new Date(localRecurrence.startDate); const end = new Date(localRecurrence.endDate); return checkDate >= start && checkDate <= end; }; // Riepilogo testuale const summaryText = computed(() => { switch (localRecurrence.type) { case 'once': return 'Viaggio singolo, senza ripetizioni'; case 'weekly': if (!localRecurrence.daysOfWeek?.length) { return 'Seleziona i giorni della settimana'; } const weeklyDays = localRecurrence.daysOfWeek .map(d => daysOfWeek.find(day => day.value === d)?.label) .join(', '); return `Ogni settimana: ${weeklyDays}`; case 'custom_days': if (!localRecurrence.daysOfWeek?.length) { return 'Seleziona i giorni della settimana'; } const customDays = localRecurrence.daysOfWeek .map(d => daysOfWeek.find(day => day.value === d)?.label) .join(', '); return `Giorni selezionati: ${customDays}`; case 'custom_dates': if (!selectedDates.value.length) { return 'Seleziona le date dal calendario'; } return `${selectedDates.value.length} date selezionate`; default: return ''; } }); return { // State localRecurrence, selectedDates, excludedDates, // Options recurrenceTypes, daysOfWeek, // Computed summaryText, // Methods isDaySelected, toggleDay, removeDate, removeExcludedDate, formatDate, dateOptions, exclusionDateOptions }; } });