Add frontend loading imporvements

This commit is contained in:
Urtzi Alfaro
2025-12-27 21:30:42 +01:00
parent 6e3a6590d6
commit 54662dde79
21 changed files with 799 additions and 363 deletions

View File

@@ -3,6 +3,7 @@
*/
import { useState, useEffect, useCallback } from 'react';
import { useQuery } from '@tanstack/react-query';
import { subscriptionService } from '../services/subscription';
import {
SUBSCRIPTION_TIERS,
@@ -34,49 +35,32 @@ export interface SubscriptionInfo {
}
export const useSubscription = () => {
const [subscriptionInfo, setSubscriptionInfo] = useState<SubscriptionInfo>({
plan: 'starter',
status: 'active',
features: {},
loading: true,
});
const currentTenant = useCurrentTenant();
const user = useAuthUser();
const tenantId = currentTenant?.id || user?.tenant_id;
const { notifySubscriptionChanged, subscriptionVersion } = useSubscriptionEvents();
const { subscriptionVersion } = useSubscriptionEvents();
// Load subscription data
const loadSubscriptionData = useCallback(async () => {
if (!tenantId) {
setSubscriptionInfo(prev => ({ ...prev, loading: false, error: 'No tenant ID available' }));
return;
}
// Initialize with tenant's subscription_plan if available, otherwise default to starter
const initialPlan = currentTenant?.subscription_plan || currentTenant?.subscription_tier || 'starter';
try {
setSubscriptionInfo(prev => ({ ...prev, loading: true, error: undefined }));
// Use React Query to fetch subscription data (automatically deduplicates & caches)
const { data: usageSummary, isLoading, error, refetch } = useQuery({
queryKey: ['subscription-usage', tenantId, subscriptionVersion],
queryFn: () => subscriptionService.getUsageSummary(tenantId!),
enabled: !!tenantId,
staleTime: 30 * 1000, // Cache for 30 seconds (matches backend cache)
gcTime: 5 * 60 * 1000, // Keep in cache for 5 minutes
retry: 1,
});
const usageSummary = await subscriptionService.getUsageSummary(tenantId);
setSubscriptionInfo({
plan: usageSummary.plan,
status: usageSummary.status,
features: usageSummary.usage || {},
loading: false,
});
} catch (error) {
console.error('Error loading subscription data:', error);
setSubscriptionInfo(prev => ({
...prev,
loading: false,
error: 'Failed to load subscription data'
}));
}
}, [tenantId]);
useEffect(() => {
loadSubscriptionData();
}, [loadSubscriptionData, subscriptionVersion]);
// Derive subscription info from query data or tenant fallback
const subscriptionInfo: SubscriptionInfo = {
plan: usageSummary?.plan || initialPlan,
status: usageSummary?.status || 'active',
features: usageSummary?.usage || {},
loading: isLoading,
error: error ? 'Failed to load subscription data' : undefined,
};
// Check if user has a specific feature
const hasFeature = useCallback(async (featureName: string): Promise<SubscriptionFeature> => {
@@ -175,7 +159,7 @@ export const useSubscription = () => {
canAccessForecasting,
canAccessAIInsights,
checkLimits,
refreshSubscription: loadSubscriptionData,
refreshSubscription: refetch,
};
};

View File

@@ -382,7 +382,8 @@ export function useControlPanelData(tenantId: string) {
},
enabled: !!tenantId,
staleTime: 20000, // 20 seconds
refetchOnMount: 'always',
refetchOnMount: true,
refetchOnWindowFocus: false,
retry: 2,
});