'use client' import { useState } from 'react' import { toast } from 'sonner' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { startDuesCheckout, startBillingPortal } from '@/lib/actions' import { DUES_PLATFORM_LABEL, type DuesLinkPlatform } from '@/lib/dues-payments-logic' type Billing = { status: string | null currentPeriodEnd: string | null hasCustomer: boolean configured: boolean } | null export type DuesMethod = { platform: string url: string instructions: string | null } const PAID = new Set(['active', 'trialing']) const platformLabel = (p: string) => DUES_PLATFORM_LABEL[p as DuesLinkPlatform] ?? p export function DuesCard({ billing, methods = [] }: { billing: Billing; methods?: DuesMethod[] }) { const [busy, setBusy] = useState(false) const paid = !!billing?.status && PAID.has(billing.status) const stripeReady = !!billing?.configured const hasAltMethods = methods.length > 0 async function go(fn: () => Promise<{ error?: string } | { data: { url: string } }>) { setBusy(true) const res = await fn() if ('error' in res && res.error) { setBusy(false) return toast.error(res.error) } window.location.href = (res as { data: { url: string } }).data.url } return (

Membership dues

{billing?.status ? (

{billing.status} {billing.currentPeriodEnd ? ` · renews ${new Date(billing.currentPeriodEnd).toLocaleDateString()}` : ''}

) : stripeReady ? (

No active dues subscription.

) : null}
{billing?.status && ( {paid ? 'Current' : 'Action needed'} )}
{/* Stripe Checkout / Portal: only when the space has Stripe set up. */} {(stripeReady && (!paid || billing?.hasCustomer)) && (
{!paid && ( )} {billing?.hasCustomer && ( )}
)} {/* Admin-configured external links. Shown when the member still owes dues. */} {!paid && hasAltMethods && (

{stripeReady ? 'Other ways to pay' : 'Pay your dues'}

{methods.map(m => (
Pay with {platformLabel(m.platform)} {m.instructions && (

{m.instructions}

)}
open ↗
))}

These open an external payment page. Your payment is recorded by a treasurer after it clears.

)} {/* Nothing set up at all. */} {!paid && !stripeReady && !hasAltMethods && (

Online dues payment isn’t set up for this space yet. Contact an admin to pay your dues.

)}
) }