diff --git a/app/components/event/Editor.vue b/app/components/event/Editor.vue index e47ee29..1058cdd 100644 --- a/app/components/event/Editor.vue +++ b/app/components/event/Editor.vue @@ -10,6 +10,10 @@ const props = defineProps({ const emit = defineEmits(['save', 'delete']) +const editedEvent = ref({}) +const filesToUpload = ref([]) +// Build asset list for the uploader from the real event assets +const eventAssets = ref<{ imageUrl: string, isPreview?: boolean, fileName?: string }[]>([]) const editedEvent = ref({ name: '', date: '', @@ -17,14 +21,42 @@ const editedEvent = ref({ image: '', }) -// Watch for changes to the event prop and update the form watch(() => props.event, (newEvent) => { if (newEvent) { editedEvent.value = { ...newEvent } + // Map existing server assets to uploader format + // imageUrl in DB is just the fileName (after the upload fix) + eventAssets.value = (newEvent.eventAssets || []).map((a: any) => ({ + imageUrl: `/api/events/${newEvent.id}/images/${a.imageUrl}`, + fileName: a.imageUrl, + isPreview: false, + })) } }, { immediate: true }) -function saveEvent() { +function onFilesChanged(files: File[]) { + filesToUpload.value = files +} + +async function saveEvent() { + // Upload any pending files first + if (filesToUpload.value.length > 0) { + for (const file of filesToUpload.value) { + const formData = new FormData() + formData.append('file', file) + try { + await $fetch(`/api/events/${editedEvent.value.id}/images/upload`, { + method: 'POST', + body: formData, + }) + } + catch (err) { + console.error(`Failed to upload ${file.name}:`, err) + } + } + filesToUpload.value = [] + } + emit('save', { ...editedEvent.value }) } @@ -39,41 +71,69 @@ function deleteEvent() { Edit Event - - - + + + - + - - - - - - - - - - - -
-

- Image Preview: -

- Event preview + + + + + + + + + + +
+ + + + + +
+
+ + +
+ + + + +
+/** + * EventImageUpload + * + * Wraps Nuxt UI's UFileUpload for use in event forms. + * - Handles multiple image selection with drag & drop + * - Shows existing server images alongside new uploads + * - Supports deleting existing images from the server + */ + +interface ServerAsset { + imageUrl: string // just the fileName as stored in DB +} + +const props = defineProps<{ + // Existing saved assets from the server (pass event.eventAssets) + existingAssets?: ServerAsset[] + // The event ID, needed to build image URLs and delete from server + eventId?: string +}>() + +const emit = defineEmits<{ + // Emits the raw File[] whenever selection changes, for parent to upload on save + (e: 'filesChanged', files: File[]): void + // Emits when an existing server image is deleted + (e: 'assetDeleted', imageUrl: string): void +}>() + +// Files selected by the user (not yet uploaded) +const selectedFiles = ref([]) + +// Track which existing assets are still present +const remainingAssets = ref([...(props.existingAssets || [])]) + +watch(() => props.existingAssets, (assets) => { + remainingAssets.value = [...(assets || [])] +}, { deep: true }) + +function onFilesChanged(files: File[] | null | undefined) { + const safeFiles = files ?? [] + selectedFiles.value = safeFiles + emit('filesChanged', safeFiles) +} + +function getAssetUrl(asset: ServerAsset) { + return `/api/events/${asset.imageUrl}` +} + +async function deleteExistingAsset(asset: ServerAsset) { + if (!props.eventId) return + + try { + await $fetch(getAssetUrl(asset), { + method: 'DELETE', + }) + remainingAssets.value = remainingAssets.value.filter(a => a.imageUrl !== asset.imageUrl) + emit('assetDeleted', asset.imageUrl) + } + catch (err) { + console.error('Failed to delete image:', err) + } +} + + + diff --git a/app/components/event/Modal.vue b/app/components/event/Modal.vue index 415f2ff..5d66dab 100644 --- a/app/components/event/Modal.vue +++ b/app/components/event/Modal.vue @@ -1,6 +1,4 @@ - + + diff --git a/app/components/event/RSVPStats.vue b/app/components/event/RSVPStats.vue new file mode 100644 index 0000000..0bbbbf8 --- /dev/null +++ b/app/components/event/RSVPStats.vue @@ -0,0 +1,148 @@ + + + diff --git a/app/components/event/Tile.vue b/app/components/event/Tile.vue index f271ab4..eb0b8e7 100644 --- a/app/components/event/Tile.vue +++ b/app/components/event/Tile.vue @@ -1,12 +1,11 @@