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) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-04-27 18:13:53 +02:00
commit f44c3827b1
2 changed files with 35 additions and 6 deletions

View file

@ -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<TicketedEvent> { async createEvent(eventData: CreateEventRequest, adminKey: string): Promise<TicketedEvent> {
return this.request('/events/api/v1/events', { 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<TicketedEvent> {
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. * Fetch available currencies from LNbits.
*/ */

View file

@ -11,7 +11,10 @@ import {
import { RefreshCw, SlidersHorizontal, ChevronDown, Plus } from 'lucide-vue-next' import { RefreshCw, SlidersHorizontal, ChevronDown, Plus } from 'lucide-vue-next'
import { useAuth } from '@/composables/useAuthService' import { useAuth } from '@/composables/useAuthService'
import { useActivities } from '../composables/useActivities' 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 ActivitySearchOverlay from '../components/ActivitySearchOverlay.vue'
import TemporalFilterBar from '../components/TemporalFilterBar.vue' import TemporalFilterBar from '../components/TemporalFilterBar.vue'
import CategoryFilterBar from '../components/CategoryFilterBar.vue' import CategoryFilterBar from '../components/CategoryFilterBar.vue'
@ -55,6 +58,16 @@ function handleSelectActivity(activity: Activity) {
function handleRefresh() { function handleRefresh() {
refresh() 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)
}
</script> </script>
<template> <template>
@ -138,10 +151,12 @@ function handleRefresh() {
@select="handleSelectActivity" @select="handleSelectActivity"
/> />
<!-- Create Activity Dialog --> <!-- Create Event Dialog -->
<CreateActivityDialog <CreateEventDialog
v-model:is-open="showCreateDialog" :open="showCreateDialog"
@created="handleRefresh" @update:open="showCreateDialog = $event"
:on-create-event="handleCreateEvent"
@event-created="handleRefresh"
/> />
</div> </div>
</template> </template>