'use client' import { useEffect, useState } from 'react' import { useParams, useRouter } from 'next/navigation' import { getAdminOrg, grantPlan, type AdminOrgDetail } from '@/lib/api/admin' import { Button, LoadingOverlay, Select, toast } from '@ciphera-net/ui' import { formatDate, formatDateTime } from '@/lib/utils/formatDate' function addMonths(d: Date, months: number) { const out = new Date(d) out.setMonth(out.getMonth() + months) return out } function addYears(d: Date, years: number) { const out = new Date(d) out.setFullYear(out.getFullYear() + years) return out } const PLAN_OPTIONS = [ { value: 'free', label: 'Free' }, { value: 'solo', label: 'Solo' }, { value: 'team', label: 'Team' }, { value: 'business', label: 'Business' }, ] const INTERVAL_OPTIONS = [ { value: 'month', label: 'Monthly' }, { value: 'year', label: 'Yearly' }, ] const LIMIT_OPTIONS = [ { value: '1000', label: '1k (Free)' }, { value: '10000', label: '10k (Solo)' }, { value: '100000', label: '100k (Team)' }, { value: '1000000', label: '1M (Business)' }, { value: '5000000', label: '5M' }, { value: '10000000', label: '10M' }, ] export default function AdminOrgDetailPage() { const params = useParams() const router = useRouter() const orgId = params.id as string const [org, setOrg] = useState(null) const [loading, setLoading] = useState(true) const [submitting, setSubmitting] = useState(false) // Form state const [planId, setPlanId] = useState('free') const [interval, setInterval] = useState('month') const [limit, setLimit] = useState('1000') const [periodEnd, setPeriodEnd] = useState('') useEffect(() => { if (orgId) { getAdminOrg(orgId) .then((data) => { setOrg({ ...data.billing, sites: data.sites }) setPlanId(data.billing.plan_id) setInterval(data.billing.billing_interval || 'month') setLimit(data.billing.pageview_limit.toString()) // Format date for input type="datetime-local" or similar if (data.billing.current_period_end) { setPeriodEnd(new Date(data.billing.current_period_end).toISOString().slice(0, 16)) } else { // Default to 1 month from now setPeriodEnd(addMonths(new Date(), 1).toISOString().slice(0, 16)) } }) .catch(() => { toast.error('Failed to load organization') router.push('/admin/orgs') }) .finally(() => setLoading(false)) } }, [orgId, router]) const handleGrantPlan = async (e: React.FormEvent) => { e.preventDefault() if (!org) return setSubmitting(true) try { await grantPlan(org.organization_id, { plan_id: planId, billing_interval: interval, pageview_limit: parseInt(limit), period_end: new Date(periodEnd).toISOString(), }) toast.success('Plan granted successfully') router.refresh() // Reload data to show updates const data = await getAdminOrg(orgId) setOrg({ ...data.billing, sites: data.sites }) } catch (error) { toast.error('Failed to grant plan') } finally { setSubmitting(false) } } if (loading) return if (!org) return
Organization not found
return (

{org.business_name || 'Unnamed Organization'}

{org.organization_id}
{/* Current Status */}

Current Status

Plan: {org.plan_id} Status: {org.subscription_status} Limit: {new Intl.NumberFormat().format(org.pageview_limit)} Interval: {org.billing_interval} Period End: {org.current_period_end ? formatDateTime(new Date(org.current_period_end)) : '-'} Customer ID: {org.billing_customer_id || '-'} Subscription ID: {org.billing_subscription_id || '-'}
{/* Sites */}

Sites ({org.sites.length})

    {org.sites.map((site) => (
  • {site.domain} {formatDate(new Date(site.created_at))}
  • ))} {org.sites.length === 0 &&
  • No sites found
  • }
{/* Grant Plan Form */}

Grant Plan (Manual Override)

setPeriodEnd(e.target.value)} className="w-full px-4 py-2 border border-neutral-200 dark:border-neutral-800 rounded-lg bg-white dark:bg-neutral-900 text-white focus:outline-none focus:ring-2 focus:ring-brand-orange focus:ring-offset-2" required />
) }