import { useMemo } from 'react'; import { useTicketStore } from '../stores/ticketStore'; import { useEventStore } from '../stores/eventStore'; import { useClaims } from '../hooks/useClaims'; import type { Ticket } from '../types/business'; /** * Hook to get tickets with territory filtering applied * Respects user role and territory access controls */ export const useTicketsQuery = (eventId?: string, selectedTerritoryIds?: string[]) => { const { tickets, isLoading, error } = useTicketStore(); const { getEvent } = useEventStore(); const { claims } = useClaims(); const filteredTickets = useMemo(() => { if (!claims) { return []; } let ticketsToFilter = tickets; // Filter by event if specified if (eventId) { ticketsToFilter = ticketsToFilter.filter(ticket => ticket.eventId === eventId); } // Apply territory filtering based on role if (claims.role === 'territoryManager') { // Territory managers can only see tickets for events in their territories const userTerritoryIds = claims.territoryIds || []; ticketsToFilter = ticketsToFilter.filter(ticket => { const event = getEvent(ticket.eventId); return event && userTerritoryIds.includes(event.territoryId || ''); }); } else if (claims.role === 'orgAdmin' || claims.role === 'superadmin') { // Admins can optionally filter by selected territories if (selectedTerritoryIds && selectedTerritoryIds.length > 0) { ticketsToFilter = ticketsToFilter.filter(ticket => { const event = getEvent(ticket.eventId); return event && selectedTerritoryIds.includes(event.territoryId || ''); }); } } return ticketsToFilter; }, [tickets, eventId, claims, selectedTerritoryIds, getEvent]); return { tickets: filteredTickets, isLoading, error, totalCount: filteredTickets.length, isFiltered: (claims?.role === 'territoryManager') || (selectedTerritoryIds && selectedTerritoryIds.length > 0) }; }; /** * Hook to get tickets for a specific event with territory validation */ export const useEventTicketsQuery = (eventId: string) => { const { tickets, isLoading, error } = useTicketStore(); const { getEvent } = useEventStore(); const { claims } = useClaims(); const eventTickets = useMemo(() => { if (!claims) { return []; } const event = getEvent(eventId); if (!event) { return []; } // Check territory access for territory managers if (claims.role === 'territoryManager') { const userTerritoryIds = claims.territoryIds || []; if (!userTerritoryIds.includes(event.territoryId || '')) { return []; // Access denied to event, so no tickets } } return tickets.filter(ticket => ticket.eventId === eventId); }, [eventId, tickets, getEvent, claims]); return { tickets: eventTickets, isLoading, error, hasAccess: eventTickets.length > 0 || claims?.role !== 'territoryManager' }; }; /** * Hook to get ticket statistics with territory filtering */ export const useTicketStatsQuery = (selectedTerritoryIds?: string[]) => { const { tickets } = useTicketStore(); const { getEvent } = useEventStore(); const { claims } = useClaims(); const stats = useMemo(() => { if (!claims) { return { totalSold: 0, totalRevenue: 0, pendingTickets: 0, scannedTickets: 0 }; } let ticketsToAnalyze = tickets; // Apply territory filtering based on role if (claims.role === 'territoryManager') { const userTerritoryIds = claims.territoryIds || []; ticketsToAnalyze = ticketsToAnalyze.filter(ticket => { const event = getEvent(ticket.eventId); return event && userTerritoryIds.includes(event.territoryId || ''); }); } else if (claims.role === 'orgAdmin' || claims.role === 'superadmin') { if (selectedTerritoryIds && selectedTerritoryIds.length > 0) { ticketsToAnalyze = ticketsToAnalyze.filter(ticket => { const event = getEvent(ticket.eventId); return event && selectedTerritoryIds.includes(event.territoryId || ''); }); } } const totalSold = ticketsToAnalyze.length; const totalRevenue = ticketsToAnalyze.reduce((sum, ticket) => sum + ticket.price, 0); const pendingTickets = ticketsToAnalyze.filter(ticket => ticket.status === 'pending').length; const scannedTickets = ticketsToAnalyze.filter(ticket => ticket.status === 'scanned').length; return { totalSold, totalRevenue, pendingTickets, scannedTickets }; }, [tickets, claims, selectedTerritoryIds, getEvent]); return stats; };