diff --git a/src/modules/events/components/EventCalendarPopup.vue b/src/modules/events/components/EventCalendarPopup.vue new file mode 100644 index 0000000..9a16173 --- /dev/null +++ b/src/modules/events/components/EventCalendarPopup.vue @@ -0,0 +1,49 @@ + + + + + + + {{ title }} + {{ description }} + + + + + diff --git a/src/modules/events/components/EventCalendarView.vue b/src/modules/events/components/EventCalendarView.vue index c77b908..f0a70c8 100644 --- a/src/modules/events/components/EventCalendarView.vue +++ b/src/modules/events/components/EventCalendarView.vue @@ -12,6 +12,10 @@ import type { Event } from '../types/event' const props = defineProps<{ events: Event[] + /** When true, render only the month grid for date-picking — no + * selected-day events panel — and emit selectDate on every day tap + * (used inside the calendar popup). */ + pickerMode?: boolean }>() const emit = defineEmits<{ @@ -77,6 +81,12 @@ const selectedDayEvents = computed(() => { }) function selectDay(date: Date) { + // Picker mode: every tap selects + emits (parent closes the popup). + if (props.pickerMode) { + selectedDay.value = date + emit('selectDate', date) + return + } if (selectedDay.value && isSameDay(selectedDay.value, date)) { selectedDay.value = null } else { @@ -97,7 +107,7 @@ function nextMonth() { - + @@ -125,7 +135,7 @@ function nextMonth() { + + {{ format(selectedDay, 'EEEE, MMMM d', { locale: dateLocale }) }} diff --git a/src/modules/events/composables/useEventFilters.ts b/src/modules/events/composables/useEventFilters.ts index 8742cd1..38eb9ce 100644 --- a/src/modules/events/composables/useEventFilters.ts +++ b/src/modules/events/composables/useEventFilters.ts @@ -15,6 +15,10 @@ import { DEFAULT_FILTERS } from '../types/filters' // tapping Hosting toggled a private ref the page never saw. const temporal = ref(DEFAULT_FILTERS.temporal) const selectedCategories = ref([]) +// A specific day picked from the calendar popup. When set it takes +// priority over the temporal pills + past/upcoming split (browse any +// single day). Cleared independently of categories. +const selectedDate = ref(undefined) const onlyOwnedTickets = ref(false) const onlyHosting = ref(false) const showPast = ref(false) @@ -35,20 +39,31 @@ export function useEventFilters() { function applyFilters(events: Event[]): Event[] { let result = events - // Temporal filter (preset pills). Specific-date browsing now lives on - // the calendar page, so the feed only narrows by these windows. - result = applyTemporalFilter(result, temporal.value) + if (selectedDate.value) { + // Specific day picked from the calendar popup — takes priority over + // the temporal pills and bypasses the past/upcoming split so any + // day (past or future) can be browsed. + const dayStart = startOfDay(selectedDate.value) + const dayEnd = endOfDay(selectedDate.value) + result = result.filter(a => { + const eventEnd = a.endDate ?? a.startDate + return a.startDate <= dayEnd && eventEnd >= dayStart + }) + } else { + // Temporal filter (preset pills). + result = applyTemporalFilter(result, temporal.value) - // Past/upcoming split — the chip narrows to one side of "now", - // mirroring the "My tickets" / "Hosting" mental model. Default - // (showPast=false) is upcoming-only; toggling on flips to past-only. - // Composes with temporal pills: "This Week" + showPast=true shows - // only the days already passed this week. - const now = new Date() - result = result.filter(a => { - const eventEnd = a.endDate ?? a.startDate - return showPast.value ? eventEnd < now : eventEnd >= now - }) + // Past/upcoming split — the chip narrows to one side of "now", + // mirroring the "My tickets" / "Hosting" mental model. Default + // (showPast=false) is upcoming-only; toggling on flips to + // past-only. Composes with temporal pills: "This Week" + + // showPast=true shows only the days already passed this week. + const now = new Date() + result = result.filter(a => { + const eventEnd = a.endDate ?? a.startDate + return showPast.value ? eventEnd < now : eventEnd >= now + }) + } // Category filter if (selectedCategories.value.length > 0) { @@ -69,6 +84,16 @@ export function useEventFilters() { function setTemporal(value: TemporalFilter) { temporal.value = value + selectedDate.value = undefined // a preset pill clears the day pick + } + + function selectDate(date: Date) { + selectedDate.value = date + temporal.value = 'all' // a specific day overrides the temporal pill + } + + function clearSelectedDate() { + selectedDate.value = undefined } function toggleCategory(category: EventCategory) { @@ -87,6 +112,7 @@ export function useEventFilters() { function resetFilters() { temporal.value = DEFAULT_FILTERS.temporal selectedCategories.value = [] + selectedDate.value = undefined onlyOwnedTickets.value = false onlyHosting.value = false showPast.value = false @@ -107,6 +133,7 @@ export function useEventFilters() { const hasActiveFilters = computed(() => temporal.value !== 'all' || selectedCategories.value.length > 0 || + selectedDate.value !== undefined || onlyOwnedTickets.value || onlyHosting.value || showPast.value @@ -116,6 +143,7 @@ export function useEventFilters() { // State temporal, selectedCategories, + selectedDate, onlyOwnedTickets, onlyHosting, showPast, @@ -125,6 +153,8 @@ export function useEventFilters() { // Actions applyFilters, setTemporal, + selectDate, + clearSelectedDate, toggleCategory, clearCategories, toggleOwnedTickets, diff --git a/src/modules/events/index.ts b/src/modules/events/index.ts index df67f58..e592b7e 100644 --- a/src/modules/events/index.ts +++ b/src/modules/events/index.ts @@ -33,15 +33,6 @@ export const eventsModule = createModulePlugin({ requiresAuth: false, }, }, - { - path: '/events/calendar', - name: 'events-calendar', - component: () => import('./views/EventsCalendarPage.vue'), - meta: { - title: 'Calendar', - requiresAuth: false, - }, - }, { path: '/events/map', name: 'events-map', diff --git a/src/modules/events/views/EventsCalendarPage.vue b/src/modules/events/views/EventsCalendarPage.vue deleted file mode 100644 index 6826125..0000000 --- a/src/modules/events/views/EventsCalendarPage.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - {{ t('common.nav.back', 'Back') }} - - - - - - - - {{ t('events.filters.myTickets', 'My tickets') }} - - - - - diff --git a/src/modules/events/views/EventsPage.vue b/src/modules/events/views/EventsPage.vue index 8d9c20b..121941e 100644 --- a/src/modules/events/views/EventsPage.vue +++ b/src/modules/events/views/EventsPage.vue @@ -1,6 +1,6 @@ @@ -161,15 +183,16 @@ function openCalendar() { @toggle-past="togglePast" /> - + @@ -183,6 +206,23 @@ function openCalendar() { + + + + + {{ selectedDateLabel }} + + + + + diff --git a/src/modules/events/views/MyTicketsPage.vue b/src/modules/events/views/MyTicketsPage.vue index 5ddaea9..b21312c 100644 --- a/src/modules/events/views/MyTicketsPage.vue +++ b/src/modules/events/views/MyTicketsPage.vue @@ -1,6 +1,6 @@