From 8b03b89b566d79b90678de92f2fadc3f10bf70a2 Mon Sep 17 00:00:00 2001 From: Padreug Date: Tue, 16 Jun 2026 01:11:00 +0200 Subject: [PATCH 01/10] feat(events): add upcoming/past toggle to My Tickets My Tickets listed every ticket with no way to separate events that already happened. Add an Upcoming/Past segmented toggle (defaults to upcoming) that filters the grouped tickets by their event's date, with the tab counts (All/Paid/Pending/Registered) derived from the visible set so badges match what's shown. Events not yet resolved from relays stay visible under Upcoming until their date is known. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/modules/events/views/MyTicketsPage.vue | 85 +++++++++++++++++----- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/src/modules/events/views/MyTicketsPage.vue b/src/modules/events/views/MyTicketsPage.vue index 5ddaea9..d394a2e 100644 --- a/src/modules/events/views/MyTicketsPage.vue +++ b/src/modules/events/views/MyTicketsPage.vue @@ -1,5 +1,5 @@ From ccaaa6a6c51bb2ab4a033053e24cde3e9a7e18c2 Mon Sep 17 00:00:00 2001 From: Padreug Date: Tue, 16 Jun 2026 12:29:24 +0200 Subject: [PATCH 08/10] refactor(events): remove the standalone calendar page The calendar is now a date-picker popup on the feed (and, next, a visual on My Tickets), so the dedicated /events/calendar page and route are no longer needed. Delete EventsCalendarPage.vue, drop its route, and update the stale openCreate comment. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/modules/events/index.ts | 9 --- .../events/views/EventsCalendarPage.vue | 70 ------------------- src/modules/events/views/EventsPage.vue | 6 +- 3 files changed, 2 insertions(+), 83 deletions(-) delete mode 100644 src/modules/events/views/EventsCalendarPage.vue 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 9040fcd..0000000 --- a/src/modules/events/views/EventsCalendarPage.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - diff --git a/src/modules/events/views/EventsPage.vue b/src/modules/events/views/EventsPage.vue index eabda4f..9cb625c 100644 --- a/src/modules/events/views/EventsPage.vue +++ b/src/modules/events/views/EventsPage.vue @@ -84,10 +84,8 @@ function handleSelectEvent(event: Event) { router.push({ name: 'event-detail', params: { id: event.id } }) } -// Create-activity CTA in the Hosting view. Calendar-tab → page lives -// on /events/calendar; the icon button at the end of the date -// strip is the only entry point now that the bottom-nav Calendar -// tab is gone. +// Create-activity CTA in the Hosting view. Replaces the old bottom-nav +// Create entry; shown only while the Hosting filter is active. function openCreate() { eventsStore.editingEvent = null eventsStore.showCreateDialog = true From a6dee2992284c2a1f674b9d71828af5b69cc73de Mon Sep 17 00:00:00 2001 From: Padreug Date: Tue, 16 Jun 2026 12:32:11 +0200 Subject: [PATCH 09/10] feat(events): add calendar date visual to My Tickets Replaces the My-tickets filter that lived on the removed calendar page. A calendar button opens the date-picker popup with per-day dots over the user's own events; picking a day filters the ticket list to it (a removable date chip overrides the upcoming/past toggle while active). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/modules/events/views/MyTicketsPage.vue | 114 +++++++++++++++++---- 1 file changed, 96 insertions(+), 18 deletions(-) diff --git a/src/modules/events/views/MyTicketsPage.vue b/src/modules/events/views/MyTicketsPage.vue index 94e851f..de9ae09 100644 --- a/src/modules/events/views/MyTicketsPage.vue +++ b/src/modules/events/views/MyTicketsPage.vue @@ -10,10 +10,14 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { ScrollArea } from '@/components/ui/scroll-area' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' -import { format } from 'date-fns' -import { Ticket, User, CreditCard, CheckCircle, Clock, AlertCircle, ChevronLeft, ChevronRight } from 'lucide-vue-next' +import { format, startOfDay, endOfDay } from 'date-fns' +import { Ticket, User, CreditCard, CheckCircle, Clock, AlertCircle, ChevronLeft, ChevronRight, CalendarDays, X } from 'lucide-vue-next' +import EventCalendarPopup from '../components/EventCalendarPopup.vue' +import { useDateLocale } from '../composables/useDateLocale' +import type { Event } from '../types/event' const { isAuthenticated, userDisplay } = useAuth() +const { dateLocale } = useDateLocale() const { tickets, groupedTickets, @@ -50,10 +54,47 @@ function isGroupPast(eventId: string): boolean { return end < new Date() } -const visibleGroups = computed(() => - groupedTickets.value.filter(g => isGroupPast(g.eventId) === showPast.value), +// Calendar popup: visualise the days the user has events. Picking a day +// filters the ticket list to it (overriding the upcoming/past toggle); +// clearing it returns to the toggle. +const calendarOpen = ref(false) +const selectedDay = ref(null) + +// The user's events (resolved from their ticket groups) — feeds the +// calendar popup's per-day dots. +const myEvents = computed(() => { + const out: Event[] = [] + for (const g of groupedTickets.value) { + const ev = eventsStore.getEventById(g.eventId) + if (ev) out.push(ev) + } + return out +}) + +const selectedDayLabel = computed(() => + selectedDay.value + ? format(selectedDay.value, 'EEE, MMM d', { locale: dateLocale.value }) + : '', ) +function isGroupOnDay(eventId: string, day: Date): boolean { + const ev = eventsStore.getEventById(eventId) + if (!ev) return false + const end = ev.endDate ?? ev.startDate + return ev.startDate <= endOfDay(day) && end >= startOfDay(day) +} + +function onSelectDay(date: Date) { + selectedDay.value = date +} + +const visibleGroups = computed(() => { + if (selectedDay.value) { + return groupedTickets.value.filter(g => isGroupOnDay(g.eventId, selectedDay.value!)) + } + return groupedTickets.value.filter(g => isGroupPast(g.eventId) === showPast.value) +}) + // Tab counts derived from the visible (past/upcoming-filtered) groups so // the badges match what's actually shown. const visibleCounts = computed(() => { @@ -205,25 +246,52 @@ onMounted(async () => {
- -
+ +
+
+ + +
@@ -239,7 +307,7 @@ onMounted(async () => {
- {{ showPast ? 'No past tickets' : 'No upcoming tickets' }} + {{ selectedDay ? 'No tickets on this day' : (showPast ? 'No past tickets' : 'No upcoming tickets') }}
@@ -414,5 +482,15 @@ onMounted(async () => {
+ + +
From 8339cd127200a8a390065242529bff2e046fb36f Mon Sep 17 00:00:00 2001 From: Padreug Date: Tue, 16 Jun 2026 12:55:33 +0200 Subject: [PATCH 10/10] fix(events): close calendar popup on route leave Defensive guard so the date-picker popup can never linger across navigation (reported: it appeared open on the feed after returning from an event detail page). Force calendarOpen=false in onBeforeRouteLeave on both the feed and My Tickets, the two popup hosts. Modals shouldn't survive a route change regardless of how the close/navigation interleave. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/modules/events/views/EventsPage.vue | 9 ++++++++- src/modules/events/views/MyTicketsPage.vue | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/modules/events/views/EventsPage.vue b/src/modules/events/views/EventsPage.vue index 9cb625c..121941e 100644 --- a/src/modules/events/views/EventsPage.vue +++ b/src/modules/events/views/EventsPage.vue @@ -1,6 +1,6 @@