refactor: Revamp PurchaseTicketDialog and introduce useTicketPurchase composable

- Update PurchaseTicketDialog.vue to integrate authentication checks and enhance ticket purchasing flow with wallet support.
- Implement useTicketPurchase composable for managing ticket purchase logic, including payment handling and QR code generation.
- Improve user experience by displaying user information and wallet status during the ticket purchase process.
- Refactor API interactions in events.ts to streamline ticket purchasing and payment status checks.
This commit is contained in:
padreug 2025-08-01 21:33:11 +02:00
parent ed51c95799
commit f7450627bc
5 changed files with 555 additions and 113 deletions

View file

@ -2,15 +2,18 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useEvents } from '@/composables/useEvents'
import { useAuth } from '@/composables/useAuth'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { format } from 'date-fns'
import PurchaseTicketDialog from '@/components/events/PurchaseTicketDialog.vue'
import { RefreshCw } from 'lucide-vue-next'
import { RefreshCw, User, LogIn } from 'lucide-vue-next'
const { upcomingEvents, pastEvents, isLoading, error, refresh } = useEvents()
const { isAuthenticated, userDisplay } = useAuth()
const showPurchaseDialog = ref(false)
const selectedEvent = ref<{
id: string
@ -29,6 +32,12 @@ function handlePurchaseClick(event: {
price_per_ticket: number
currency: string
}) {
if (!isAuthenticated.value) {
// Show login prompt or redirect to login
// You could emit an event to show login dialog here
return
}
selectedEvent.value = event
showPurchaseDialog.value = true
}
@ -37,7 +46,18 @@ function handlePurchaseClick(event: {
<template>
<div class="container mx-auto py-8 px-4">
<div class="flex justify-between items-center mb-6">
<h1 class="text-3xl font-bold text-foreground">Events</h1>
<div class="space-y-1">
<h1 class="text-3xl font-bold text-foreground">Events</h1>
<div v-if="isAuthenticated && userDisplay" class="flex items-center gap-2 text-sm text-muted-foreground">
<User class="w-4 h-4" />
<span>Logged in as {{ userDisplay.name }}</span>
<Badge variant="outline" class="text-xs">{{ userDisplay.shortId }}</Badge>
</div>
<div v-else class="flex items-center gap-2 text-sm text-muted-foreground">
<LogIn class="w-4 h-4" />
<span>Please log in to purchase tickets</span>
</div>
</div>
<Button variant="secondary" size="sm" @click="refresh" :disabled="isLoading">
<RefreshCw class="w-4 h-4 mr-2" :class="{ 'animate-spin': isLoading }" />
Refresh
@ -84,9 +104,17 @@ function handlePurchaseClick(event: {
</div>
</CardContent>
<CardFooter>
<Button class="w-full" variant="default" :disabled="event.amount_tickets <= event.sold"
@click="handlePurchaseClick(event)">
Buy Ticket
<Button
class="w-full"
variant="default"
:disabled="event.amount_tickets <= event.sold || !isAuthenticated"
@click="handlePurchaseClick(event)"
>
<span v-if="!isAuthenticated" class="flex items-center gap-2">
<LogIn class="w-4 h-4" />
Login to Purchase
</span>
<span v-else>Buy Ticket</span>
</Button>
</CardFooter>
</Card>