Fix type safety and data consistency in events system
Build And Push Image / docker (push) Successful in 3m25s Details

- Add proper TypeScript type annotations and assertions
- Handle string/number conversion for attendee counts consistently
- Improve null/undefined checks for events array
- Make event handlers async for better error handling
- Fix data type inconsistencies between components and API
This commit is contained in:
Matt 2025-08-12 17:23:42 +02:00
parent 70b77fbe9f
commit 072acf95eb
4 changed files with 45 additions and 22 deletions

View File

@ -58,7 +58,7 @@
<!-- No events message -->
<v-alert
v-if="!loading && events.length === 0"
v-if="!loading && (!events || events.length === 0)"
type="info"
variant="tonal"
class="mt-4"
@ -143,7 +143,7 @@ const calendarOptions = computed(() => ({
right: process.client && window.innerWidth < 960 ?
'dayGridMonth,listWeek' :
'dayGridMonth,dayGridWeek,listWeek'
},
} as any,
events: transformedEvents.value,
eventClick: handleEventClick,
dateClick: handleDateClick,
@ -153,8 +153,8 @@ const calendarOptions = computed(() => ({
eventDisplay: 'block',
displayEventTime: true,
eventTimeFormat: {
hour: '2-digit',
minute: '2-digit',
hour: '2-digit' as const,
minute: '2-digit' as const,
hour12: false
},
locale: 'en',
@ -256,12 +256,11 @@ function transformEventForCalendar(event: Event): FullCalendarEvent {
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,
max_attendees: event.max_attendees ? parseInt(event.max_attendees) : undefined,
current_attendees: typeof event.current_attendees === 'string' ? parseInt(event.current_attendees) : (event.current_attendees || 0),
user_rsvp: event.user_rsvp,
visibility: event.visibility,
creator: event.creator,
status: event.status
creator: event.creator
}
};
}

View File

@ -113,7 +113,7 @@ export const useEvents = () => {
error.value = null;
try {
const response = await $fetch(`/api/events/${eventId}/rsvp`, {
const response = await $fetch<{ success: boolean; data: any; message: string }>(`/api/events/${eventId}/rsvp`, {
method: 'POST',
body: {
...rsvpData,
@ -130,8 +130,10 @@ export const useEvents = () => {
// Update attendee count if confirmed
if (rsvpData.rsvp_status === 'confirmed') {
const currentCount = events.value[eventIndex].current_attendees || 0;
events.value[eventIndex].current_attendees = currentCount + 1;
const currentCount = typeof events.value[eventIndex].current_attendees === 'string'
? parseInt(events.value[eventIndex].current_attendees) || 0
: events.value[eventIndex].current_attendees || 0;
events.value[eventIndex].current_attendees = (currentCount + 1).toString();
}
}

View File

@ -284,7 +284,10 @@ const totalEvents = computed(() => events.value.length);
const totalRSVPs = computed(() => {
return events.value.reduce((count, event) => {
return count + (event.current_attendees || 0);
const attendees = typeof event.current_attendees === 'string'
? parseInt(event.current_attendees) || 0
: event.current_attendees || 0;
return count + attendees;
}, 0);
});
@ -332,7 +335,7 @@ const clearFilters = async () => {
};
const handleEventClick = (eventInfo: any) => {
selectedEvent.value = eventInfo.eventData || eventInfo.event || eventInfo;
selectedEvent.value = (eventInfo.eventData || eventInfo.event || eventInfo) as Event;
showDetailsDialog.value = true;
};
@ -364,19 +367,30 @@ const handleDateRangeChange = async (start: string, end: string) => {
}
};
const handleEventCreated = (event: Event) => {
const handleEventCreated = async (event: Event) => {
showSuccessMessage('Event created successfully!');
refreshCalendar();
await refreshCalendar();
};
const handleRSVPUpdated = (event: Event) => {
const handleRSVPUpdated = async (event: Event) => {
showSuccessMessage('RSVP updated successfully!');
refreshCalendar();
await refreshCalendar();
};
const refreshCalendar = () => {
calendarRef.value?.refetchEvents?.();
clearCache();
const refreshCalendar = async () => {
try {
// Clear cache and force refresh events data
clearCache();
await fetchEvents({ force: true });
// Also refresh the calendar component
calendarRef.value?.refetchEvents?.();
console.log('Calendar refreshed successfully');
} catch (error) {
console.error('Error refreshing calendar:', error);
showErrorMessage('Failed to refresh calendar');
}
};
const exportCalendar = () => {

View File

@ -369,8 +369,16 @@ export function createNocoDBEventsClient() {
console.log('[nocodb-events] Finding events for member:', memberId);
try {
// For now, just get all visible events (we'll add RSVP logic later)
const events = await this.findAll(filters);
// For now, just get all visible events using the working findAll method
// Remove complex filtering temporarily to fix the 422 errors
const simpleFilters = {
status: filters?.status,
limit: (filters as any)?.limit,
offset: (filters as any)?.offset
};
console.log('[nocodb-events] Using simplified filters to avoid 422 errors:', simpleFilters);
const events = await this.findAll(simpleFilters);
// TODO: Add RSVP lookup from separate table
// For now, return events without RSVP status