import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' import './mobile-fixes.css' // Mobile-specific CSS fixes import { Elements } from '@stripe/react-stripe-js' import { StripeLoader } from './lib/stripe-loader' import MobileErrorBoundary from './components/MobileErrorBoundary' import MobileLoading from './components/MobileLoading' // Mobile compatibility checks const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); const isIOSSafari = /iPhone|iPad|iPod/i.test(navigator.userAgent) && /Safari/i.test(navigator.userAgent) && !/Chrome|CriOS|FxiOS/i.test(navigator.userAgent); // Initialize production-ready Stripe loader const stripeLoader = StripeLoader.getInstance(); // Loading state management for mobile let appLoadingState = { isLoading: true, error: null as string | null, startTime: Date.now() }; // Update loading state const setLoadingState = (loading: boolean, error?: string | null) => { appLoadingState.isLoading = loading; appLoadingState.error = error || null; // Re-render if needed const globalWindow = window as any; if (globalWindow.mobileLoadingRender) { globalWindow.mobileLoadingRender(); } }; // Enhanced error handling for mobile const handleMobileError = (error: any) => { console.error('Mobile App Initialization Error:', error); let errorMessage = 'Failed to load the app'; if (error.name === 'ChunkLoadError') { errorMessage = 'Failed to load app resources. Please refresh the page.'; } else if (error.message?.includes('stripe')) { errorMessage = 'Payment system initialization failed. Please try again.'; } else if (!navigator.onLine) { errorMessage = 'No internet connection. Please check your connection and try again.'; } else if (isMobile) { errorMessage = 'Mobile app loading failed. Please refresh or try a different browser.'; } setLoadingState(false, errorMessage); }; // Mobile-specific route preloading for Orders and Testimonials if (isMobile) { // Preload critical mobile routes to prevent blank screens const mobileRoutes = ['/orders', '/my-orders', '/testimonials', '/reviews']; mobileRoutes.forEach(route => { const link = document.createElement('link'); link.rel = 'prefetch'; link.href = route; document.head.appendChild(link); }); // Add mobile-specific debugging for Orders/Testimonials console.log('🔧 Mobile Orders/Testimonials Debug Mode Active'); // Check for mobile visibility issues const checkMobileVisibility = () => { setTimeout(() => { const ordersElements = document.querySelectorAll('[class*="order"], [href*="order"]'); const testimonialsElements = document.querySelectorAll('[class*="testimonial"], [href*="testimonial"]'); console.log(`📱 Mobile Debug - Orders elements found: ${ordersElements.length}`); console.log(`📱 Mobile Debug - Testimonials elements found: ${testimonialsElements.length}`); if (ordersElements.length === 0 && testimonialsElements.length === 0) { console.warn('⚠️ Mobile Orders/Testimonials not found - possible routing issue'); } }, 2000); }; window.addEventListener('load', checkMobileVisibility); } // Debug: log environment and key information with mobile context try { const pk = String(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY || ''); const envInfo = stripeLoader.getEnvironmentInfo(); console.log('🔍 Production-Ready Stripe Initialization:'); console.log(' - Environment:', envInfo.isProduction ? 'PRODUCTION' : 'DEVELOPMENT'); console.log(' - Hostname:', envInfo.hostname); console.log(' - Mobile Device:', isMobile); console.log(' - iOS Safari:', isIOSSafari); console.log(' - Key exists:', !!pk); console.log(' - Key type:', pk.startsWith('pk_live_') ? 'LIVE' : pk.startsWith('pk_test_') ? 'TEST' : 'UNKNOWN'); if (pk) { console.debug('client: VITE_STRIPE_PUBLISHABLE_KEY (masked)=', `${pk.slice(0,12)}...${pk.slice(-8)}`); // Validate key format if (pk.length < 100) { console.error('❌ Stripe key appears too short:', pk.length, 'characters'); } else if (pk.length > 120) { console.error('❌ Stripe key appears too long:', pk.length, 'characters'); } else { console.log('✅ Stripe key length looks correct:', pk.length, 'characters'); } } else { console.error('❌ VITE_STRIPE_PUBLISHABLE_KEY is missing or empty'); } } catch (e) { console.error('❌ Error during Stripe initialization setup:', e); handleMobileError(e); } // Create stripe promise using production-ready loader with mobile error handling const stripePromise = stripeLoader.loadStripe(import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY as string) .catch((error) => { handleMobileError(error); return null; }); // Enhanced root element check for mobile const rootElement = document.getElementById('root'); if (!rootElement) { console.error('❌ Root element not found'); document.body.innerHTML = `
⚠️

App Container Missing

The app container could not be found. Please refresh the page.

`; throw new Error('Root element not found'); } // Mobile-specific initialization if (isMobile) { // Set CSS custom properties for mobile viewport const setVH = () => { const vh = window.innerHeight * 0.01; document.documentElement.style.setProperty('--vh', `${vh}px`); }; setVH(); window.addEventListener('resize', setVH); window.addEventListener('orientationchange', setVH); // iOS-specific fixes if (isIOSSafari) { // Handle iOS Safari viewport issues if (window.visualViewport) { const updateViewport = () => { document.documentElement.style.setProperty('--viewport-height', `${window.visualViewport!.height}px`); }; window.visualViewport.addEventListener('resize', updateViewport); updateViewport(); } } } // App wrapper component with mobile-specific features const MobileAppWrapper: React.FC = () => { const [loading, setLoading] = React.useState(true); const [error, setError] = React.useState(null); // Store render function for global access React.useEffect(() => { const globalWindow = window as any; globalWindow.mobileLoadingRender = () => { setLoading(appLoadingState.isLoading); setError(appLoadingState.error); }; // Initial load timeout for mobile const loadTimeout = setTimeout(() => { if (loading) { setLoading(false); } }, isMobile ? 10000 : 5000); // Longer timeout for mobile return () => { clearTimeout(loadTimeout); delete globalWindow.mobileLoadingRender; }; }, []); // Handle successful load const handleAppLoad = () => { setLoading(false); setError(null); }; if (loading || error) { return ( window.location.reload()} /> ); } return ( ); }; // Render with mobile optimizations try { ReactDOM.createRoot(rootElement).render( , ); // Mark as loaded after a short delay to allow React to initialize setTimeout(() => { setLoadingState(false); }, 100); } catch (error) { console.error('❌ Failed to render React app:', error); handleMobileError(error); }