From f44c3827b1ea4c576c343f3ad77bdef058a06103 Mon Sep 17 00:00:00 2001 From: Padreug Date: Mon, 27 Apr 2026 18:13:53 +0200 Subject: [PATCH] feat: use propose endpoint for user event creation Replace CreateActivityDialog (direct Nostr publish) with CreateEventDialog (LNbits propose flow) on ActivitiesPage. Users submit events via POST /events/propose with invoice key. Admin reviews and approves before events go live. Add proposeEvent() to TicketApiService for invoice-key auth. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../activities/services/TicketApiService.ts | 16 +++++++++++- .../activities/views/ActivitiesPage.vue | 25 +++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/modules/activities/services/TicketApiService.ts b/src/modules/activities/services/TicketApiService.ts index 918b0c3..2ecbdc5 100644 --- a/src/modules/activities/services/TicketApiService.ts +++ b/src/modules/activities/services/TicketApiService.ts @@ -134,7 +134,7 @@ export class TicketApiService { } /** - * Create a new ticketed event in LNbits. + * Create a new ticketed event in LNbits (admin). */ async createEvent(eventData: CreateEventRequest, adminKey: string): Promise { return this.request('/events/api/v1/events', { @@ -147,6 +147,20 @@ export class TicketApiService { }) } + /** + * Propose a new event for admin approval (any user with invoice key). + */ + async proposeEvent(eventData: CreateEventRequest, invoiceKey: string): Promise { + return this.request('/events/api/v1/events/propose', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-API-KEY': invoiceKey, + }, + body: JSON.stringify(eventData), + }) + } + /** * Fetch available currencies from LNbits. */ diff --git a/src/modules/activities/views/ActivitiesPage.vue b/src/modules/activities/views/ActivitiesPage.vue index 216b601..bee4edf 100644 --- a/src/modules/activities/views/ActivitiesPage.vue +++ b/src/modules/activities/views/ActivitiesPage.vue @@ -11,7 +11,10 @@ import { import { RefreshCw, SlidersHorizontal, ChevronDown, Plus } from 'lucide-vue-next' import { useAuth } from '@/composables/useAuthService' import { useActivities } from '../composables/useActivities' -import CreateActivityDialog from '../components/CreateActivityDialog.vue' +import CreateEventDialog from '../components/CreateEventDialog.vue' +import { injectService, SERVICE_TOKENS } from '@/core/di-container' +import type { TicketApiService } from '../services/TicketApiService' +import type { CreateEventRequest } from '../types/ticket' import ActivitySearchOverlay from '../components/ActivitySearchOverlay.vue' import TemporalFilterBar from '../components/TemporalFilterBar.vue' import CategoryFilterBar from '../components/CategoryFilterBar.vue' @@ -55,6 +58,16 @@ function handleSelectActivity(activity: Activity) { function handleRefresh() { refresh() } + +async function handleCreateEvent(eventData: CreateEventRequest) { + const ticketApi = injectService(SERVICE_TOKENS.TICKET_API) as TicketApiService + const { currentUser } = useAuth() + const invoiceKey = currentUser.value?.wallets?.[0]?.inkey + if (!invoiceKey) { + throw new Error('No wallet available. Please log in first.') + } + await ticketApi.proposeEvent(eventData, invoiceKey) +}