/** * DatePicker Component * * Beautiful mobile date picker with bottom sheet modal. * Features quick buttons (Heute, Gestern) and calendar grid. */ export default { name: 'DatePicker', emits: ['update:modelValue', 'close'], props: { modelValue: { type: String, default: null }, show: { type: Boolean, default: false } }, setup(props, { emit }) { const { ref, computed, watch } = Vue; // Current calendar view month/year const viewDate = ref(new Date()); // Initialize view date when opened watch(() => props.show, (newVal) => { if (newVal && props.modelValue) { viewDate.value = new Date(props.modelValue); } else if (newVal) { viewDate.value = new Date(); } }); // German weekday names (short) const weekDays = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So']; // German month names const monthNames = [ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember' ]; const shortMonthNames = [ 'Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez' ]; const weekDayNames = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa']; // Format date for display const formatDisplayDate = (dateStr) => { if (!dateStr) return 'Datum wählen'; const date = new Date(dateStr); const dayName = weekDayNames[date.getDay()]; const day = date.getDate(); const month = shortMonthNames[date.getMonth()]; const year = date.getFullYear(); return `${dayName}, ${day}. ${month} ${year}`; }; // Current month/year display const currentMonthYear = computed(() => { const month = monthNames[viewDate.value.getMonth()]; const year = viewDate.value.getFullYear(); return `${month} ${year}`; }); // Get calendar days for current view const calendarDays = computed(() => { const year = viewDate.value.getFullYear(); const month = viewDate.value.getMonth(); // First day of month const firstDay = new Date(year, month, 1); // Last day of month const lastDay = new Date(year, month + 1, 0); // Day of week for first day (0=Sun, convert to 0=Mon) let startDay = firstDay.getDay() - 1; if (startDay < 0) startDay = 6; const days = []; // Add empty slots for days before first of month for (let i = 0; i < startDay; i++) { days.push({ day: null, date: null }); } // Add days of month for (let d = 1; d <= lastDay.getDate(); d++) { const date = new Date(year, month, d); const dateStr = formatDateISO(date); days.push({ day: d, date: dateStr, isToday: isToday(date), isSelected: dateStr === props.modelValue }); } return days; }); // Check if date is today const isToday = (date) => { const today = new Date(); return date.toDateString() === today.toDateString(); }; // Format date as ISO string (YYYY-MM-DD) const formatDateISO = (date) => { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }; // Quick date helpers const getToday = () => formatDateISO(new Date()); const getYesterday = () => { const d = new Date(); d.setDate(d.getDate() - 1); return formatDateISO(d); }; // Navigation const prevMonth = () => { viewDate.value = new Date(viewDate.value.getFullYear(), viewDate.value.getMonth() - 1, 1); }; const nextMonth = () => { viewDate.value = new Date(viewDate.value.getFullYear(), viewDate.value.getMonth() + 1, 1); }; // Selection const selectDate = (dateStr) => { if (!dateStr) return; emit('update:modelValue', dateStr); emit('close'); }; const selectToday = () => selectDate(getToday()); const selectYesterday = () => selectDate(getYesterday()); const close = () => { emit('close'); }; return { viewDate, weekDays, currentMonthYear, calendarDays, formatDisplayDate, prevMonth, nextMonth, selectDate, selectToday, selectYesterday, close, getToday, getYesterday }; }, template: `

Datum wählen

{{ currentMonthYear }}
{{ day }}
` };