import React, { useEffect, lazy, Suspense } from 'react'; import ReactDOM from 'react-dom/client'; import { ChakraProvider } from '@chakra-ui/react'; import { BrowserRouter as Router, Route, Routes, useLocation, useParams, useNavigate, Navigate } from 'react-router-dom'; import { HelmetProvider } from 'react-helmet-async'; import createCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; // Authentication-related imports - keep these eager loaded as they're critical import { AuthProvider, useAuth } from './context/AuthContext'; import LoginPage from './login'; import SignUpPage from './signup'; import Logout from './logout'; import SuccessPage from './SuccessPage'; import CancelPage from './CancelPage'; import NotFoundPage from './components/NotFoundPage'; import TawkToWidget from './TawkToWidget'; import ThemeColorUpdater from './ThemeColorUpdater'; // Import PostHog utilities import { initPostHog, PostHogTracking } from './utils/posthog-config'; // Initialize PostHog initPostHog(); // Lazy-loaded components for public routes const App = lazy(() => import('./MainPage/App.jsx')); const PricingPage = lazy(() => import('./MainPage/Pricingpage.jsx')); const PolicyPage = lazy(() => import('./MainPage/PolicyPage')); const TermsPage = lazy(() => import('./MainPage/TermsPage.jsx')); const AboutUsPage = lazy(() => import('./MainPage/AboutUsPage')); const ContactUsPage = lazy(() => import('./MainPage/ContactUsPage')); const AiMockInterviewPage = lazy(() => import('./components/AiMockInterview/AIMockInterviewPage.jsx')); const JobHuntTrackerPage = lazy(() => import('./components/JobHuntTracker/JobHuntTrackerPage')); const BlogList = lazy(() => import('./Blog').then(module => ({ default: module.BlogList }))); const BlogPost = lazy(() => import('./Blog').then(module => ({ default: module.BlogPost }))); // Lazy-loaded components for authenticated routes const Dashboard = lazy(() => import('./GetStarted/Dashboard.jsx')); const InterviewBoard = lazy(() => import('./Interview/interview-board.jsx')); const NewInterview = lazy(() => import('./Interview/new-interview.jsx')); const CreateInterview = lazy(() => import('./Interview/NewInterview/CreateInterview.jsx')); const InterviewDetail = lazy(() => import('./Interview/InterviewDetail/InterviewDetail.jsx')); const InterviewFeedback = lazy(() => import('./Interview/interviewFeedback.jsx')); const OnboardingForm = lazy(() => import('./Onboarding/OnboardingForm')); const InterviewV2 = lazy(() => import('./VideoCallV2/InterviewV2.jsx')); const InterviewFeedbackV2 = lazy(() => import('./VideoCallV2/InterviewFeedback')); const DeviceTestV2Page = lazy(() => import('./VideoCallV2/DeviceTestV2Page')); const QuestionBank = lazy(() => import('./QuestionBank/QuestionBank')); const QuestionDetails = lazy(() => import('./QuestionBank/QuestionDetails')); const Goals = lazy(() => import('./Goals/goals')); const Subscriptions = lazy(() => import('./Subscriptions/subscriptions')); const MyDocuments = lazy(() => import('./my-documents')); const EducationMaterials = lazy(() => import('./education-materials')); const WaveformDemo = lazy(() => import('./WaveformDemo.jsx')); const InterviewTemplates = lazy(() => import('./Interview/InterviewTemplates')); // Lazy-loaded admin components const AdminTemplateManagement = lazy(() => import('./Admin/TemplateManagement.jsx')); const CreateTemplate = lazy(() => import('./Admin/CreateTemplate.jsx')); // Create emotion cache with key const emotionCache = createCache({ key: 'prepin', prepend: true, speedy: true, // Enable speedy mode for production container: document.head, insertionPoint: document.querySelector('meta[name="emotion-insertion-point"]') }); // Simple loading component const LoadingFallback = () => (
); // Simplified ProtectedRoute component const ProtectedRoute = ({ children, requireAuth = true, checkOnboarding = false }) => { const { user, loading } = useAuth(); const location = useLocation(); if (loading) { return ; } // Handle authentication check if (!user && requireAuth) { return ; } // Handle onboarding check if (checkOnboarding && user) { const needsOnboarding = !user.onboarding?.isCompleted; const isOnboardingRoute = location.pathname === '/onboarding'; // If user needs onboarding and isn't on the onboarding page if (needsOnboarding && !isOnboardingRoute) { return ; } // If user has completed onboarding but is still on the onboarding page if (!needsOnboarding && isOnboardingRoute) { return ; } } return children; }; // Page tracking component const PageTrackingWrapper = () => { const location = useLocation(); useEffect(() => { PostHogTracking.trackPageView(location.pathname, location.search); }, [location]); return null; }; // Admin Route component const AdminRoute = ({ children }) => { const { user } = useAuth(); const navigate = useNavigate(); useEffect(() => { if (!user?.role === 'admin') { navigate('/interview-board', { replace: true }); } }, [user, navigate]); return user?.role === 'admin' ? children : null; }; // App Routes component const AppRoutes = () => { return ( <> }> {/* Public Routes */} } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* Authentication Routes - Kept eagerly loaded */} } /> } /> } /> } /> } /> {/* Feedback route - Publicly accessible */} } /> {/* Device test route */} } /> {/* Interview route */} } /> {/* Main Dashboard Route */} } /> } /> {/* Admin Routes */} } /> } /> {/* Onboarding Route */} } /> {/* Other Protected Routes */} } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* Catch-all for 404 */} } /> ); }; // Theme wrapper component const AppWithTheme = () => ( ); // Main App wrapper component const AppWrapper = () => { useEffect(() => { // Track app initialization const appStartTime = performance.now(); // Create memory monitoring function const checkMemoryUsage = () => { if (performance.memory) { console.log('Memory usage:', { usedJSHeapSize: Math.round(performance.memory.usedJSHeapSize / 1048576) + ' MB', totalJSHeapSize: Math.round(performance.memory.totalJSHeapSize / 1048576) + ' MB' }); } }; const cleanup = () => { const duration = performance.now() - appStartTime; // Final memory check before cleanup checkMemoryUsage(); }; // Track initialization PostHogTracking.trackEvent('app_initialized', { timestamp: new Date().toISOString(), environment: import.meta.env.MODE, initialMemoryUsage: performance.memory ? Math.round(performance.memory.usedJSHeapSize / 1048576) : null }); window.addEventListener('beforeunload', cleanup); return () => { window.removeEventListener('beforeunload', cleanup); cleanup(); PostHogTracking.trackEvent('app_terminated', { timestamp: new Date().toISOString(), sessionDuration: performance.now() - appStartTime }); }; }, []); return ( ); }; ReactDOM.createRoot(document.getElementById('root')).render(); export default AppWrapper;