2025-08-12 04:25:35 +02:00
// server/utils/nocodb-events.ts
import type { Event , EventRSVP , EventsResponse , EventFilters } from '~/utils/types' ;
2025-08-12 12:29:59 +02:00
import { getEffectiveNocoDBConfig } from './admin-config' ;
2025-08-12 04:25:35 +02:00
/ * *
* Creates a client for interacting with the Events NocoDB table
* Provides CRUD operations and specialized queries for events and RSVPs
* /
export function createNocoDBEventsClient() {
2025-08-12 12:24:16 +02:00
// Get effective configuration from admin config system
const effectiveConfig = getEffectiveNocoDBConfig ( ) ;
2025-08-12 04:25:35 +02:00
2025-08-12 12:24:16 +02:00
const baseUrl = effectiveConfig . url ;
const token = effectiveConfig . token ;
const eventsBaseId = effectiveConfig . baseId ;
const eventsTableId = effectiveConfig . tables . events || 'events' ;
const rsvpTableId = effectiveConfig . tables . rsvps || 'event_rsvps' ;
2025-08-12 04:25:35 +02:00
if ( ! baseUrl || ! token || ! eventsBaseId ) {
throw new Error ( 'Events NocoDB configuration is incomplete. Please check environment variables.' ) ;
}
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
// Validate API token before using it
if ( token ) {
const cleanToken = token . trim ( ) ;
// Check for non-ASCII characters that would cause ByteString errors
if ( ! /^[\x00-\xFF]*$/ . test ( cleanToken ) ) {
console . error ( '[nocodb-events] ❌ CRITICAL ERROR: API token contains invalid Unicode characters!' ) ;
console . error ( '[nocodb-events] This will cause ByteString conversion errors in HTTP headers.' ) ;
console . error ( '[nocodb-events] Please update the API token in the admin configuration.' ) ;
throw createError ( {
statusCode : 500 ,
statusMessage : 'Events system: NocoDB API token contains invalid characters. Please reconfigure the database connection in the admin panel with a valid API token.'
} ) ;
}
// Additional validation for common token issues
if ( cleanToken . includes ( '•' ) || cleanToken . includes ( '…' ) || cleanToken . includes ( '"' ) || cleanToken . includes ( '"' ) ) {
console . error ( '[nocodb-events] ❌ CRITICAL ERROR: API token contains formatting characters!' ) ;
console . error ( '[nocodb-events] Found characters like bullets (•), quotes, etc. that break HTTP headers.' ) ;
console . error ( '[nocodb-events] Please copy the raw API token from NocoDB without any formatting.' ) ;
throw createError ( {
statusCode : 500 ,
statusMessage : 'Events system: NocoDB API token contains formatting characters (bullets, quotes, etc.). Please reconfigure with the raw token from NocoDB.'
} ) ;
}
}
2025-08-12 04:25:35 +02:00
const headers = {
'xc-token' : token ,
'Content-Type' : 'application/json'
} ;
const eventsClient = {
/ * *
* Find all events with optional filtering
* /
async findAll ( filters? : EventFilters & { limit? : number ; offset? : number } ) {
const queryParams = new URLSearchParams ( ) ;
if ( filters ? . limit ) queryParams . set ( 'limit' , filters . limit . toString ( ) ) ;
if ( filters ? . offset ) queryParams . set ( 'offset' , filters . offset . toString ( ) ) ;
2025-08-12 13:41:59 +02:00
// Build where clause for filtering using correct field names from NocoDB
const whereConditions : string [ ] = [ ] ;
2025-08-12 04:25:35 +02:00
2025-08-12 13:41:59 +02:00
if ( filters ? . start_date && filters ? . end_date ) {
// Date range filtering using gte and lte (btw didn't work)
whereConditions . push ( ` (start_datetime,gte, ${ filters . start_date } ) ` ) ;
whereConditions . push ( ` (start_datetime,lte, ${ filters . end_date } ) ` ) ;
}
2025-08-12 04:25:35 +02:00
2025-08-12 13:41:59 +02:00
if ( filters ? . event_type ) {
whereConditions . push ( ` (event_type,eq, ${ filters . event_type } ) ` ) ;
}
if ( filters ? . visibility ) {
whereConditions . push ( ` (visibility,eq, ${ filters . visibility } ) ` ) ;
} else if ( filters ? . user_role ) {
// Role-based visibility filtering
if ( filters . user_role === 'user' ) {
whereConditions . push ( ` (visibility,eq,public) ` ) ;
} else if ( filters . user_role === 'board' ) {
// Board members can see public and board-only events
whereConditions . push ( ` ~or((visibility,eq,public),(visibility,eq,board-only)) ` ) ;
2025-08-12 13:33:23 +02:00
}
2025-08-12 13:41:59 +02:00
// Admin sees all events (no filter)
}
if ( filters ? . status ) {
whereConditions . push ( ` (status,eq, ${ filters . status } ) ` ) ;
} else {
// Default to active events only
whereConditions . push ( ` (status,eq,active) ` ) ;
}
if ( filters ? . search ) {
// Search in title or description
whereConditions . push ( ` ~or((title,like,% ${ filters . search } %),(description,like,% ${ filters . search } %)) ` ) ;
}
// Combine conditions with ~and if multiple conditions exist
if ( whereConditions . length > 0 ) {
const whereClause = whereConditions . length === 1
? whereConditions [ 0 ]
: ` ~and( ${ whereConditions . join ( ',' ) } ) ` ;
queryParams . set ( 'where' , whereClause ) ;
2025-08-12 13:33:23 +02:00
}
2025-08-12 13:41:59 +02:00
// Sort by start date
queryParams . set ( 'sort' , 'start_datetime' ) ;
const url = ` ${ baseUrl } /api/v2/tables/ ${ eventsTableId } /records? ${ queryParams . toString ( ) } ` ;
const response = await $fetch ( url , {
method : 'GET' ,
headers
} ) ;
return response ;
2025-08-12 04:25:35 +02:00
} ,
/ * *
* Find a single event by ID
* /
async findOne ( id : string ) {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ eventsTableId } /records/ ${ id } ` ;
2025-08-12 04:25:35 +02:00
return await $fetch < Event > ( url , {
method : 'GET' ,
headers
} ) ;
} ,
/ * *
* Create a new event
* /
async create ( eventData : Partial < Event > ) {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ eventsTableId } /records ` ;
2025-08-12 04:25:35 +02:00
// Set default values
const data = {
. . . eventData ,
status : eventData.status || 'active' ,
created_at : new Date ( ) . toISOString ( ) ,
updated_at : new Date ( ) . toISOString ( )
} ;
return await $fetch < Event > ( url , {
method : 'POST' ,
headers ,
body : data
} ) ;
} ,
/ * *
* Update an existing event
* /
async update ( id : string , eventData : Partial < Event > ) {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ eventsTableId } /records ` ;
2025-08-12 04:25:35 +02:00
const data = {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
Id : parseInt ( id ) ,
2025-08-12 04:25:35 +02:00
. . . eventData ,
updated_at : new Date ( ) . toISOString ( )
} ;
return await $fetch < Event > ( url , {
method : 'PATCH' ,
headers ,
body : data
} ) ;
} ,
/ * *
* Delete an event
* /
async delete ( id : string ) {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ eventsTableId } /records ` ;
2025-08-12 04:25:35 +02:00
return await $fetch ( url , {
method : 'DELETE' ,
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
headers ,
body : { Id : parseInt ( id ) }
2025-08-12 04:25:35 +02:00
} ) ;
} ,
/ * *
* Create an RSVP record for an event
* /
async createRSVP ( rsvpData : Partial < EventRSVP > ) {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ rsvpTableId } /records ` ;
2025-08-12 04:25:35 +02:00
const data = {
. . . rsvpData ,
2025-08-12 12:24:16 +02:00
created_time : new Date ( ) . toISOString ( ) ,
updated_time : new Date ( ) . toISOString ( )
2025-08-12 04:25:35 +02:00
} ;
return await $fetch < EventRSVP > ( url , {
method : 'POST' ,
headers ,
body : data
} ) ;
} ,
/ * *
* Find RSVPs for a specific event
* /
async findEventRSVPs ( eventId : string ) {
const queryParams = new URLSearchParams ( ) ;
fix(events): Convert NocoDB query syntax from SQL-like to v2 API format
- Updated all where clauses to use NocoDB v2 syntax: (field,operator,value)
- Changed SQL-like syntax (field >= 'value' AND field = 'value') to v2 format
- Fixed date range queries: (start_datetime,gte,date) and (start_datetime,lte,date)
- Fixed equality queries: (status,eq,active) instead of (status = 'active')
- Fixed AND/OR logic: ~and() and ~or() syntax for complex conditions
- Updated findEventRSVPs, findUserRSVP, and findUserEvents methods
- Fixed RSVP queries to use proper v2 format for member and event matching
This should resolve the 422 Unprocessable Entity errors that were caused by
using deprecated SQL-like syntax with the v2 API endpoints.
2025-08-12 13:15:06 +02:00
queryParams . set ( 'where' , ` (event_id,eq, ${ eventId } ) ` ) ;
2025-08-12 12:24:16 +02:00
queryParams . set ( 'sort' , 'created_time' ) ;
2025-08-12 04:25:35 +02:00
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ rsvpTableId } /records? ${ queryParams . toString ( ) } ` ;
2025-08-12 04:25:35 +02:00
return await $fetch ( url , {
method : 'GET' ,
headers
} ) ;
} ,
/ * *
* Find a user ' s RSVP for a specific event
* /
async findUserRSVP ( eventId : string , memberId : string ) {
const queryParams = new URLSearchParams ( ) ;
fix(events): Convert NocoDB query syntax from SQL-like to v2 API format
- Updated all where clauses to use NocoDB v2 syntax: (field,operator,value)
- Changed SQL-like syntax (field >= 'value' AND field = 'value') to v2 format
- Fixed date range queries: (start_datetime,gte,date) and (start_datetime,lte,date)
- Fixed equality queries: (status,eq,active) instead of (status = 'active')
- Fixed AND/OR logic: ~and() and ~or() syntax for complex conditions
- Updated findEventRSVPs, findUserRSVP, and findUserEvents methods
- Fixed RSVP queries to use proper v2 format for member and event matching
This should resolve the 422 Unprocessable Entity errors that were caused by
using deprecated SQL-like syntax with the v2 API endpoints.
2025-08-12 13:15:06 +02:00
queryParams . set ( 'where' , ` ~and((event_id,eq, ${ eventId } ),(member_id,eq, ${ memberId } )) ` ) ;
2025-08-12 04:25:35 +02:00
queryParams . set ( 'limit' , '1' ) ;
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ rsvpTableId } /records? ${ queryParams . toString ( ) } ` ;
2025-08-12 04:25:35 +02:00
2025-08-12 12:24:16 +02:00
const response = await $fetch < { list? : EventRSVP [ ] ; PageInfo? : any } > ( url , {
2025-08-12 04:25:35 +02:00
method : 'GET' ,
headers
} ) ;
return response ? . list ? . [ 0 ] || null ;
} ,
/ * *
* Update an RSVP record
* /
async updateRSVP ( id : string , rsvpData : Partial < EventRSVP > ) {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ rsvpTableId } /records ` ;
2025-08-12 04:25:35 +02:00
const data = {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
Id : parseInt ( id ) ,
2025-08-12 04:25:35 +02:00
. . . rsvpData ,
2025-08-12 12:24:16 +02:00
updated_time : new Date ( ) . toISOString ( )
2025-08-12 04:25:35 +02:00
} ;
return await $fetch < EventRSVP > ( url , {
method : 'PATCH' ,
headers ,
body : data
} ) ;
} ,
/ * *
* Update event attendance count ( for optimization )
* /
async updateAttendeeCount ( eventId : string , count : number ) {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const url = ` ${ baseUrl } /api/v2/tables/ ${ eventsTableId } /records ` ;
2025-08-12 04:25:35 +02:00
return await $fetch ( url , {
method : 'PATCH' ,
headers ,
body : {
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
Id : parseInt ( eventId ) ,
2025-08-12 04:25:35 +02:00
current_attendees : count.toString ( ) ,
updated_at : new Date ( ) . toISOString ( )
}
} ) ;
} ,
/ * *
* Get events for a specific user with their RSVP status
* /
async findUserEvents ( memberId : string , filters? : EventFilters ) {
// First get all visible events
2025-08-12 12:24:16 +02:00
const events = await this . findAll ( filters ) as { list? : Event [ ] ; PageInfo? : any } ;
2025-08-12 04:25:35 +02:00
if ( ! events . list || events . list . length === 0 ) {
return { list : [ ] , PageInfo : events.PageInfo } ;
}
// Get user's RSVPs for these events
2025-08-12 13:41:59 +02:00
// Fix: Use 'Id' (capital I) as that's the actual field name from NocoDB
const eventIds = events . list . map ( ( e : any ) = > e . Id ) ;
// Skip RSVP lookup if no valid event IDs
if ( ! eventIds . length || eventIds . some ( id = > ! id ) ) {
console . log ( '[nocodb-events] ⚠️ No valid event IDs found, skipping RSVP lookup' ) ;
return { list : events.list , PageInfo : events.PageInfo } ;
}
2025-08-12 04:25:35 +02:00
const rsvpQueryParams = new URLSearchParams ( ) ;
fix(events): Convert NocoDB query syntax from SQL-like to v2 API format
- Updated all where clauses to use NocoDB v2 syntax: (field,operator,value)
- Changed SQL-like syntax (field >= 'value' AND field = 'value') to v2 format
- Fixed date range queries: (start_datetime,gte,date) and (start_datetime,lte,date)
- Fixed equality queries: (status,eq,active) instead of (status = 'active')
- Fixed AND/OR logic: ~and() and ~or() syntax for complex conditions
- Updated findEventRSVPs, findUserRSVP, and findUserEvents methods
- Fixed RSVP queries to use proper v2 format for member and event matching
This should resolve the 422 Unprocessable Entity errors that were caused by
using deprecated SQL-like syntax with the v2 API endpoints.
2025-08-12 13:15:06 +02:00
const eventIdConditions = eventIds . map ( id = > ` (event_id,eq, ${ id } ) ` ) . join ( ',' ) ;
rsvpQueryParams . set ( 'where' , ` ~and((member_id,eq, ${ memberId } ),~or( ${ eventIdConditions } )) ` ) ;
2025-08-12 04:25:35 +02:00
fix(events): Convert events NocoDB client from v1 to v2 API
- Updated all NocoDB API calls from v1/db/data/v1/ to v2/tables/ endpoints
- Fixed 422 Unprocessable Entity errors on events calendar page
- Ensures consistency with members system which already uses v2 API
- Updated methods: findAll, findOne, create, update, delete, createRSVP, findEventRSVPs, findUserRSVP, updateRSVP, updateAttendeeCount, findUserEvents
- Maintains same functionality while using correct API version
Resolves continuous 422 errors when loading events calendar.
2025-08-12 13:02:13 +02:00
const rsvpUrl = ` ${ baseUrl } /api/v2/tables/ ${ rsvpTableId } /records? ${ rsvpQueryParams . toString ( ) } ` ;
2025-08-12 04:25:35 +02:00
2025-08-12 12:24:16 +02:00
const rsvps = await $fetch < { list? : EventRSVP [ ] ; PageInfo? : any } > ( rsvpUrl , {
2025-08-12 04:25:35 +02:00
method : 'GET' ,
headers
} ) ;
// Map RSVPs to events
const rsvpMap = new Map ( ) ;
if ( rsvps . list ) {
rsvps . list . forEach ( ( rsvp : EventRSVP ) = > {
rsvpMap . set ( rsvp . event_id , rsvp ) ;
} ) ;
}
// Add RSVP information to events
2025-08-12 13:41:59 +02:00
// Fix: Use 'Id' (capital I) as that's the actual field name from NocoDB
const eventsWithRSVP = events . list . map ( ( event : any ) = > ( {
2025-08-12 04:25:35 +02:00
. . . event ,
2025-08-12 13:41:59 +02:00
user_rsvp : rsvpMap.get ( event . Id ) || null
2025-08-12 04:25:35 +02:00
} ) ) ;
return {
list : eventsWithRSVP ,
PageInfo : events.PageInfo
} ;
} ,
/ * *
* Generate payment reference for RSVP
* /
generatePaymentReference ( memberId : string , date? : Date ) : string {
const referenceDate = date || new Date ( ) ;
const dateString = referenceDate . toISOString ( ) . split ( 'T' ) [ 0 ] ; // YYYY-MM-DD
return ` EVT- ${ memberId } - ${ dateString } ` ;
} ,
/ * *
* Check if event has reached capacity
* /
async isEventFull ( eventId : string ) : Promise < boolean > {
const event = await this . findOne ( eventId ) ;
if ( ! event . max_attendees ) return false ; // Unlimited capacity
const maxAttendees = parseInt ( event . max_attendees ) ;
2025-08-12 12:24:16 +02:00
const currentAttendees = parseInt ( String ( event . current_attendees || 0 ) ) ;
2025-08-12 04:25:35 +02:00
return currentAttendees >= maxAttendees ;
}
} ;
return eventsClient ;
}
/ * *
* Utility function to transform Event data for FullCalendar
2025-08-12 13:41:59 +02:00
* Updated to use correct field names from NocoDB ( Id instead of id )
2025-08-12 04:25:35 +02:00
* /
2025-08-12 13:41:59 +02:00
export function transformEventForCalendar ( event : any ) : any {
2025-08-12 04:25:35 +02:00
const eventTypeColors = {
'meeting' : { bg : '#2196f3' , border : '#1976d2' } ,
'social' : { bg : '#4caf50' , border : '#388e3c' } ,
'fundraiser' : { bg : '#ff9800' , border : '#f57c00' } ,
'workshop' : { bg : '#9c27b0' , border : '#7b1fa2' } ,
'board-only' : { bg : '#a31515' , border : '#8b1212' }
} ;
const colors = eventTypeColors [ event . event_type as keyof typeof eventTypeColors ] ||
{ bg : '#757575' , border : '#424242' } ;
return {
2025-08-12 13:41:59 +02:00
id : event.Id , // Fix: Use 'Id' (capital I) from NocoDB
title : event.title || 'Untitled Event' ,
2025-08-12 04:25:35 +02:00
start : event.start_datetime ,
end : event.end_datetime ,
backgroundColor : colors.bg ,
borderColor : colors.border ,
textColor : '#ffffff' ,
extendedProps : {
description : event.description ,
location : event.location ,
event_type : event.event_type ,
is_paid : event.is_paid === 'true' ,
cost_members : event.cost_members ,
cost_non_members : event.cost_non_members ,
max_attendees : event.max_attendees ? parseInt ( event . max_attendees ) : null ,
current_attendees : event.current_attendees || 0 ,
user_rsvp : event.user_rsvp ,
visibility : event.visibility ,
creator : event.creator ,
status : event.status
}
} ;
}