Feature/v2/stripeorsupabaseNotEnabled (#5006)

Removed current plan section from static plan to match connected version

stripe publishable key not required to show plans or checkout in hosted
version

lazy load plans when needed not on load
This commit is contained in:
ConnorYoh
2025-11-25 17:09:41 +00:00
committed by GitHub
parent 7253b9fa6d
commit 3b8b539efc
7 changed files with 81 additions and 79 deletions
@@ -1,7 +1,6 @@
import React, { createContext, useContext, useState, useCallback, useEffect, ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import { usePlans } from '@app/hooks/usePlans';
import licenseService, { PlanTierGroup, LicenseInfo, mapLicenseToTier } from '@app/services/licenseService';
import licenseService, { PlanTierGroup, LicenseInfo, mapLicenseToTier, PlanTier } from '@app/services/licenseService';
import { StripeCheckout } from '@app/components/shared/stripeCheckout';
import { userManagementService } from '@app/services/userManagementService';
import { alert } from '@app/components/toast';
@@ -54,8 +53,33 @@ export const CheckoutProvider: React.FC<CheckoutProviderProps> = ({
licenseKey?: string;
} | null>(null);
// Load plans with current currency
const { plans, refetch: refetchPlans } = usePlans(currentCurrency);
// Lazy-loaded plans state (no fetch on mount)
const [plans, setPlans] = useState<PlanTier[]>([]);
const [plansLoaded, setPlansLoaded] = useState(false);
const [plansLoading, setPlansLoading] = useState(false);
// Lazy fetch plans only when needed
const fetchPlansIfNeeded = useCallback(async (currency: string) => {
// Don't fetch if already loading
if (plansLoading) return;
try {
setPlansLoading(true);
const response = await licenseService.getPlans(currency);
setPlans(response.plans);
setPlansLoaded(true);
} catch (error) {
console.error('Failed to fetch plans:', error);
// Don't block - let components handle the error
} finally {
setPlansLoading(false);
}
}, [plansLoading]);
const refetchPlans = useCallback(() => {
setPlansLoaded(false); // Force refetch
return fetchPlansIfNeeded(currentCurrency);
}, [currentCurrency, fetchPlansIfNeeded]);
// Handle return from hosted Stripe checkout
useEffect(() => {
@@ -89,6 +113,11 @@ export const CheckoutProvider: React.FC<CheckoutProviderProps> = ({
if (activation.success) {
console.log('License synced successfully, refreshing license context');
// Ensure plans are loaded before using them
if (!plansLoaded) {
await fetchPlansIfNeeded(currentCurrency);
}
// Refresh global license context
await refetchLicense();
await refetchPlans();
@@ -135,6 +164,11 @@ export const CheckoutProvider: React.FC<CheckoutProviderProps> = ({
if (activation.success) {
console.log(`License key activated: ${activation.licenseType}`);
// Ensure plans are loaded before using them
if (!plansLoaded) {
await fetchPlansIfNeeded(currentCurrency);
}
// Refresh global license context
await refetchLicense();
await refetchPlans();
@@ -201,7 +235,7 @@ export const CheckoutProvider: React.FC<CheckoutProviderProps> = ({
};
handleCheckoutReturn();
}, [t, refetchPlans, refetchLicense, plans]);
}, [t, refetchPlans, refetchLicense, plans, fetchPlansIfNeeded, plansLoaded, currentCurrency]);
const openCheckout = useCallback(
async (tier: 'server' | 'enterprise', options: CheckoutOptions = {}) => {
@@ -217,7 +251,11 @@ export const CheckoutProvider: React.FC<CheckoutProviderProps> = ({
const currency = options.currency || currentCurrency;
if (currency !== currentCurrency) {
setCurrentCurrency(currency);
// Plans will reload automatically via usePlans
}
// Fetch plans if not already loaded
if (!plansLoaded) {
await fetchPlansIfNeeded(currency);
}
// Fetch license info and user data for seat calculations
@@ -277,7 +315,7 @@ export const CheckoutProvider: React.FC<CheckoutProviderProps> = ({
setIsLoading(false);
}
},
[currentCurrency, plans]
[currentCurrency, plans, plansLoaded, fetchPlansIfNeeded]
);
const closeCheckout = useCallback(() => {