monacousa-portal/server/api/board/stats.get.ts

102 lines
3.2 KiB
TypeScript
Raw Permalink Normal View History

import { createNocoDBEventsClient } from '~/server/utils/nocodb-events';
export default defineEventHandler(async (event) => {
try {
// Get member statistics using the same pattern as other APIs
const { getMembers } = await import('~/server/utils/nocodb');
const allMembers = await getMembers();
if (!allMembers?.list) {
return {
success: true,
data: {
totalMembers: 0,
activeMembers: 0,
upcomingMeetings: 0,
pendingActions: 0,
dataSource: 'unavailable'
}
};
}
const totalMembers = allMembers.list.length;
const activeMembers = allMembers.list.filter((member: any) =>
member.membership_status === 'Active'
).length;
// Get real upcoming meetings count from events
let upcomingMeetings = 0;
let eventsSource = 'unavailable';
try {
const eventsClient = createNocoDBEventsClient();
const now = new Date();
const thirtyDaysFromNow = new Date();
thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);
const eventsResponse = await eventsClient.findAll({
limit: 200 // Increased limit to get all events
});
// Handle different possible response structures
const eventsList = (eventsResponse as any)?.list || [];
if (eventsList && Array.isArray(eventsList)) {
// Count meetings in the next 30 days
upcomingMeetings = eventsList.filter((event: any) => {
if (!event.start_datetime) return false;
const eventDate = new Date(event.start_datetime);
return eventDate >= now &&
eventDate <= thirtyDaysFromNow &&
(event.event_type === 'meeting' ||
event.title?.toLowerCase().includes('meeting') ||
event.title?.toLowerCase().includes('board'));
}).length;
eventsSource = 'live';
console.log(`[board-stats] Found ${upcomingMeetings} upcoming meetings from live data`);
}
} catch (error) {
console.error('[board-stats] Error fetching events:', error);
// Keep upcomingMeetings as 0 instead of using fallback
upcomingMeetings = 0;
eventsSource = 'error';
}
// Get overdue dues count for pending actions
let pendingActions = 0;
let duesSource = 'unavailable';
try {
const overdueResponse: any = await $fetch('/api/members/overdue-count');
pendingActions = overdueResponse?.data?.count || 0;
duesSource = 'live';
} catch (error) {
console.error('[board-stats] Error fetching overdue count:', error);
pendingActions = 0;
duesSource = 'error';
}
return {
success: true,
data: {
totalMembers,
activeMembers,
upcomingMeetings,
pendingActions,
// Add metadata about data sources
dataSources: {
members: 'live',
events: eventsSource,
dues: duesSource
}
}
};
} catch (error: any) {
console.error('[board-stats] Error:', error);
throw createError({
statusCode: error.statusCode || 500,
statusMessage: error.message || 'Failed to fetch board statistics'
});
}
});