Add series management and ticketing features: Introduce series event functionality in event creation, enhance event display with series information, and implement ticketing options for public events. Update layouts and improve form handling for better user experience.
This commit is contained in:
parent
c3a29fa47c
commit
a88aa62198
24 changed files with 2897 additions and 44 deletions
112
server/api/events/[id]/guest-register.post.js
Normal file
112
server/api/events/[id]/guest-register.post.js
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
import Event from '../../../models/event.js'
|
||||
import { connectDB } from '../../../utils/mongoose.js'
|
||||
import mongoose from 'mongoose'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
await connectDB()
|
||||
const identifier = getRouterParam(event, 'id')
|
||||
const body = await readBody(event)
|
||||
|
||||
if (!identifier) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Event identifier is required'
|
||||
})
|
||||
}
|
||||
|
||||
// Validate required fields for guest registration
|
||||
if (!body.name || !body.email) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Name and email are required'
|
||||
})
|
||||
}
|
||||
|
||||
// Fetch the event
|
||||
let eventData
|
||||
if (mongoose.Types.ObjectId.isValid(identifier)) {
|
||||
eventData = await Event.findById(identifier)
|
||||
}
|
||||
if (!eventData) {
|
||||
eventData = await Event.findOne({ slug: identifier })
|
||||
}
|
||||
|
||||
if (!eventData) {
|
||||
throw createError({
|
||||
statusCode: 404,
|
||||
statusMessage: 'Event not found'
|
||||
})
|
||||
}
|
||||
|
||||
// Check if event allows public registration (not members-only)
|
||||
if (eventData.membersOnly) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: 'This event is for members only. Please become a member to register.'
|
||||
})
|
||||
}
|
||||
|
||||
// If event requires payment, reject guest registration
|
||||
if (eventData.pricing.paymentRequired && !eventData.pricing.isFree) {
|
||||
throw createError({
|
||||
statusCode: 402,
|
||||
statusMessage: 'This event requires payment. Please use the payment registration endpoint.'
|
||||
})
|
||||
}
|
||||
|
||||
// Check if event is full
|
||||
if (eventData.maxAttendees && eventData.registrations.length >= eventData.maxAttendees) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Event is full'
|
||||
})
|
||||
}
|
||||
|
||||
// Check if already registered
|
||||
const alreadyRegistered = eventData.registrations.some(
|
||||
reg => reg.email.toLowerCase() === body.email.toLowerCase()
|
||||
)
|
||||
|
||||
if (alreadyRegistered) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'You are already registered for this event'
|
||||
})
|
||||
}
|
||||
|
||||
// Add guest registration
|
||||
eventData.registrations.push({
|
||||
name: body.name,
|
||||
email: body.email.toLowerCase(),
|
||||
membershipLevel: 'guest',
|
||||
isMember: false,
|
||||
paymentStatus: 'not_required',
|
||||
amountPaid: 0,
|
||||
registeredAt: new Date()
|
||||
})
|
||||
|
||||
await eventData.save()
|
||||
|
||||
// TODO: Send confirmation email for guest registration
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Successfully registered as guest',
|
||||
registrationId: eventData.registrations[eventData.registrations.length - 1]._id,
|
||||
note: 'As a guest, you have access to this free public event. Consider becoming a member for access to all events!'
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error with guest registration:', error)
|
||||
|
||||
if (error.statusCode) {
|
||||
throw error
|
||||
}
|
||||
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to register as guest'
|
||||
})
|
||||
}
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue