Add organizer-only attendee list to event detail view (011)
New GET /events/{token}/attendees endpoint returns attendee names when
a valid organizer token is provided (403 otherwise). The frontend
conditionally renders the list below the attendee count for organizers,
silently degrading for visitors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -54,6 +54,8 @@
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<AttendeeList v-if="isOrganizer && attendeeNames !== null" :attendees="attendeeNames" />
|
||||
|
||||
<div v-if="event.description" class="detail__section">
|
||||
<h2 class="detail__section-title">About</h2>
|
||||
<p class="detail__description">{{ event.description }}</p>
|
||||
@@ -111,6 +113,7 @@ import { ref, computed, onMounted } from 'vue'
|
||||
import { RouterLink, useRoute } from 'vue-router'
|
||||
import { api } from '@/api/client'
|
||||
import { useEventStorage } from '@/composables/useEventStorage'
|
||||
import AttendeeList from '@/components/AttendeeList.vue'
|
||||
import BottomSheet from '@/components/BottomSheet.vue'
|
||||
import RsvpBar from '@/components/RsvpBar.vue'
|
||||
import type { components } from '@/api/schema'
|
||||
@@ -132,6 +135,7 @@ const submitError = ref('')
|
||||
const submitting = ref(false)
|
||||
const rsvpName = ref<string | undefined>(undefined)
|
||||
const isOrganizer = ref(false)
|
||||
const attendeeNames = ref<string[] | null>(null)
|
||||
|
||||
const formattedDateTime = computed(() => {
|
||||
if (!event.value) return ''
|
||||
@@ -160,7 +164,13 @@ async function fetchEvent() {
|
||||
state.value = 'loaded'
|
||||
|
||||
// Check if current user is the organizer
|
||||
isOrganizer.value = !!getOrganizerToken(event.value.eventToken)
|
||||
const orgToken = getOrganizerToken(event.value.eventToken)
|
||||
isOrganizer.value = !!orgToken
|
||||
|
||||
// Fetch attendee list for organizer
|
||||
if (orgToken) {
|
||||
fetchAttendees(event.value.eventToken, orgToken)
|
||||
}
|
||||
|
||||
// Restore RSVP status from localStorage
|
||||
const stored = getRsvp(event.value.eventToken)
|
||||
@@ -220,6 +230,23 @@ async function submitRsvp() {
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchAttendees(eventToken: string, organizerToken: string) {
|
||||
try {
|
||||
const { data, error } = await api.GET('/events/{token}/attendees', {
|
||||
params: {
|
||||
path: { token: eventToken },
|
||||
query: { organizerToken },
|
||||
},
|
||||
})
|
||||
|
||||
if (!error) {
|
||||
attendeeNames.value = data!.attendees.map((a) => a.name)
|
||||
}
|
||||
} catch {
|
||||
// Silently degrade — don't show attendee list
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(fetchEvent)
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user