Fix type safety and data consistency in events system
Build And Push Image / docker (push) Successful in 3m25s
Details
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:
parent
70b77fbe9f
commit
072acf95eb
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
<!-- No events message -->
|
<!-- No events message -->
|
||||||
<v-alert
|
<v-alert
|
||||||
v-if="!loading && events.length === 0"
|
v-if="!loading && (!events || events.length === 0)"
|
||||||
type="info"
|
type="info"
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
class="mt-4"
|
class="mt-4"
|
||||||
|
|
@ -143,7 +143,7 @@ const calendarOptions = computed(() => ({
|
||||||
right: process.client && window.innerWidth < 960 ?
|
right: process.client && window.innerWidth < 960 ?
|
||||||
'dayGridMonth,listWeek' :
|
'dayGridMonth,listWeek' :
|
||||||
'dayGridMonth,dayGridWeek,listWeek'
|
'dayGridMonth,dayGridWeek,listWeek'
|
||||||
},
|
} as any,
|
||||||
events: transformedEvents.value,
|
events: transformedEvents.value,
|
||||||
eventClick: handleEventClick,
|
eventClick: handleEventClick,
|
||||||
dateClick: handleDateClick,
|
dateClick: handleDateClick,
|
||||||
|
|
@ -153,8 +153,8 @@ const calendarOptions = computed(() => ({
|
||||||
eventDisplay: 'block',
|
eventDisplay: 'block',
|
||||||
displayEventTime: true,
|
displayEventTime: true,
|
||||||
eventTimeFormat: {
|
eventTimeFormat: {
|
||||||
hour: '2-digit',
|
hour: '2-digit' as const,
|
||||||
minute: '2-digit',
|
minute: '2-digit' as const,
|
||||||
hour12: false
|
hour12: false
|
||||||
},
|
},
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
|
|
@ -256,12 +256,11 @@ function transformEventForCalendar(event: Event): FullCalendarEvent {
|
||||||
is_paid: event.is_paid === 'true',
|
is_paid: event.is_paid === 'true',
|
||||||
cost_members: event.cost_members,
|
cost_members: event.cost_members,
|
||||||
cost_non_members: event.cost_non_members,
|
cost_non_members: event.cost_non_members,
|
||||||
max_attendees: event.max_attendees ? parseInt(event.max_attendees) : null,
|
max_attendees: event.max_attendees ? parseInt(event.max_attendees) : undefined,
|
||||||
current_attendees: event.current_attendees || 0,
|
current_attendees: typeof event.current_attendees === 'string' ? parseInt(event.current_attendees) : (event.current_attendees || 0),
|
||||||
user_rsvp: event.user_rsvp,
|
user_rsvp: event.user_rsvp,
|
||||||
visibility: event.visibility,
|
visibility: event.visibility,
|
||||||
creator: event.creator,
|
creator: event.creator
|
||||||
status: event.status
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ export const useEvents = () => {
|
||||||
error.value = null;
|
error.value = null;
|
||||||
|
|
||||||
try {
|
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',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
...rsvpData,
|
...rsvpData,
|
||||||
|
|
@ -130,8 +130,10 @@ export const useEvents = () => {
|
||||||
|
|
||||||
// Update attendee count if confirmed
|
// Update attendee count if confirmed
|
||||||
if (rsvpData.rsvp_status === 'confirmed') {
|
if (rsvpData.rsvp_status === 'confirmed') {
|
||||||
const currentCount = events.value[eventIndex].current_attendees || 0;
|
const currentCount = typeof events.value[eventIndex].current_attendees === 'string'
|
||||||
events.value[eventIndex].current_attendees = currentCount + 1;
|
? parseInt(events.value[eventIndex].current_attendees) || 0
|
||||||
|
: events.value[eventIndex].current_attendees || 0;
|
||||||
|
events.value[eventIndex].current_attendees = (currentCount + 1).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,10 @@ const totalEvents = computed(() => events.value.length);
|
||||||
|
|
||||||
const totalRSVPs = computed(() => {
|
const totalRSVPs = computed(() => {
|
||||||
return events.value.reduce((count, event) => {
|
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);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -332,7 +335,7 @@ const clearFilters = async () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEventClick = (eventInfo: any) => {
|
const handleEventClick = (eventInfo: any) => {
|
||||||
selectedEvent.value = eventInfo.eventData || eventInfo.event || eventInfo;
|
selectedEvent.value = (eventInfo.eventData || eventInfo.event || eventInfo) as Event;
|
||||||
showDetailsDialog.value = true;
|
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!');
|
showSuccessMessage('Event created successfully!');
|
||||||
refreshCalendar();
|
await refreshCalendar();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRSVPUpdated = (event: Event) => {
|
const handleRSVPUpdated = async (event: Event) => {
|
||||||
showSuccessMessage('RSVP updated successfully!');
|
showSuccessMessage('RSVP updated successfully!');
|
||||||
refreshCalendar();
|
await refreshCalendar();
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshCalendar = () => {
|
const refreshCalendar = async () => {
|
||||||
calendarRef.value?.refetchEvents?.();
|
try {
|
||||||
|
// Clear cache and force refresh events data
|
||||||
clearCache();
|
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 = () => {
|
const exportCalendar = () => {
|
||||||
|
|
|
||||||
|
|
@ -369,8 +369,16 @@ export function createNocoDBEventsClient() {
|
||||||
console.log('[nocodb-events] Finding events for member:', memberId);
|
console.log('[nocodb-events] Finding events for member:', memberId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// For now, just get all visible events (we'll add RSVP logic later)
|
// For now, just get all visible events using the working findAll method
|
||||||
const events = await this.findAll(filters);
|
// 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
|
// TODO: Add RSVP lookup from separate table
|
||||||
// For now, return events without RSVP status
|
// For now, return events without RSVP status
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue