'use client' import { useState } from 'react' import { toast } from 'sonner' import { CalendarDays } from 'lucide-react' import { PageHeader, PageTitle } from '@/components/ui/page-title' import { Badge } from '@/components/ui/badge' import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty' import { signUpForClass, cancelMySignup } from '@/lib/actions' import { effectiveCapacity, SIGNUP_STATUS_LABEL } from '@/lib/classes-logic' import { SessionAttendance } from '@/components/classes/session-attendance' import { useRouter } from 'next/navigation' type Row = { id: string starts_at: string ends_at: string | null location: string | null capacity: number | null status: string notes: string | null classes: { title: string; description: string | null; payment_link: string | null; capacity: number | null } | Array<{ title: string; description: string | null; payment_link: string | null; capacity: number | null }> | null registered_count: number my_status: string | null required_form: { title: string; url: string | null; satisfied: boolean } | null } function classOf(r: Row) { return Array.isArray(r.classes) ? r.classes[0] : r.classes } export function ClassesBrowseClient({ sessions, canRunSessions, }: { sessions: unknown[] canRunSessions: boolean }) { const router = useRouter() const [rows, setRows] = useState(sessions as Row[]) const [busyId, setBusyId] = useState(null) const [openAttendance, setOpenAttendance] = useState(null) async function onSignUp(r: Row) { setBusyId(r.id) const res = await signUpForClass({ sessionId: r.id }) setBusyId(null) if ('error' in res && res.error) { toast.error(res.error) return } const status = (res as { data: { status: string } }).data.status toast.success(status === 'waitlisted' ? 'Added to the waitlist' : 'You are signed up') setRows(prev => prev.map(x => x.id === r.id ? { ...x, my_status: status, registered_count: x.registered_count + (status === 'registered' ? 1 : 0) } : x, ), ) } async function onCancel(r: Row) { setBusyId(r.id) const res = await cancelMySignup({ sessionId: r.id }) setBusyId(null) if ('error' in res && res.error) { toast.error(res.error) return } toast.success('Signup cancelled') setRows(prev => prev.map(x => x.id === r.id ? { ...x, my_status: null, registered_count: Math.max(0, x.registered_count - (r.my_status === 'registered' ? 1 : 0)) } : x, ), ) } return ( <> Classes
{rows.length === 0 ? ( No upcoming classes Check back later, or ask an organizer to schedule a session. ) : (
    {rows.map(r => { const c = classOf(r) const cap = effectiveCapacity(r.capacity, c?.capacity ?? null) const spots = cap == null ? null : Math.max(0, cap - r.registered_count) const full = cap != null && r.registered_count >= cap const formBlocked = !r.my_status && !!r.required_form && !r.required_form.satisfied return (
  • {c?.title ?? 'Class'} {r.my_status && ( {SIGNUP_STATUS_LABEL[r.my_status] ?? r.my_status} )}
    {c?.description &&

    {c.description}

    }

    {new Date(r.starts_at).toLocaleString()} {r.ends_at ? ` – ${new Date(r.ends_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}` : ''} {r.location ? ` · ${r.location}` : ''} {cap == null ? ' · open' : ` · ${spots} of ${cap} spots left`}

    {r.required_form && (

    {r.required_form.satisfied ? `Required form on file: ${r.required_form.title}` : `Requires the "${r.required_form.title}" form before signup`} {!r.required_form.satisfied && r.required_form.url && ( <> {' · '} complete it )}

    )} {r.notes &&

    {r.notes}

    } {c?.payment_link && ( payment link )}
    {r.my_status ? ( ) : formBlocked ? ( r.required_form?.url ? ( Complete required form ) : ( Form required ) ) : ( )} {canRunSessions && ( )}
    {canRunSessions && openAttendance === r.id && ( { setOpenAttendance(null); router.refresh() }} /> )}
  • ) })}
)}
) }