diff --git a/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx b/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx index f413f8a50..4cfc90936 100644 --- a/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/AdminPlanSection.tsx @@ -13,9 +13,12 @@ import { InfoBanner } from '@app/components/shared/InfoBanner'; import { useLicenseAlert } from '@app/hooks/useLicenseAlert'; import { isSupabaseConfigured } from '@app/services/supabaseClient'; import { getPreferredCurrency, setCachedCurrency } from '@app/utils/currencyDetection'; +import { useLoginRequired } from '@app/hooks/useLoginRequired'; +import LoginRequiredBanner from '@core/components/shared/config/LoginRequiredBanner'; const AdminPlanSection: React.FC = () => { const { t, i18n } = useTranslation(); + const { loginEnabled, validateLoginEnabled } = useLoginRequired(); const { openCheckout } = useCheckout(); const { licenseInfo, refetchLicense } = useLicense(); const [currency, setCurrency] = useState(() => { @@ -39,6 +42,11 @@ const AdminPlanSection: React.FC = () => { }, [error]); const handleSaveLicense = async () => { + // Block save if login is disabled + if (!validateLoginEnabled()) { + return; + } + try { setSavingLicense(true); // Allow empty string to clear/remove license @@ -86,6 +94,11 @@ const AdminPlanSection: React.FC = () => { ]; const handleManageClick = useCallback(async () => { + // Block access if login is disabled + if (!validateLoginEnabled()) { + return; + } + try { // Only allow PRO or ENTERPRISE licenses to access billing portal if (!licenseInfo?.licenseType || licenseInfo.licenseType === 'NORMAL') { @@ -112,7 +125,7 @@ const AdminPlanSection: React.FC = () => { body: error.message || 'Please try again or contact support.', }); } - }, [licenseInfo, t]); + }, [licenseInfo, t, validateLoginEnabled]); const handleCurrencyChange = useCallback((newCurrency: string) => { setCurrency(newCurrency); @@ -122,6 +135,11 @@ const AdminPlanSection: React.FC = () => { const handleUpgradeClick = useCallback( (planGroup: PlanTierGroup) => { + // Block access if login is disabled + if (!validateLoginEnabled()) { + return; + } + // Only allow upgrades for server and enterprise tiers if (planGroup.tier === 'free') { return; @@ -151,7 +169,7 @@ const AdminPlanSection: React.FC = () => { }, }); }, - [openCheckout, currency, refetch, licenseInfo, t] + [openCheckout, currency, refetch, licenseInfo, t, validateLoginEnabled] ); const shouldShowLicenseWarning = licenseAlert.active && licenseAlert.audience === 'admin'; @@ -200,7 +218,9 @@ const AdminPlanSection: React.FC = () => { return (
- {shouldShowLicenseWarning && ( + + + {shouldShowLicenseWarning && ( { currency={currency} onCurrencyChange={handleCurrencyChange} currencyOptions={currencyOptions} + loginEnabled={loginEnabled} /> @@ -288,11 +309,11 @@ const AdminPlanSection: React.FC = () => { onChange={(e) => setLicenseKeyInput(e.target.value)} placeholder={licenseInfo?.licenseKey || '00000000-0000-0000-0000-000000000000'} type="password" - disabled={savingLicense} + disabled={!loginEnabled || savingLicense} /> - diff --git a/frontend/src/proprietary/components/shared/config/configSections/plan/AvailablePlansSection.tsx b/frontend/src/proprietary/components/shared/config/configSections/plan/AvailablePlansSection.tsx index 80d651893..a3b8800d1 100644 --- a/frontend/src/proprietary/components/shared/config/configSections/plan/AvailablePlansSection.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/plan/AvailablePlansSection.tsx @@ -15,6 +15,7 @@ interface AvailablePlansSectionProps { currency?: string; onCurrencyChange?: (currency: string) => void; currencyOptions?: { value: string; label: string }[]; + loginEnabled?: boolean; } const AvailablePlansSection: React.FC = ({ @@ -25,6 +26,7 @@ const AvailablePlansSection: React.FC = ({ currency, onCurrencyChange, currencyOptions, + loginEnabled = true, }) => { const { t } = useTranslation(); const [showComparison, setShowComparison] = useState(false); @@ -91,6 +93,7 @@ const AvailablePlansSection: React.FC = ({ clearable={false} w={300} comboboxProps={{ withinPortal: true, zIndex: Z_INDEX_OVER_CONFIG_MODAL }} + disabled={!loginEnabled} /> )} @@ -113,6 +116,7 @@ const AvailablePlansSection: React.FC = ({ currentTier={currentTier} onUpgradeClick={onUpgradeClick} onManageClick={onManageClick} + loginEnabled={loginEnabled} /> ))}
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 dff579dee..7dff90f8e 100644 --- a/frontend/src/proprietary/components/shared/config/configSections/plan/PlanCard.tsx +++ b/frontend/src/proprietary/components/shared/config/configSections/plan/PlanCard.tsx @@ -15,9 +15,10 @@ interface PlanCardProps { currentTier?: 'free' | 'server' | 'enterprise' | null; onUpgradeClick: (planGroup: PlanTierGroup) => void; onManageClick?: () => void; + loginEnabled?: boolean; } -const PlanCard: React.FC = ({ planGroup, isCurrentTier, isDowngrade, currentLicenseInfo, currentTier, onUpgradeClick, onManageClick }) => { +const PlanCard: React.FC = ({ planGroup, isCurrentTier, isDowngrade, currentLicenseInfo, currentTier, onUpgradeClick, onManageClick, loginEnabled = true }) => { const { t } = useTranslation(); // Render Free plan @@ -174,7 +175,7 @@ const PlanCard: React.FC = ({ planGroup, isCurrentTier, isDowngra variant={isCurrentTier ? 'filled' : isDowngrade ? 'filled' : isEnterpriseBlockedForFree ? 'light' : 'filled'} fullWidth onClick={() => isCurrentTier && onManageClick ? onManageClick() : onUpgradeClick(planGroup)} - disabled={isDowngrade || isEnterpriseBlockedForFree} + disabled={!loginEnabled || isDowngrade || isEnterpriseBlockedForFree} > {isCurrentTier ? t('plan.manage', 'Manage')