monacousa-portal/server/api/members/index.get.ts

103 lines
3.5 KiB
TypeScript

import { getMembers, handleNocoDbError } from '~/server/utils/nocodb';
import type { Member } from '~/utils/types';
export default defineEventHandler(async (event) => {
console.log('[api/members.get] =========================');
console.log('[api/members.get] GET /api/members - List all members');
console.log('[api/members.get] Request from:', getClientIP(event));
try {
// Get query parameters
const query = getQuery(event);
const limit = parseInt(query.limit as string) || 1000;
const searchTerm = query.search as string;
const nationality = query.nationality as string;
const membershipStatus = query.status as string;
const duesPaid = query.duesPaid as string;
console.log('[api/members.get] Query parameters:', {
limit,
searchTerm,
nationality,
membershipStatus,
duesPaid
});
// Fetch members from NocoDB
const result = await getMembers();
let members = result.list || [];
console.log('[api/members.get] Fetched members count:', members.length);
// Apply client-side filtering since NocoDB filtering can be complex
if (searchTerm) {
const search = searchTerm.toLowerCase();
members = members.filter(member =>
member['First Name']?.toLowerCase().includes(search) ||
member['Last Name']?.toLowerCase().includes(search) ||
member.Email?.toLowerCase().includes(search)
);
console.log('[api/members.get] After search filter:', members.length);
}
if (nationality) {
members = members.filter(member => member.Nationality === nationality);
console.log('[api/members.get] After nationality filter:', members.length);
}
if (membershipStatus) {
members = members.filter(member => member['Membership Status'] === membershipStatus);
console.log('[api/members.get] After status filter:', members.length);
}
if (duesPaid === 'true' || duesPaid === 'false') {
members = members.filter(member => member['Current Year Dues Paid'] === duesPaid);
console.log('[api/members.get] After dues filter:', members.length);
}
// Add computed fields
const processedMembers = members.map(member => ({
...member,
FullName: `${member['First Name'] || ''} ${member['Last Name'] || ''}`.trim(),
FormattedPhone: formatPhoneNumber(member.Phone)
}));
console.log('[api/members.get] ✅ Successfully processed', processedMembers.length, 'members');
return {
success: true,
data: {
list: processedMembers,
totalCount: processedMembers.length,
filters: {
searchTerm,
nationality,
membershipStatus,
duesPaid: duesPaid ? duesPaid === 'true' : undefined
}
}
};
} catch (error: any) {
console.error('[api/members.get] ❌ Error fetching members:', error);
handleNocoDbError(error, 'getMembers', 'Members');
}
});
// Utility function to format phone numbers
function formatPhoneNumber(phone: string): string {
if (!phone) return '';
// Remove all non-digits
const cleaned = phone.replace(/\D/g, '');
// Format based on length
if (cleaned.length === 10) {
return `(${cleaned.substring(0, 3)}) ${cleaned.substring(3, 6)}-${cleaned.substring(6)}`;
} else if (cleaned.length === 11 && cleaned.startsWith('1')) {
return `+1 (${cleaned.substring(1, 4)}) ${cleaned.substring(4, 7)}-${cleaned.substring(7)}`;
}
return phone; // Return original if we can't format it
}