From ef7b3d2b4950faef56500564a24d974e6cf0f513 Mon Sep 17 00:00:00 2001 From: ajaysi Date: Fri, 8 May 2026 12:06:47 +0530 Subject: [PATCH] fix(01-code-splitting): convert billing, blog, content-planning, error-boundary, pricing, alerts MUI icons - Converted barrel imports to individual imports across 8 files - Affected files: billing (2), BlogWriter (1), ContentPlanningDashboard (2), ErrorBoundary (1), Pricing (1), AlertsBadge (1) --- .../BlogWriter/BlogWriterPhasesSection.tsx | 3 +- .../components/CardExpansionWrapper.tsx | 2 +- .../components/StrategyErrorBoundary.tsx | 2 +- frontend/src/components/ErrorBoundary.tsx | 4 ++- .../src/components/Pricing/PricingPage.tsx | 30 ++++++++++--------- .../billing/ComprehensiveAPIBreakdown.tsx | 2 +- .../CostOptimizationRecommendations.tsx | 2 +- .../src/components/shared/AlertsBadge.tsx | 18 ++++++----- 8 files changed, 36 insertions(+), 27 deletions(-) diff --git a/frontend/src/components/BlogWriter/BlogWriterPhasesSection.tsx b/frontend/src/components/BlogWriter/BlogWriterPhasesSection.tsx index 3a6acf84..29e90e9a 100644 --- a/frontend/src/components/BlogWriter/BlogWriterPhasesSection.tsx +++ b/frontend/src/components/BlogWriter/BlogWriterPhasesSection.tsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import { Container, Grid, Card, CardContent, Typography, Box, Stack, Chip } from '@mui/material'; -import { CheckCircle, AutoAwesome } from '@mui/icons-material'; +import CheckCircle from '@mui/icons-material/CheckCircle'; +import AutoAwesome from '@mui/icons-material/AutoAwesome'; interface PhaseFeature { title: string; diff --git a/frontend/src/components/ContentPlanningDashboard/components/ContentStrategyBuilder/components/CardExpansionWrapper.tsx b/frontend/src/components/ContentPlanningDashboard/components/ContentStrategyBuilder/components/CardExpansionWrapper.tsx index 9212ba7f..e683cc2e 100644 --- a/frontend/src/components/ContentPlanningDashboard/components/ContentStrategyBuilder/components/CardExpansionWrapper.tsx +++ b/frontend/src/components/ContentPlanningDashboard/components/ContentStrategyBuilder/components/CardExpansionWrapper.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import { Box, Paper } from '@mui/material'; import { motion, AnimatePresence } from 'framer-motion'; -import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; interface CardExpansionWrapperProps { children: React.ReactNode; diff --git a/frontend/src/components/ContentPlanningDashboard/components/StrategyIntelligence/components/StrategyErrorBoundary.tsx b/frontend/src/components/ContentPlanningDashboard/components/StrategyIntelligence/components/StrategyErrorBoundary.tsx index ccc9ea78..75e9a42d 100644 --- a/frontend/src/components/ContentPlanningDashboard/components/StrategyIntelligence/components/StrategyErrorBoundary.tsx +++ b/frontend/src/components/ContentPlanningDashboard/components/StrategyIntelligence/components/StrategyErrorBoundary.tsx @@ -1,6 +1,6 @@ import React, { Component, ErrorInfo, ReactNode } from 'react'; import { Box, Typography, Alert, Button } from '@mui/material'; -import { Refresh as RefreshIcon } from '@mui/icons-material'; +import RefreshIcon from '@mui/icons-material/Refresh'; interface Props { children: ReactNode; diff --git a/frontend/src/components/ErrorBoundary.tsx b/frontend/src/components/ErrorBoundary.tsx index 14ab216e..1e571d40 100644 --- a/frontend/src/components/ErrorBoundary.tsx +++ b/frontend/src/components/ErrorBoundary.tsx @@ -7,7 +7,9 @@ import { Alert, AlertTitle } from '@mui/material'; -import { Refresh, BugReport, Home } from '@mui/icons-material'; +import Refresh from '@mui/icons-material/Refresh'; +import BugReport from '@mui/icons-material/BugReport'; +import Home from '@mui/icons-material/Home'; interface Props { children: ReactNode; diff --git a/frontend/src/components/Pricing/PricingPage.tsx b/frontend/src/components/Pricing/PricingPage.tsx index db18b630..60c77a23 100644 --- a/frontend/src/components/Pricing/PricingPage.tsx +++ b/frontend/src/components/Pricing/PricingPage.tsx @@ -18,10 +18,11 @@ import { Backdrop, Snackbar, } from '@mui/material'; -import { Warning } from '@mui/icons-material'; +import Warning from '@mui/icons-material/Warning'; import { useNavigate } from 'react-router-dom'; import { apiClient } from '../../api/client'; import { restoreNavigationState, saveCurrentPhaseForTool } from '../../utils/navigationState'; +import { getEnabledFeatures, getDefaultLandingRoute } from '../../utils/demoMode'; import PlanCard from './PricingPage/PlanCard'; export interface SubscriptionPlan { @@ -97,14 +98,16 @@ const PricingPage: React.FC = () => { fetchPlans(); }, []); - const isPodcastOnlyDemoMode = () => { + const isFeatureLimitedMode = (): boolean => { const appMode = (localStorage.getItem('app_mode') || '').toLowerCase(); const demoMode = (localStorage.getItem('demo_mode') || '').toLowerCase(); const podcastOnlyDemoMode = (localStorage.getItem('podcast_only_demo_mode') || '').toLowerCase(); const envAppMode = (process.env.REACT_APP_APP_MODE || '').toLowerCase(); const envDemoMode = (process.env.REACT_APP_DEMO_MODE || '').toLowerCase(); + const enabledFeatures = getEnabledFeatures(); return ( + !enabledFeatures.has('all') || podcastOnlyDemoMode === 'true' || appMode === 'podcast-only' || demoMode === 'podcast-only' || @@ -114,10 +117,9 @@ const PricingPage: React.FC = () => { }; const redirectAfterSubscription = () => { - // In podcast-only demo mode, always force users into podcast flow. - // Never send demo users to onboarding. - if (isPodcastOnlyDemoMode()) { - navigate('/podcast-maker'); + if (isFeatureLimitedMode()) { + const route = getDefaultLandingRoute(); + navigate(route); return; } @@ -235,8 +237,8 @@ const PricingPage: React.FC = () => { const response = await apiClient.post('/api/subscription/create-checkout-session', { tier: plan.tier, billing_cycle: yearlyBilling ? 'yearly' : 'monthly', - success_url: isPodcastOnlyDemoMode() - ? `${window.location.origin}/podcast-maker?subscription=success` + success_url: isFeatureLimitedMode() + ? `${window.location.origin}${getDefaultLandingRoute()}?subscription=success` : `${window.location.origin}/dashboard?subscription=success`, cancel_url: `${window.location.origin}/pricing?subscription=cancel`, }); @@ -254,9 +256,9 @@ const PricingPage: React.FC = () => { 'Stripe checkout is required but REACT_APP_STRIPE_PUBLISHABLE_KEY is not configured.' ); } else { - // Stripe not configured - warn in demo mode - if (isPodcastOnlyDemoMode()) { - console.warn('[PricingPage] ⚠️ DEMO MODE WARNING: Stripe is not configured. Using legacy subscription API.'); + // Stripe not configured - warn in feature-limited mode + if (isFeatureLimitedMode()) { + console.warn('[PricingPage] ⚠️ FEATURE-LIMITED MODE WARNING: Stripe is not configured. Using legacy subscription API.'); } } @@ -311,9 +313,9 @@ const PricingPage: React.FC = () => { setTimeout(() => { clearInterval(countdownInterval); - // In podcast-only demo mode, always route users to podcast flow. - if (isPodcastOnlyDemoMode()) { - navigate('/podcast-maker'); + // In feature-limited mode, route users to the feature's landing page. + if (isFeatureLimitedMode()) { + navigate(getDefaultLandingRoute()); } else { const onboardingComplete = localStorage.getItem('onboarding_complete') === 'true'; diff --git a/frontend/src/components/billing/ComprehensiveAPIBreakdown.tsx b/frontend/src/components/billing/ComprehensiveAPIBreakdown.tsx index 157b7c28..82ac8a6a 100644 --- a/frontend/src/components/billing/ComprehensiveAPIBreakdown.tsx +++ b/frontend/src/components/billing/ComprehensiveAPIBreakdown.tsx @@ -12,7 +12,7 @@ import { AccordionDetails, CircularProgress, } from '@mui/material'; -import { ExpandMore } from '@mui/icons-material'; +import ExpandMore from '@mui/icons-material/ExpandMore'; import { motion } from 'framer-motion'; import { Info, diff --git a/frontend/src/components/billing/CostOptimizationRecommendations.tsx b/frontend/src/components/billing/CostOptimizationRecommendations.tsx index 69966261..f4c6541a 100644 --- a/frontend/src/components/billing/CostOptimizationRecommendations.tsx +++ b/frontend/src/components/billing/CostOptimizationRecommendations.tsx @@ -14,7 +14,7 @@ import { AccordionSummary, AccordionDetails, } from '@mui/material'; -import { ExpandMore } from '@mui/icons-material'; +import ExpandMore from '@mui/icons-material/ExpandMore'; import { motion } from 'framer-motion'; import { Lightbulb, diff --git a/frontend/src/components/shared/AlertsBadge.tsx b/frontend/src/components/shared/AlertsBadge.tsx index 42299f1d..efa52791 100644 --- a/frontend/src/components/shared/AlertsBadge.tsx +++ b/frontend/src/components/shared/AlertsBadge.tsx @@ -1,11 +1,15 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; import { Badge, IconButton, Menu, Typography, Box, Divider, Chip, Tooltip, List, ListItem, ListItemText, ListItemIcon, Button } from '@mui/material'; -import { Notifications as NotificationsIcon, NotificationsActive as NotificationsActiveIcon } from '@mui/icons-material'; -import { Warning as WarningIcon, Error as ErrorIcon, Info as InfoIcon, CheckCircle as CheckCircleIcon } from '@mui/icons-material'; +import NotificationsIcon from '@mui/icons-material/Notifications'; +import NotificationsActiveIcon from '@mui/icons-material/NotificationsActive'; +import WarningIcon from '@mui/icons-material/Warning'; +import ErrorIcon from '@mui/icons-material/Error'; +import InfoIcon from '@mui/icons-material/Info'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import { billingService } from '../../services/billingService'; import { useAuth } from '@clerk/clerk-react'; import { getTasksNeedingIntervention, TaskNeedingIntervention } from '../../api/schedulerDashboard'; -import { isPodcastOnlyDemoMode } from '../../utils/demoMode'; +import { isFeatureOnlyMode } from '../../utils/demoMode'; import { apiClient, isBackendCooldownActive, @@ -107,8 +111,8 @@ const AlertsBadge: React.FC = ({ colorMode = 'light' }) => { const fetchAlerts = async () => { if (!userId || isPollingRef.current) return; - // Skip alerts fetching in podcast-only mode (endpoints not available) - if (isPodcastOnlyDemoMode()) { + // Skip alerts fetching in feature-limited mode (endpoints not available) + if (isFeatureOnlyMode()) { setLoading(false); return; } @@ -222,8 +226,8 @@ const AlertsBadge: React.FC = ({ colorMode = 'light' }) => { // Poll for alerts useEffect(() => { - // Skip alerts polling entirely in podcast-only mode - if (isPodcastOnlyDemoMode()) { + // Skip alerts polling entirely in feature-limited mode + if (isFeatureOnlyMode()) { return; }