96 lines
2.5 KiB
TypeScript
96 lines
2.5 KiB
TypeScript
|
|
// server/api/events/[id]/attendees.patch.ts
|
||
|
|
import { createNocoDBEventsClient } from '~/server/utils/nocodb-events';
|
||
|
|
import type { EventAttendanceRequest } from '~/utils/types';
|
||
|
|
|
||
|
|
export default defineEventHandler(async (event) => {
|
||
|
|
try {
|
||
|
|
const eventId = getRouterParam(event, 'id');
|
||
|
|
const body = await readBody(event) as EventAttendanceRequest;
|
||
|
|
|
||
|
|
if (!eventId) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 400,
|
||
|
|
statusMessage: 'Event ID is required'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get user session
|
||
|
|
const session = await getUserSession(event);
|
||
|
|
if (!session || !session.user) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 401,
|
||
|
|
statusMessage: 'Authentication required'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if user has permission to mark attendance (board or admin only)
|
||
|
|
if (session.user.tier !== 'board' && session.user.tier !== 'admin') {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 403,
|
||
|
|
statusMessage: 'Only board members and administrators can mark attendance'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
const eventsClient = createNocoDBEventsClient();
|
||
|
|
|
||
|
|
// Verify event exists
|
||
|
|
const eventDetails = await eventsClient.findOne(eventId);
|
||
|
|
if (!eventDetails) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 404,
|
||
|
|
statusMessage: 'Event not found'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Find the user's RSVP record
|
||
|
|
const userRSVP = await eventsClient.findUserRSVP(eventId, body.member_id);
|
||
|
|
if (!userRSVP) {
|
||
|
|
throw createError({
|
||
|
|
statusCode: 404,
|
||
|
|
statusMessage: 'RSVP record not found for this member'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Update attendance status
|
||
|
|
const updatedRSVP = await eventsClient.updateRSVP(userRSVP.id, {
|
||
|
|
attended: body.attended ? 'true' : 'false',
|
||
|
|
updated_at: new Date().toISOString()
|
||
|
|
});
|
||
|
|
|
||
|
|
return {
|
||
|
|
success: true,
|
||
|
|
data: updatedRSVP,
|
||
|
|
message: `Attendance ${body.attended ? 'marked' : 'unmarked'} successfully`
|
||
|
|
};
|
||
|
|
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error updating attendance:', error);
|
||
|
|
|
||
|
|
if (error.statusCode) {
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
|
||
|
|
throw createError({
|
||
|
|
statusCode: 500,
|
||
|
|
statusMessage: 'Failed to update attendance'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Helper function
|
||
|
|
async function getUserSession(event: any) {
|
||
|
|
try {
|
||
|
|
const sessionCookie = getCookie(event, 'session') || getHeader(event, 'authorization');
|
||
|
|
if (!sessionCookie) return null;
|
||
|
|
|
||
|
|
return {
|
||
|
|
user: {
|
||
|
|
id: 'user-id',
|
||
|
|
tier: 'board' // Replace with actual session logic
|
||
|
|
}
|
||
|
|
};
|
||
|
|
} catch {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|