Files
crewli/apps/app/src/pages/events/index.vue

192 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { useEventList } from '@/composables/api/useEvents'
import { dutchPlural } from '@/lib/dutch-plural'
import { useAuthStore } from '@/stores/useAuthStore'
import CreateEventDialog from '@/components/events/CreateEventDialog.vue'
import type { EventStatus, EventItem } from '@/types/event'
const router = useRouter()
const authStore = useAuthStore()
const orgId = computed(() => authStore.currentOrganisation?.id ?? '')
const { data: events, isLoading, isError, refetch } = useEventList(orgId)
const isCreateDialogOpen = ref(false)
// Filter: only top-level events (no sub-events)
const topLevelEvents = computed(() =>
events.value?.filter(e => !e.is_sub_event) ?? [],
)
const statusColor: Record<EventStatus, string> = {
draft: 'default',
published: 'info',
registration_open: 'cyan',
buildup: 'warning',
showday: 'success',
teardown: 'warning',
closed: 'error',
}
const eventTypeColor: Record<string, string> = {
festival: 'purple',
series: 'info',
}
const dateFormatter = new Intl.DateTimeFormat('nl-NL', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
})
function formatDate(iso: string) {
return dateFormatter.format(new Date(iso))
}
function navigateToEvent(event: EventItem) {
router.push({ name: 'events-id', params: { id: event.id } })
}
</script>
<template>
<div>
<!-- No org selected -->
<VAlert
v-if="!orgId"
type="warning"
class="mb-4"
>
Selecteer eerst een organisatie.
<template #append>
<VBtn
variant="text"
:to="{ name: 'organisation' }"
>
Naar organisatie
</VBtn>
</template>
</VAlert>
<template v-else>
<div class="d-flex justify-space-between align-center mb-6">
<h4 class="text-h4">
Evenementen
</h4>
<VBtn
prepend-icon="tabler-plus"
@click="isCreateDialogOpen = true"
>
Nieuw aanmaken
</VBtn>
</div>
<!-- Loading -->
<VSkeletonLoader
v-if="isLoading"
type="card@4"
/>
<!-- Error -->
<VAlert
v-else-if="isError"
type="error"
class="mb-4"
>
Kon evenementen niet laden.
<template #append>
<VBtn
variant="text"
@click="refetch()"
>
Opnieuw proberen
</VBtn>
</template>
</VAlert>
<!-- Empty -->
<VCard
v-else-if="!topLevelEvents.length"
class="text-center pa-8"
>
<VIcon
icon="tabler-calendar-event"
size="48"
class="mb-4 text-disabled"
/>
<p class="text-body-1 text-disabled">
Nog geen evenementen. Maak je eerste evenement aan.
</p>
</VCard>
<!-- Event cards grid -->
<VRow v-else>
<VCol
v-for="event in topLevelEvents"
:key="event.id"
cols="12"
md="6"
>
<VCard
class="cursor-pointer"
hover
@click="navigateToEvent(event)"
>
<VCardText>
<div class="d-flex justify-space-between align-start mb-2">
<h5 class="text-h5">
{{ event.name }}
</h5>
<div class="d-flex gap-x-2">
<VChip
v-if="event.event_type === 'festival'"
color="purple"
size="small"
variant="tonal"
>
Festival
</VChip>
<VChip
v-else-if="event.event_type === 'series'"
color="info"
size="small"
variant="tonal"
>
Serie
</VChip>
<VChip
:color="statusColor[event.status]"
size="small"
>
{{ event.status }}
</VChip>
</div>
</div>
<p class="text-body-2 text-medium-emphasis mb-0">
{{ formatDate(event.start_date) }} {{ formatDate(event.end_date) }}
</p>
<p
v-if="event.children_count && event.children_count > 0"
class="text-body-2 text-medium-emphasis d-flex align-center gap-x-1 mt-1 mb-0"
>
<VIcon
icon="tabler-layout-grid"
size="16"
/>
{{ event.children_count }} {{ event.sub_event_label ? dutchPlural(event.sub_event_label).toLowerCase() : 'programmaonderdelen' }}
</p>
</VCardText>
</VCard>
</VCol>
</VRow>
<CreateEventDialog
v-model="isCreateDialogOpen"
:org-id="orgId"
/>
</template>
</div>
</template>