'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}{stripeReady ? 'Other ways to pay' : 'Pay your dues'}
{m.instructions}
)}These open an external payment page. Your payment is recorded by a treasurer after it clears.
Online dues payment isn’t set up for this space yet. Contact an admin to pay your dues.
)}