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)
This commit is contained in:
ajaysi
2026-05-08 12:06:47 +05:30
parent 98cfb03cf7
commit ef7b3d2b49
8 changed files with 36 additions and 27 deletions

View File

@@ -1,6 +1,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Container, Grid, Card, CardContent, Typography, Box, Stack, Chip } from '@mui/material'; 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 { interface PhaseFeature {
title: string; title: string;

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Box, Paper } from '@mui/material'; import { Box, Paper } from '@mui/material';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
interface CardExpansionWrapperProps { interface CardExpansionWrapperProps {
children: React.ReactNode; children: React.ReactNode;

View File

@@ -1,6 +1,6 @@
import React, { Component, ErrorInfo, ReactNode } from 'react'; import React, { Component, ErrorInfo, ReactNode } from 'react';
import { Box, Typography, Alert, Button } from '@mui/material'; 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 { interface Props {
children: ReactNode; children: ReactNode;

View File

@@ -7,7 +7,9 @@ import {
Alert, Alert,
AlertTitle AlertTitle
} from '@mui/material'; } 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 { interface Props {
children: ReactNode; children: ReactNode;

View File

@@ -18,10 +18,11 @@ import {
Backdrop, Backdrop,
Snackbar, Snackbar,
} from '@mui/material'; } from '@mui/material';
import { Warning } from '@mui/icons-material'; import Warning from '@mui/icons-material/Warning';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { apiClient } from '../../api/client'; import { apiClient } from '../../api/client';
import { restoreNavigationState, saveCurrentPhaseForTool } from '../../utils/navigationState'; import { restoreNavigationState, saveCurrentPhaseForTool } from '../../utils/navigationState';
import { getEnabledFeatures, getDefaultLandingRoute } from '../../utils/demoMode';
import PlanCard from './PricingPage/PlanCard'; import PlanCard from './PricingPage/PlanCard';
export interface SubscriptionPlan { export interface SubscriptionPlan {
@@ -97,14 +98,16 @@ const PricingPage: React.FC = () => {
fetchPlans(); fetchPlans();
}, []); }, []);
const isPodcastOnlyDemoMode = () => { const isFeatureLimitedMode = (): boolean => {
const appMode = (localStorage.getItem('app_mode') || '').toLowerCase(); const appMode = (localStorage.getItem('app_mode') || '').toLowerCase();
const demoMode = (localStorage.getItem('demo_mode') || '').toLowerCase(); const demoMode = (localStorage.getItem('demo_mode') || '').toLowerCase();
const podcastOnlyDemoMode = (localStorage.getItem('podcast_only_demo_mode') || '').toLowerCase(); const podcastOnlyDemoMode = (localStorage.getItem('podcast_only_demo_mode') || '').toLowerCase();
const envAppMode = (process.env.REACT_APP_APP_MODE || '').toLowerCase(); const envAppMode = (process.env.REACT_APP_APP_MODE || '').toLowerCase();
const envDemoMode = (process.env.REACT_APP_DEMO_MODE || '').toLowerCase(); const envDemoMode = (process.env.REACT_APP_DEMO_MODE || '').toLowerCase();
const enabledFeatures = getEnabledFeatures();
return ( return (
!enabledFeatures.has('all') ||
podcastOnlyDemoMode === 'true' || podcastOnlyDemoMode === 'true' ||
appMode === 'podcast-only' || appMode === 'podcast-only' ||
demoMode === 'podcast-only' || demoMode === 'podcast-only' ||
@@ -114,10 +117,9 @@ const PricingPage: React.FC = () => {
}; };
const redirectAfterSubscription = () => { const redirectAfterSubscription = () => {
// In podcast-only demo mode, always force users into podcast flow. if (isFeatureLimitedMode()) {
// Never send demo users to onboarding. const route = getDefaultLandingRoute();
if (isPodcastOnlyDemoMode()) { navigate(route);
navigate('/podcast-maker');
return; return;
} }
@@ -235,8 +237,8 @@ const PricingPage: React.FC = () => {
const response = await apiClient.post('/api/subscription/create-checkout-session', { const response = await apiClient.post('/api/subscription/create-checkout-session', {
tier: plan.tier, tier: plan.tier,
billing_cycle: yearlyBilling ? 'yearly' : 'monthly', billing_cycle: yearlyBilling ? 'yearly' : 'monthly',
success_url: isPodcastOnlyDemoMode() success_url: isFeatureLimitedMode()
? `${window.location.origin}/podcast-maker?subscription=success` ? `${window.location.origin}${getDefaultLandingRoute()}?subscription=success`
: `${window.location.origin}/dashboard?subscription=success`, : `${window.location.origin}/dashboard?subscription=success`,
cancel_url: `${window.location.origin}/pricing?subscription=cancel`, 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.' 'Stripe checkout is required but REACT_APP_STRIPE_PUBLISHABLE_KEY is not configured.'
); );
} else { } else {
// Stripe not configured - warn in demo mode // Stripe not configured - warn in feature-limited mode
if (isPodcastOnlyDemoMode()) { if (isFeatureLimitedMode()) {
console.warn('[PricingPage] ⚠️ DEMO MODE WARNING: Stripe is not configured. Using legacy subscription API.'); console.warn('[PricingPage] ⚠️ FEATURE-LIMITED MODE WARNING: Stripe is not configured. Using legacy subscription API.');
} }
} }
@@ -311,9 +313,9 @@ const PricingPage: React.FC = () => {
setTimeout(() => { setTimeout(() => {
clearInterval(countdownInterval); clearInterval(countdownInterval);
// In podcast-only demo mode, always route users to podcast flow. // In feature-limited mode, route users to the feature's landing page.
if (isPodcastOnlyDemoMode()) { if (isFeatureLimitedMode()) {
navigate('/podcast-maker'); navigate(getDefaultLandingRoute());
} else { } else {
const onboardingComplete = localStorage.getItem('onboarding_complete') === 'true'; const onboardingComplete = localStorage.getItem('onboarding_complete') === 'true';

View File

@@ -12,7 +12,7 @@ import {
AccordionDetails, AccordionDetails,
CircularProgress, CircularProgress,
} from '@mui/material'; } from '@mui/material';
import { ExpandMore } from '@mui/icons-material'; import ExpandMore from '@mui/icons-material/ExpandMore';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { import {
Info, Info,

View File

@@ -14,7 +14,7 @@ import {
AccordionSummary, AccordionSummary,
AccordionDetails, AccordionDetails,
} from '@mui/material'; } from '@mui/material';
import { ExpandMore } from '@mui/icons-material'; import ExpandMore from '@mui/icons-material/ExpandMore';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { import {
Lightbulb, Lightbulb,

View File

@@ -1,11 +1,15 @@
import React, { useState, useEffect, useRef, useCallback } from 'react'; 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 { 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 NotificationsIcon from '@mui/icons-material/Notifications';
import { Warning as WarningIcon, Error as ErrorIcon, Info as InfoIcon, CheckCircle as CheckCircleIcon } from '@mui/icons-material'; 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 { billingService } from '../../services/billingService';
import { useAuth } from '@clerk/clerk-react'; import { useAuth } from '@clerk/clerk-react';
import { getTasksNeedingIntervention, TaskNeedingIntervention } from '../../api/schedulerDashboard'; import { getTasksNeedingIntervention, TaskNeedingIntervention } from '../../api/schedulerDashboard';
import { isPodcastOnlyDemoMode } from '../../utils/demoMode'; import { isFeatureOnlyMode } from '../../utils/demoMode';
import { import {
apiClient, apiClient,
isBackendCooldownActive, isBackendCooldownActive,
@@ -107,8 +111,8 @@ const AlertsBadge: React.FC<AlertsBadgeProps> = ({ colorMode = 'light' }) => {
const fetchAlerts = async () => { const fetchAlerts = async () => {
if (!userId || isPollingRef.current) return; if (!userId || isPollingRef.current) return;
// Skip alerts fetching in podcast-only mode (endpoints not available) // Skip alerts fetching in feature-limited mode (endpoints not available)
if (isPodcastOnlyDemoMode()) { if (isFeatureOnlyMode()) {
setLoading(false); setLoading(false);
return; return;
} }
@@ -222,8 +226,8 @@ const AlertsBadge: React.FC<AlertsBadgeProps> = ({ colorMode = 'light' }) => {
// Poll for alerts // Poll for alerts
useEffect(() => { useEffect(() => {
// Skip alerts polling entirely in podcast-only mode // Skip alerts polling entirely in feature-limited mode
if (isPodcastOnlyDemoMode()) { if (isFeatureOnlyMode()) {
return; return;
} }