'use client'; import { useCallback, useEffect, useState } from 'react'; import { apiService, usePreviewStepLocalizedContent, type ManageSubscriptionsResponse } from '@funnelsgrove/runtime'; import { subscriptionDashboardContent } from '@/steps/content/subscription-dashboard.content'; export default function ManageSubscriptionPage() { const content = usePreviewStepLocalizedContent('subscription-dashboard', subscriptionDashboardContent); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [updatingSubscriptionId, setUpdatingSubscriptionId] = useState(null); const load = useCallback(async () => { setLoading(true); setError(null); try { const payload = await apiService.getManageSubscriptions(); setData(payload); } catch (err) { setError(err instanceof Error ? err.message : content.loadError); } finally { setLoading(false); } }, [content.loadError]); useEffect(() => { void load(); }, [load]); const mutate = async (subscriptionId: string, action: 'cancel' | 'renew') => { setUpdatingSubscriptionId(subscriptionId); setError(null); try { const payload = await apiService.updateSubscription({ subscriptionId, action, }); setData(payload); } catch (err) { setError(err instanceof Error ? err.message : (action === 'cancel' ? content.cancelError : content.renewError)); } finally { setUpdatingSubscriptionId(null); } }; return (

{content.brand}

{content.title}

{content.description}

{loading ?

{content.loading}

: null} {error ?

{error}

: null} {!loading && data?.user ? (

{content.userId} {data.user.user_id}

{content.email} {data.user.email || content.notProvided}

{content.status} {data.user.subscriptionStatus || content.unknown}

{content.events} {data.eventsCount}

) : null} {!loading && (!data || data.subscriptions.length === 0) ? (

{content.empty}

) : null} {!loading && data?.subscriptions.length ? (
    {data.subscriptions.map((subscription) => (
  • {subscription.providerSubscriptionId}

    {subscription.environment.toUpperCase()} ยท {subscription.status}

    {subscription.cancelAtPeriodEnd ? content.cancelAtEnd : content.autoRenew}

    {subscription.currentPeriodEnd ? (

    {content.periodEnds}{' '} {new Date(subscription.currentPeriodEnd).toLocaleString()}

    ) : null}
    {subscription.cancelAtPeriodEnd ? ( ) : ( )}
  • ))}
) : null}
{manageSubscriptionStyles ? : null}
); } const manageSubscriptionStyles = ` .manage-subscription-page { min-height: 100svh; display: flex; justify-content: center; padding: 24px; background: var(--color-bg); font-family: var(--font-family-base); } .manage-subscription-card { width: min(760px, 100%); border-radius: 20px; background: var(--color-surface); box-shadow: 0 12px 40px rgb(21 39 113 / 10%); padding: 24px; } .manage-subscription-tag { margin: 0; color: var(--color-accent); font-size: 13px; font-weight: 700; line-height: 1.2; text-transform: uppercase; letter-spacing: 0.06em; } .manage-subscription-title { margin: 8px 0 0; color: var(--color-text); font-size: 32px; line-height: 1.15; } .manage-subscription-description { margin: 10px 0 0; color: var(--color-text-muted); font-size: 16px; line-height: 1.45; } .manage-subscription-muted { margin-top: 20px; color: var(--color-text-muted); } .manage-subscription-error { margin-top: 20px; border-radius: 12px; background: #ffecec; color: var(--color-danger); padding: 12px; } .manage-subscription-user { margin-top: 20px; border-radius: 12px; border: 1px solid var(--color-border); padding: 14px; } .manage-subscription-user p { margin: 6px 0; color: var(--color-text); } .manage-subscription-list { list-style: none; margin: 20px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; } .manage-subscription-item { border: 1px solid var(--color-border); border-radius: 14px; padding: 14px; display: flex; justify-content: space-between; gap: 14px; } .manage-subscription-item-title { margin: 0; color: var(--color-text); font-size: 15px; font-weight: 700; } .manage-subscription-item-meta { margin: 6px 0 0; color: var(--color-text-muted); font-size: 13px; } .manage-subscription-actions { display: flex; align-items: center; } .manage-subscription-button { border: none; border-radius: 999px; background: var(--color-button); color: var(--color-button-text); font-weight: 700; padding: 10px 16px; cursor: pointer; } .manage-subscription-button.is-secondary { background: var(--color-accent); } .manage-subscription-button:disabled { opacity: 0.6; cursor: default; } .manage-subscription-refresh { margin-top: 20px; border: 1px solid var(--color-border); border-radius: 999px; background: transparent; color: var(--color-accent); font-weight: 700; padding: 10px 16px; cursor: pointer; } `;