import { createClient } from '@/lib/supabase/server' import Link from 'next/link' import { redirect } from 'next/navigation' function IcoUsers({ className }: { className?: string }) { return } function IcoDues({ className }: { className?: string }) { return } function IcoTask({ className }: { className?: string }) { return } function IcoPay({ className }: { className?: string }) { return } function IcoPlus({ className }: { className?: string }) { return } export default async function DashboardPage() { 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, display_name, role') .eq('user_id', user.id) .in('status', ['current', 'unverified', 'late']) .maybeSingle() if (!member?.space_id) redirect('/signup') const spaceId = member.space_id const [ { count: activeMembers }, { count: openTasks }, { count: unlinkedPayments }, { data: tasks }, { data: projects }, { data: activity }, ] = await Promise.all([ supabase.from('space_members').select('*', { count: 'exact', head: true }).eq('space_id', spaceId).eq('status', 'current'), supabase.from('tasks').select('*', { count: 'exact', head: true }).eq('space_id', spaceId).in('status', ['open', 'claimed', 'in_progress']), supabase.from('payments').select('*', { count: 'exact', head: true }).eq('space_id', spaceId).eq('link_status', 'unlinked'), supabase.from('tasks').select('*').eq('space_id', spaceId).neq('status', 'done').order('due_date', { ascending: true, nullsFirst: false }).limit(5), supabase.from('projects').select('*').eq('space_id', spaceId).in('status', ['in_progress', 'blocked', 'review']).limit(3), supabase.from('activity_log').select('*').eq('space_id', spaceId).order('created_at', { ascending: false }).limit(6), ]) const overdueTasks = (tasks ?? []).filter((t: any) => t.due_date && new Date(t.due_date) < new Date()) const stats = [ { label: 'Active Members', value: activeMembers ?? 0, Ico: IcoUsers, sub: 'in your space', warn: false }, { label: 'Dues Current', value: Math.max(0, (activeMembers ?? 0) - (unlinkedPayments ?? 0)), Ico: IcoDues, sub: `${unlinkedPayments ?? 0} unpaid / unverified`, warn: (unlinkedPayments ?? 0) > 0 }, { label: 'Open Tasks', value: openTasks ?? 0, Ico: IcoTask, sub: `${overdueTasks.length} overdue`, warn: (openTasks ?? 0) > 0 }, { label: 'Unlinked Payments', value: unlinkedPayments ?? 0, Ico: IcoPay, sub: 'needs reconciliation', warn: (unlinkedPayments ?? 0) > 0 }, ] return (
{value}
{sub}
Quick Chores
All tasks{task.title}
{[task.area, task.recurrence && task.recurrence !== 'none' ? `${task.recurrence}` : null, task.due_date ? `due ${new Date(task.due_date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}` : null].filter(Boolean).join(' · ')}
Active Projects
All projects{project.title}
{project.status.replace(/_/g, ' ').toUpperCase()}{project.description}
}Payment Alerts
ReconcileConnect a payment platform {' '}to see alerts here.
Recent Activity
{item.display_name || 'System'}{' '}{item.action}
{new Date(item.created_at).toLocaleDateString()}
No recent activity yet.
)}