From 88ebd03ba0d53dd46a4ae296461b2bdfa4ef4497 Mon Sep 17 00:00:00 2001 From: Connor Yoh Date: Mon, 24 Nov 2025 11:58:02 +0000 Subject: [PATCH] Manage button on cards --- .../configSections/AdminPlanSection.tsx | 62 +++++++++---------- .../plan/AvailablePlansSection.tsx | 51 +++++++++++---- .../config/configSections/plan/PlanCard.tsx | 13 ++-- .../proprietary/constants/planConstants.ts | 2 + 4 files changed, 76 insertions(+), 52 deletions(-) diff --git a/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx b/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx index f5c6229748..1c47ad2a81 100644 --- a/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx @@ -1,5 +1,5 @@ import React, { useState, useCallback, useEffect } from 'react'; -import { Divider, Loader, Alert, Select, Group, Text, Collapse, Button, TextInput, Stack, Paper } from '@mantine/core'; +import { Divider, Loader, Alert, Group, Text, Collapse, Button, TextInput, Stack, Paper } from '@mantine/core'; import { useTranslation } from 'react-i18next'; import { usePlans } from '@app/hooks/usePlans'; import licenseService, { PlanTierGroup, mapLicenseToTier } from '@app/services/licenseService'; @@ -9,8 +9,6 @@ import AvailablePlansSection from '@app/components/shared/config/configSections/ import StaticPlanSection from '@app/components/shared/config/configSections/plan/StaticPlanSection'; import { alert } from '@app/components/toast'; import LocalIcon from '@app/components/shared/LocalIcon'; -import { Z_INDEX_OVER_CONFIG_MODAL } from '@app/styles/zIndex'; -import { ManageBillingButton } from '@app/components/shared/ManageBillingButton'; import { isSupabaseConfigured } from '@app/services/supabaseClient'; const AdminPlanSection: React.FC = () => { @@ -80,6 +78,30 @@ const AdminPlanSection: React.FC = () => { { value: 'idr', label: 'Indonesian rupiah (IDR, Rp)' }, ]; + const handleManageClick = useCallback(async () => { + try { + if (!licenseInfo?.licenseKey) { + throw new Error('No license key found. Please activate a license first.'); + } + + // Create billing portal session with license key + const response = await licenseService.createBillingPortalSession( + window.location.href, + licenseInfo.licenseKey + ); + + // Open billing portal in new tab + window.open(response.url, '_blank'); + } catch (error: any) { + console.error('Failed to open billing portal:', error); + alert({ + alertType: 'error', + title: t('billing.portal.error', 'Failed to open billing portal'), + body: error.message || 'Please try again or contact support.', + }); + } + }, [licenseInfo, t]); + const handleUpgradeClick = useCallback( (planGroup: PlanTierGroup) => { // Only allow upgrades for server and enterprise tiers @@ -143,40 +165,14 @@ const AdminPlanSection: React.FC = () => { return (
- {/* Currency Selection & Manage Subscription */} - - - - - {t('plan.currency', 'Currency')} - - onCurrencyChange(value || 'gbp')} + data={currencyOptions} + searchable + clearable={false} + w={300} + comboboxProps={{ withinPortal: true, zIndex: Z_INDEX_OVER_CONFIG_MODAL }} + /> + )} +
= ({ currentLicenseInfo={currentLicenseInfo} currentTier={currentTier} onUpgradeClick={onUpgradeClick} + onManageClick={onManageClick} /> ))}
diff --git a/frontend/src/proprietary/components/shared/config/configSections/plan/PlanCard.tsx b/frontend/src/proprietary/components/shared/config/configSections/plan/PlanCard.tsx index 2594d91d48..564f6c11b6 100644 --- a/frontend/src/proprietary/components/shared/config/configSections/plan/PlanCard.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/plan/PlanCard.tsx @@ -14,9 +14,10 @@ interface PlanCardProps { currentLicenseInfo?: LicenseInfo | null; currentTier?: 'free' | 'server' | 'enterprise' | null; onUpgradeClick: (planGroup: PlanTierGroup) => void; + onManageClick?: () => void; } -const PlanCard: React.FC = ({ planGroup, isCurrentTier, isDowngrade, currentLicenseInfo, currentTier, onUpgradeClick }) => { +const PlanCard: React.FC = ({ planGroup, isCurrentTier, isDowngrade, currentLicenseInfo, currentTier, onUpgradeClick, onManageClick }) => { const { t } = useTranslation(); // Render Free plan @@ -160,15 +161,15 @@ const PlanCard: React.FC = ({ planGroup, isCurrentTier, isDowngra withArrow >