monacousa-portal/src/routes/(app)/board/members/+page.server.ts

63 lines
1.7 KiB
TypeScript
Raw Normal View History

import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals, url }) => {
const searchQuery = url.searchParams.get('search') || '';
const statusFilter = url.searchParams.get('status') || 'all';
const roleFilter = url.searchParams.get('role') || 'all';
// Build the query
let query = locals.supabase
.from('members_with_dues')
.select('*')
.order('last_name', { ascending: true });
// Apply filters
if (statusFilter !== 'all') {
query = query.eq('status_name', statusFilter);
}
if (roleFilter !== 'all') {
query = query.eq('role', roleFilter);
}
const { data: members } = await query;
// Filter by search query in application (for name/email search)
let filteredMembers = members || [];
if (searchQuery) {
const lowerSearch = searchQuery.toLowerCase();
filteredMembers = filteredMembers.filter(
(m: any) =>
m.first_name?.toLowerCase().includes(lowerSearch) ||
m.last_name?.toLowerCase().includes(lowerSearch) ||
m.email?.toLowerCase().includes(lowerSearch) ||
m.member_id?.toLowerCase().includes(lowerSearch)
);
}
// Get membership statuses for filter dropdown
const { data: statuses } = await locals.supabase
.from('membership_statuses')
.select('*')
.order('sort_order', { ascending: true });
// Calculate stats
const stats = {
total: members?.length || 0,
active: members?.filter((m: any) => m.status_name === 'active').length || 0,
pending: members?.filter((m: any) => m.status_name === 'pending').length || 0,
inactive: members?.filter((m: any) => m.status_name === 'inactive').length || 0
};
return {
members: filteredMembers,
statuses: statuses || [],
stats,
filters: {
search: searchQuery,
status: statusFilter,
role: roleFilter
}
};
};