import { MembersListView } from '@kit/member-management/components'; import { createMemberServices } from '@kit/member-management/services'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { AccountNotFound } from '~/components/account-not-found'; const PAGE_SIZE = 25; interface Props { params: Promise<{ account: string }>; searchParams: Promise>; } export default async function MembersPage({ params, searchParams }: Props) { const { account } = await params; const search = await searchParams; const client = getSupabaseServerClient(); const { data: acct } = await client .from('accounts') .select('id') .eq('slug', account) .single(); if (!acct) return ; const { query, organization } = createMemberServices(client); const page = Number(search.page) || 1; // Parse multi-status filter const statusParam = search.status; const statusFilter = statusParam ? Array.isArray(statusParam) ? statusParam : statusParam.split(',') : undefined; const result = await query.search({ accountId: acct.id, search: search.q as string, status: statusFilter as any, duesCategoryId: search.duesCategoryId as string, sortBy: (search.sortBy as string) ?? 'last_name', sortDirection: (search.sortDirection as 'asc' | 'desc') ?? 'asc', page, pageSize: PAGE_SIZE, }); // Fetch categories and departments (always available) const [duesCategories, departments] = await Promise.all([ organization.listDuesCategories(acct.id), organization.listDepartmentsWithCounts(acct.id), ]); // Fetch tags gracefully (tables may not exist if migration hasn't run) let accountTags: Array<{ id: string; name: string; color: string }> = []; const memberTags: Record< string, Array<{ id: string; name: string; color: string }> > = {}; try { const memberIds = result.data.map((m: any) => m.id); const [tagsResult, tagAssignmentsResult] = await Promise.all([ (client.from as any)('member_tags') .select('id, name, color') .eq('account_id', acct.id) .order('sort_order'), memberIds.length > 0 ? (client.from as any)('member_tag_assignments') .select('member_id, tag_id, member_tags(id, name, color)') .in('member_id', memberIds) : { data: [] }, ]); accountTags = (tagsResult.data ?? []).map((t: any) => ({ id: String(t.id), name: String(t.name), color: String(t.color), })); for (const a of tagAssignmentsResult.data ?? []) { const memberId = String(a.member_id); const tag = a.member_tags; if (!tag) continue; if (!memberTags[memberId]) memberTags[memberId] = []; memberTags[memberId]!.push({ id: String(tag.id), name: String(tag.name), color: String(tag.color), }); } } catch { // Tags tables may not exist yet — gracefully degrade } return ( ) => ({ id: String(c.id), name: String(c.name), }), )} departments={(departments ?? []).map((d) => ({ id: String(d.id), name: String(d.name), memberCount: d.memberCount, }))} tags={accountTags} memberTags={memberTags} /> ); }