import Link from 'next/link' import { redirect } from 'next/navigation' import { createClient } from '@/lib/supabase/server' export const dynamic = 'force-dynamic' type SkilledMember = { id: string display_name: string | null handle: string | null role: string tier: string skills: string[] interests: string[] willing_to: string[] coi_last_disclosed_at: string | null } export default async function RecruitmentPage() { const supabase = await createClient() const { data: { user } } = await supabase.auth.getUser() if (!user) redirect('/login') const { data: member } = await supabase .from('space_members') .select('space_id, role') .eq('user_id', user.id) .in('status', ['current', 'unverified', 'late']) .maybeSingle() if (!member?.space_id) redirect('/signup') if (member.role !== 'admin' && member.role !== 'board') redirect('/dashboard') const { data: rowsRaw } = await supabase .from('space_members') .select('id, display_name, handle, role, tier, skills, interests, willing_to, coi_last_disclosed_at') .eq('space_id', member.space_id) .in('status', ['current', 'unverified', 'late']) .eq('approved', true) .order('display_name', { ascending: true }) const members = ((rowsRaw ?? []) as unknown as SkilledMember[]).filter( m => m.willing_to.length > 0 || m.skills.length > 0, ) // Group by willing_to role. const byRole = new Map() for (const m of members) { for (const w of m.willing_to) { if (!byRole.has(w)) byRole.set(w, []) byRole.get(w)!.push(m) } } const roleGroups = Array.from(byRole.entries()).sort(([a], [b]) => a.localeCompare(b)) // Members who only declared skills but no willing_to. const skillsOnly = members.filter(m => m.willing_to.length === 0 && m.skills.length > 0) return (

Recruitment

Board / admin view. Read-only.

{members.length === 0 ? (

No members have declared willingness or skills yet.

Members opt in from their profile page.

) : ( <> {roleGroups.length > 0 && (

Willing to take on

{roleGroups.map(([role, list]) => (

{role.replace(/_/g, ' ')}

    {list.map(m => (
  • {m.display_name ?? 'Unnamed'} {m.handle ? · @{m.handle} : null}

    {m.role} · {m.tier} {m.skills.length > 0 ? ` · skills: ${m.skills.join(', ')}` : ''}

    {(m.role === 'admin' || m.role === 'board' || m.role === 'treasurer') && ( {m.coi_last_disclosed_at ? 'COI on file' : 'no COI'} )}
  • ))}
))}
)} {skillsOnly.length > 0 && (

Skills declared (no role opt-in)

{skillsOnly.map(m => (

{m.display_name ?? 'Unnamed'} {m.handle ? · @{m.handle} : null}

skills: {m.skills.join(', ')}

))}
)} )}
) }