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
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { useEvents } from '@/composables/useEvents'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import type { UpdateEventData } from '@/types/events'
|
||||
import type { EventCrewEventStatus, UpdateEventData } from '@/types/events'
|
||||
|
||||
definePage({
|
||||
meta: {
|
||||
@@ -17,62 +17,57 @@ const eventId = computed(() => route.params.id as string)
|
||||
|
||||
const formData = ref<UpdateEventData>({})
|
||||
|
||||
const statusOptions = [
|
||||
const statusOptions: { title: string; value: EventCrewEventStatus }[] = [
|
||||
{ title: 'Draft', value: 'draft' },
|
||||
{ title: 'Pending', value: 'pending' },
|
||||
{ title: 'Confirmed', value: 'confirmed' },
|
||||
{ title: 'Completed', value: 'completed' },
|
||||
{ title: 'Cancelled', value: 'cancelled' },
|
||||
]
|
||||
|
||||
const visibilityOptions = [
|
||||
{ title: 'Private', value: 'private' },
|
||||
{ title: 'Members', value: 'members' },
|
||||
{ title: 'Public', value: 'public' },
|
||||
{ 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>>({})
|
||||
|
||||
// Load event data
|
||||
watch(() => eventId.value, async () => {
|
||||
if (eventId.value) {
|
||||
await fetchEvent(eventId.value)
|
||||
if (currentEvent.value) {
|
||||
formData.value = {
|
||||
title: currentEvent.value.title,
|
||||
description: currentEvent.value.description || '',
|
||||
event_date: currentEvent.value.event_date,
|
||||
start_time: currentEvent.value.start_time,
|
||||
end_time: currentEvent.value.end_time || '',
|
||||
load_in_time: currentEvent.value.load_in_time || '',
|
||||
soundcheck_time: currentEvent.value.soundcheck_time || '',
|
||||
location_id: currentEvent.value.location?.id || '',
|
||||
customer_id: currentEvent.value.customer?.id || '',
|
||||
setlist_id: currentEvent.value.setlist?.id || '',
|
||||
fee: currentEvent.value.fee || undefined,
|
||||
currency: currentEvent.value.currency,
|
||||
status: currentEvent.value.status,
|
||||
visibility: currentEvent.value.visibility,
|
||||
rsvp_deadline: currentEvent.value.rsvp_deadline || '',
|
||||
notes: currentEvent.value.notes || '',
|
||||
internal_notes: currentEvent.value.internal_notes || '',
|
||||
is_public_setlist: currentEvent.value.is_public_setlist,
|
||||
}
|
||||
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)
|
||||
router.push(`/events/${eventId.value}`)
|
||||
} catch (err: any) {
|
||||
if (err.response?.data?.errors) {
|
||||
errors.value = err.response.data.errors
|
||||
} else {
|
||||
errors.value._general = err.message || 'Failed to update event'
|
||||
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')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,20 +93,19 @@ async function handleSubmit() {
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<AppTextField
|
||||
v-model="formData.title"
|
||||
label="Title"
|
||||
placeholder="Event Title"
|
||||
:error-messages="errors.title"
|
||||
v-model="formData.name"
|
||||
label="Name"
|
||||
:error-messages="errors.name"
|
||||
required
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<AppTextarea
|
||||
v-model="formData.description"
|
||||
label="Description"
|
||||
placeholder="Event Description"
|
||||
rows="3"
|
||||
<AppTextField
|
||||
v-model="formData.slug"
|
||||
label="Slug"
|
||||
:error-messages="errors.slug"
|
||||
required
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
@@ -120,11 +114,10 @@ async function handleSubmit() {
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="formData.event_date"
|
||||
label="Event Date"
|
||||
v-model="formData.start_date"
|
||||
label="Start date"
|
||||
type="date"
|
||||
:error-messages="errors.event_date"
|
||||
required
|
||||
:error-messages="errors.start_date"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
@@ -133,126 +126,27 @@ async function handleSubmit() {
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="formData.start_time"
|
||||
label="Start Time"
|
||||
type="time"
|
||||
:error-messages="errors.start_time"
|
||||
required
|
||||
v-model="formData.end_date"
|
||||
label="End date"
|
||||
type="date"
|
||||
:error-messages="errors.end_date"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VCol cols="12">
|
||||
<AppTextField
|
||||
v-model="formData.end_time"
|
||||
label="End Time"
|
||||
type="time"
|
||||
v-model="formData.timezone"
|
||||
label="Timezone"
|
||||
:error-messages="errors.timezone"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="formData.load_in_time"
|
||||
label="Load-in Time"
|
||||
type="time"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="formData.soundcheck_time"
|
||||
label="Soundcheck Time"
|
||||
type="time"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model="formData.rsvp_deadline"
|
||||
label="RSVP Deadline"
|
||||
type="datetime-local"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppTextField
|
||||
v-model.number="formData.fee"
|
||||
label="Fee"
|
||||
type="number"
|
||||
step="0.01"
|
||||
prefix="€"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppSelect
|
||||
v-model="formData.currency"
|
||||
label="Currency"
|
||||
:items="[{ title: 'EUR', value: 'EUR' }, { title: 'USD', value: 'USD' }]"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VCol cols="12">
|
||||
<AppSelect
|
||||
v-model="formData.status"
|
||||
label="Status"
|
||||
:items="statusOptions"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<AppSelect
|
||||
v-model="formData.visibility"
|
||||
label="Visibility"
|
||||
:items="visibilityOptions"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<AppTextarea
|
||||
v-model="formData.notes"
|
||||
label="Notes"
|
||||
placeholder="Public notes"
|
||||
rows="3"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<AppTextarea
|
||||
v-model="formData.internal_notes"
|
||||
label="Internal Notes"
|
||||
placeholder="Private notes (only visible to admins)"
|
||||
rows="3"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<VCheckbox
|
||||
v-model="formData.is_public_setlist"
|
||||
label="Public Setlist"
|
||||
:error-messages="errors.status"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
@@ -271,11 +165,10 @@ async function handleSubmit() {
|
||||
color="primary"
|
||||
:loading="isLoading"
|
||||
>
|
||||
Update Event
|
||||
Save
|
||||
</VBtn>
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
:to="`/events/${eventId}`"
|
||||
>
|
||||
Cancel
|
||||
@@ -287,7 +180,7 @@ async function handleSubmit() {
|
||||
</VCardText>
|
||||
</VCard>
|
||||
|
||||
<VCard v-else>
|
||||
<VCard v-else-if="isLoading">
|
||||
<VCardText class="text-center py-12">
|
||||
<VProgressCircular
|
||||
indeterminate
|
||||
@@ -297,4 +190,3 @@ async function handleSubmit() {
|
||||
</VCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user