import Member from "../../../../models/member.js"; import { loadPublicEvent } from "../../../../utils/loadEvent.js"; import { calculateTicketPrice, checkTicketAvailability, formatPrice, } from "../../../../utils/tickets.js"; /** * GET /api/events/[id]/tickets/available * Check ticket availability and pricing for current user * Query params: ?email=user@example.com (optional) */ export default defineEventHandler(async (event) => { try { const identifier = getRouterParam(event, "id"); const query = getQuery(event); const userEmail = query.email; const eventData = await loadPublicEvent(event, identifier); if (eventData.isCancelled) { return { available: false, reason: "Event has been cancelled" }; } if (new Date(eventData.startDate) < new Date()) { return { available: false, reason: "Event has already started" }; } if ( eventData.registrationDeadline && new Date(eventData.registrationDeadline) < new Date() ) { return { available: false, reason: "Registration deadline has passed" }; } let member = null; if (userEmail) { member = await Member.findOne({ email: userEmail.toLowerCase() }); } const ticketInfo = calculateTicketPrice(eventData, member); if (!ticketInfo) { return { available: false, reason: eventData.membersOnly ? "This event is for members only" : "No tickets available", membersOnly: eventData.membersOnly, }; } const availability = checkTicketAvailability( eventData, ticketInfo.ticketType, ); const response = { available: availability.available, ticketType: ticketInfo.ticketType, price: ticketInfo.price, currency: ticketInfo.currency, formattedPrice: formatPrice(ticketInfo.price, ticketInfo.currency), isFree: ticketInfo.isFree, isEarlyBird: ticketInfo.isEarlyBird, name: ticketInfo.name, description: ticketInfo.description, remaining: availability.remaining, waitlistAvailable: availability.waitlistAvailable, }; if (ticketInfo.isEarlyBird && eventData.tickets?.public?.earlyBirdDeadline) { response.earlyBirdDeadline = eventData.tickets.public.earlyBirdDeadline; response.regularPrice = eventData.tickets.public.price; response.formattedRegularPrice = formatPrice( eventData.tickets.public.price, ticketInfo.currency, ); } if (member && eventData.tickets?.public?.available) { response.publicTicket = { price: eventData.tickets.public.price, formattedPrice: formatPrice( eventData.tickets.public.price, eventData.tickets.currency, ), }; response.memberSavings = eventData.tickets.public.price - ticketInfo.price; } if (userEmail) { const alreadyRegistered = eventData.registrations?.some( (reg) => reg.email.toLowerCase() === userEmail.toLowerCase() && !reg.cancelledAt, ); if (alreadyRegistered) { response.alreadyRegistered = true; response.available = false; response.reason = "You are already registered for this event"; } } return response; } catch (error) { if (error.statusCode) { throw error; } console.error("Error checking ticket availability:", error); throw createError({ statusCode: 500, statusMessage: "Failed to check ticket availability", }); } });