import Link from 'next/link' import { redirect } from 'next/navigation' import { Vote } from 'lucide-react' import { createClient } from '@/lib/supabase/server' import type { Proposal } from '@/types/domain' import { ProposalStatusBadge } from './proposal-badges' import { PageTitle } from '@/components/ui/page-title' import { Empty, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty' export const dynamic = 'force-dynamic' export default async function ProposalsPage() { 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') .eq('user_id', user.id) .in('status', ['current', 'unverified', 'late']) .maybeSingle() if (!member?.space_id) redirect('/signup') const { data: proposals } = await supabase .from('proposals') .select('*') .eq('space_id', member.space_id) .order('created_at', { ascending: false }) const list = (proposals ?? []) as unknown as Proposal[] const open = list.filter(p => p.status === 'open') const drafts = list.filter(p => p.status === 'draft') const decided = list.filter(p => ['decided', 'withdrawn', 'expired'].includes(p.status)) return (
Proposals New proposal
) } function Section({ title, empty, proposals }: { title: string; empty: string; proposals: Proposal[] }) { return (

{title}

{proposals.length === 0 ? ( {empty} ) : ( proposals.map(p => ) )}
) } function ProposalRow({ p }: { p: Proposal }) { const totalVotes = p.outcome_yes + p.outcome_no + p.outcome_abstain return (

{p.title}

{p.proposal_type.replace(/_/g, ' ')} {p.proposer_name ? ` · proposed by ${p.proposer_name}` : ''} {p.voting_closes_at && p.status === 'open' ? ` · closes ${new Date(p.voting_closes_at).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })}` : ''}

{p.outcome_yes} y · {p.outcome_no} n · {p.outcome_abstain} a

{totalVotes}/{p.quorum_required} for quorum

) }