feat: Add My Tickets feature with ticket management
- Introduce MyTickets.vue page to display user tickets with filtering options for paid, pending, and registered tickets. - Implement useUserTickets composable for fetching and managing user ticket data. - Update Navbar.vue to include a link to the My Tickets page. - Enhance events API to support fetching user tickets. - Define Ticket type in event.ts for better type safety.
This commit is contained in:
parent
f7450627bc
commit
63d636a8a0
6 changed files with 403 additions and 2 deletions
77
src/composables/useUserTickets.ts
Normal file
77
src/composables/useUserTickets.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import { ref, computed } from 'vue'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import type { Ticket } from '@/lib/types/event'
|
||||
import { fetchUserTickets } from '@/lib/api/events'
|
||||
import { useAuth } from './useAuth'
|
||||
|
||||
export function useUserTickets() {
|
||||
const { isAuthenticated, currentUser } = useAuth()
|
||||
|
||||
const { state: tickets, isLoading, error: asyncError, execute: refresh } = useAsyncState(
|
||||
async () => {
|
||||
if (!isAuthenticated.value || !currentUser.value) {
|
||||
return []
|
||||
}
|
||||
return await fetchUserTickets(currentUser.value.id)
|
||||
},
|
||||
[] as Ticket[],
|
||||
{
|
||||
immediate: false,
|
||||
resetOnExecute: false,
|
||||
}
|
||||
)
|
||||
|
||||
const error = computed(() => {
|
||||
if (asyncError.value) {
|
||||
return {
|
||||
message: asyncError.value instanceof Error
|
||||
? asyncError.value.message
|
||||
: 'An error occurred while fetching tickets'
|
||||
}
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const sortedTickets = computed(() => {
|
||||
return [...tickets.value].sort((a, b) =>
|
||||
new Date(b.time).getTime() - new Date(a.time).getTime()
|
||||
)
|
||||
})
|
||||
|
||||
const paidTickets = computed(() => {
|
||||
return sortedTickets.value.filter(ticket => ticket.paid)
|
||||
})
|
||||
|
||||
const pendingTickets = computed(() => {
|
||||
return sortedTickets.value.filter(ticket => !ticket.paid)
|
||||
})
|
||||
|
||||
const registeredTickets = computed(() => {
|
||||
return sortedTickets.value.filter(ticket => ticket.registered)
|
||||
})
|
||||
|
||||
const unregisteredTickets = computed(() => {
|
||||
return sortedTickets.value.filter(ticket => ticket.paid && !ticket.registered)
|
||||
})
|
||||
|
||||
// Load tickets when authenticated
|
||||
const loadTickets = async () => {
|
||||
if (isAuthenticated.value && currentUser.value) {
|
||||
await refresh()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
tickets: sortedTickets,
|
||||
paidTickets,
|
||||
pendingTickets,
|
||||
registeredTickets,
|
||||
unregisteredTickets,
|
||||
isLoading,
|
||||
error,
|
||||
|
||||
// Actions
|
||||
refresh: loadTickets,
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue