diff --git a/src/modules/activities/components/CreateEventDialog.vue b/src/modules/activities/components/CreateEventDialog.vue index 5f3a605..2a9861a 100644 --- a/src/modules/activities/components/CreateEventDialog.vue +++ b/src/modules/activities/components/CreateEventDialog.vue @@ -41,6 +41,8 @@ import { import { Calendar, Loader2, ChevronDown, MapPin } from 'lucide-vue-next' import { toastService } from '@/core/services/ToastService' import { injectService, SERVICE_TOKENS } from '@/core/di-container' +import ImageUpload from '@/modules/base/components/ImageUpload.vue' +import type { ImageUploadService, UploadedImage } from '@/modules/base/services/ImageUploadService' import type { TicketApiService } from '../services/TicketApiService' import type { CreateEventRequest } from '../types/ticket' import { ALL_CATEGORIES } from '../types/category' @@ -66,7 +68,6 @@ const formSchema = toTypedSchema(z.object({ event_end_date: z.string().optional().default(''), event_end_time: z.string().optional().default(''), location: z.string().max(500).optional().default(''), - banner: z.string().optional().default(''), currency: z.string().default("sat"), amount_tickets: z.number().min(0).max(100000).default(0), price_per_ticket: z.number().min(0).default(0), @@ -82,13 +83,17 @@ const form = useForm({ event_end_date: '', event_end_time: '', location: '', - banner: '', currency: 'sat', amount_tickets: 0, price_per_ticket: 0, } }) +interface BannerImage extends UploadedImage { + isPrimary: boolean +} +const bannerImages = ref([]) + // Fold a date input ("YYYY-MM-DD") and an optional time input ("HH:MM") // into the events-extension wire format: date-only when no time given, // ISO 8601 datetime otherwise. The publisher switches NIP-52 kinds on @@ -100,6 +105,7 @@ function foldDateTime(date: string, time: string): string { const paymentService = injectService(SERVICE_TOKENS.PAYMENT_SERVICE) const ticketApi = injectService(SERVICE_TOKENS.TICKET_API) as TicketApiService | null +const imageService = injectService(SERVICE_TOKENS.IMAGE_UPLOAD_SERVICE) const availableCurrencies = ref(['sat']) const loadingCurrencies = ref(false) @@ -173,7 +179,9 @@ const onSubmit = form.handleSubmit(async (formValues) => { ) } if (formValues.location) eventData.location = formValues.location - if (formValues.banner) eventData.banner = formValues.banner + if (bannerImages.value.length > 0) { + eventData.banner = imageService.getImageUrl(bannerImages.value[0].alias) + } if (formValues.currency) eventData.currency = formValues.currency if (formValues.amount_tickets) eventData.amount_tickets = formValues.amount_tickets if (formValues.price_per_ticket) eventData.price_per_ticket = formValues.price_per_ticket @@ -183,6 +191,7 @@ const onSubmit = form.handleSubmit(async (formValues) => { toastService.success('Event submitted!') resetForm() selectedCategories.value = [] + bannerImages.value = [] emit('update:open', false) emit('event-created') } catch (error) { @@ -197,6 +206,7 @@ const handleOpenChange = (open: boolean) => { if (!open && !isLoading.value) { resetForm() selectedCategories.value = [] + bannerImages.value = [] } emit('update:open', open) } @@ -296,16 +306,26 @@ const handleOpenChange = (open: boolean) => { - - - - Image URL - - - - - - + +
+

Banner image

+

+ One poster image. Auto-resized to 1920px max edge and re-encoded as WebP. +

+ +