Files
myprojplanet_vite/src/modules/viaggi/components/ride/RecurrenceSelector.ts
Surya Paolo 11c17bdd8e - Parte 3 : Viaggi
- Chat
2025-12-24 00:26:29 +01:00

200 lines
5.4 KiB
TypeScript

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<Recurrence>,
default: () => ({ type: 'once' })
}
},
emits: ['update:modelValue'],
setup(props, { emit }) {
// State
const localRecurrence = reactive<Recurrence>({
type: 'once',
daysOfWeek: [],
customDates: [],
startDate: '',
endDate: '',
excludedDates: []
});
const selectedDates = ref<string[]>([]);
const excludedDates = ref<string[]>([]);
// 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
};
}
});