Files
band-management/apps/admin/src/pages/events/[id]/edit.vue
bert.hausmans 1cb7674d52 refactor: align codebase with EventCrew domain and trim legacy band stack
- Update API: events, users, policies, routes, resources, migrations
- Remove deprecated models/resources (customers, setlists, invitations, etc.)
- Refresh admin app and docs; remove apps/band

Made-with: Cursor
2026-03-29 23:19:06 +02:00

193 lines
5.0 KiB
Vue

<script setup lang="ts">
import { useEvents } from '@/composables/useEvents'
import { useRoute, useRouter } from 'vue-router'
import type { EventCrewEventStatus, UpdateEventData } from '@/types/events'
definePage({
meta: {
navActiveLink: 'events',
},
})
const route = useRoute()
const router = useRouter()
const { currentEvent, fetchEvent, updateEvent, isLoading } = useEvents()
const eventId = computed(() => route.params.id as string)
const formData = ref<UpdateEventData>({})
const statusOptions: { title: string; value: EventCrewEventStatus }[] = [
{ title: 'Draft', value: 'draft' },
{ title: 'Published', value: 'published' },
{ title: 'Registration open', value: 'registration_open' },
{ title: 'Build-up', value: 'buildup' },
{ title: 'Show day', value: 'showday' },
{ title: 'Teardown', value: 'teardown' },
{ title: 'Closed', value: 'closed' },
]
const errors = ref<Record<string, string>>({})
watch(() => eventId.value, async () => {
if (!eventId.value) {
return
}
await fetchEvent(eventId.value)
if (currentEvent.value) {
const e = currentEvent.value
formData.value = {
name: e.name,
slug: e.slug,
start_date: e.start_date,
end_date: e.end_date,
timezone: e.timezone,
status: e.status,
}
}
}, { immediate: true })
function flattenValidationErrors(raw: Record<string, string[] | string>): Record<string, string> {
const out: Record<string, string> = {}
for (const [key, val] of Object.entries(raw)) {
out[key] = Array.isArray(val) ? val[0]! : val
}
return out
}
async function handleSubmit() {
errors.value = {}
try {
await updateEvent(eventId.value, formData.value)
await router.push(`/events/${eventId.value}`)
}
catch (err: unknown) {
const ax = err as { response?: { data?: { errors?: Record<string, string[] | string>; message?: string } } }
if (ax.response?.data?.errors) {
errors.value = flattenValidationErrors(ax.response.data.errors)
}
else {
errors.value._general = ax.response?.data?.message ?? (err instanceof Error ? err.message : 'Failed to update event')
}
}
}
</script>
<template>
<div>
<VCard v-if="currentEvent">
<VCardTitle class="d-flex align-center gap-2">
<VIcon icon="tabler-arrow-left" />
<RouterLink
:to="`/events/${eventId}`"
class="text-decoration-none"
>
Back to Event
</RouterLink>
</VCardTitle>
<VDivider />
<VCardText>
<VForm @submit.prevent="handleSubmit">
<VRow>
<VCol cols="12">
<AppTextField
v-model="formData.name"
label="Name"
:error-messages="errors.name"
required
/>
</VCol>
<VCol cols="12">
<AppTextField
v-model="formData.slug"
label="Slug"
:error-messages="errors.slug"
required
/>
</VCol>
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="formData.start_date"
label="Start date"
type="date"
:error-messages="errors.start_date"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="formData.end_date"
label="End date"
type="date"
:error-messages="errors.end_date"
/>
</VCol>
<VCol cols="12">
<AppTextField
v-model="formData.timezone"
label="Timezone"
:error-messages="errors.timezone"
/>
</VCol>
<VCol cols="12">
<AppSelect
v-model="formData.status"
label="Status"
:items="statusOptions"
:error-messages="errors.status"
/>
</VCol>
<VCol cols="12">
<VAlert
v-if="errors._general"
type="error"
class="mb-4"
>
{{ errors._general }}
</VAlert>
<div class="d-flex gap-4">
<VBtn
type="submit"
color="primary"
:loading="isLoading"
>
Save
</VBtn>
<VBtn
variant="tonal"
:to="`/events/${eventId}`"
>
Cancel
</VBtn>
</div>
</VCol>
</VRow>
</VForm>
</VCardText>
</VCard>
<VCard v-else-if="isLoading">
<VCardText class="text-center py-12">
<VProgressCircular
indeterminate
color="primary"
/>
</VCardText>
</VCard>
</div>
</template>