feat(events): add reusable calendar date-picker popup
Add a pickerMode to EventCalendarView (month grid only, emits selectDate on every day tap, no selected-day events panel) and a new EventCalendarPopup dialog wrapping it. Picking a day emits the date and closes. Groundwork for replacing the standalone calendar page with an on-feed date-picker popup and a My-Tickets event-date visual. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8c9a8ab945
commit
f7642db611
2 changed files with 62 additions and 2 deletions
49
src/modules/events/components/EventCalendarPopup.vue
Normal file
49
src/modules/events/components/EventCalendarPopup.vue
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
} from '@/components/ui/dialog'
|
||||
import EventCalendarView from './EventCalendarView.vue'
|
||||
import type { Event } from '../types/event'
|
||||
|
||||
// A date-picker popup: the month grid (with per-day event dots) in a
|
||||
// dialog. Picking a day emits selectDate and closes. Reused by the feed
|
||||
// (filter to a day) and My Tickets (visualise the user's event dates).
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
events: Event[]
|
||||
title: string
|
||||
description: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:open': [value: boolean]
|
||||
selectDate: [date: Date]
|
||||
}>()
|
||||
|
||||
const isOpen = computed({
|
||||
get: () => props.open,
|
||||
set: (v) => emit('update:open', v),
|
||||
})
|
||||
|
||||
function onSelectDate(date: Date) {
|
||||
emit('selectDate', date)
|
||||
isOpen.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:open="isOpen">
|
||||
<DialogContent class="max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{{ title }}</DialogTitle>
|
||||
<DialogDescription>{{ description }}</DialogDescription>
|
||||
</DialogHeader>
|
||||
<EventCalendarView :events="events" picker-mode @select-date="onSelectDate" />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
|
@ -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 {
|
||||
|
|
@ -147,8 +157,9 @@ function nextMonth() {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Selected day events -->
|
||||
<div v-if="selectedDay" class="border-t pt-4 space-y-2">
|
||||
<!-- Selected day events (hidden in picker mode — the popup just
|
||||
picks a day and closes). -->
|
||||
<div v-if="selectedDay && !pickerMode" class="border-t pt-4 space-y-2">
|
||||
<h3 class="text-sm font-medium text-muted-foreground">
|
||||
{{ format(selectedDay, 'EEEE, MMMM d', { locale: dateLocale }) }}
|
||||
<span v-if="selectedDayEvents.length > 0" class="ml-1">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue