import React, { useState, useEffect, useMemo } from 'react'; import { extendDemoSession, destroyDemoSession } from '../../../api/services/demo'; import { apiClient } from '../../../api/client'; import { useNavigate } from 'react-router-dom'; import { useDemoTour, getTourState, trackTourEvent } from '../../../features/demo-onboarding'; import { BookOpen, Clock, Sparkles, X } from 'lucide-react'; export const DemoBanner: React.FC = () => { const navigate = useNavigate(); const { startTour, resumeTour } = useDemoTour(); const [isDemo, setIsDemo] = useState(() => localStorage.getItem('demo_mode') === 'true'); const [expiresAt, setExpiresAt] = useState(() => localStorage.getItem('demo_expires_at')); const [timeRemaining, setTimeRemaining] = useState(''); const [canExtend, setCanExtend] = useState(true); const [extending, setExtending] = useState(false); const [showExitModal, setShowExitModal] = useState(false); // Memoize tour state to prevent re-renders const tourState = useMemo(() => { try { return getTourState(); } catch (error) { console.error('Error getting tour state:', error); return null; } }, []); // Only get tour state on initial render useEffect(() => { const demoMode = localStorage.getItem('demo_mode') === 'true'; const expires = localStorage.getItem('demo_expires_at'); console.log('[DemoBanner] Demo mode from localStorage:', demoMode); console.log('[DemoBanner] Expires at:', expires); setIsDemo(demoMode); setExpiresAt(expires); if (demoMode && expires) { const interval = setInterval(async () => { const now = new Date().getTime(); const expiryTime = new Date(expires).getTime(); const diff = expiryTime - now; if (diff <= 0) { setTimeRemaining('Sesión expirada'); await handleExpiration(); } else { const minutes = Math.floor(diff / 60000); const seconds = Math.floor((diff % 60000) / 1000); setTimeRemaining(`${minutes}:${seconds.toString().padStart(2, '0')}`); } }, 1000); return () => clearInterval(interval); } }, [expiresAt]); const handleExpiration = async () => { // Clear demo-specific localStorage keys localStorage.removeItem('demo_mode'); localStorage.removeItem('demo_session_id'); localStorage.removeItem('demo_account_type'); localStorage.removeItem('demo_expires_at'); localStorage.removeItem('demo_tenant_id'); // Clear API client demo session ID and tenant ID apiClient.setDemoSessionId(null); apiClient.setTenantId(null); // Clear tenant store to remove cached demo tenant data const { useTenantStore } = await import('../../../stores/tenant.store'); useTenantStore.getState().clearTenants(); // Clear notification storage to ensure notifications don't persist across sessions const { clearNotificationStorage } = await import('../../../hooks/useNotifications'); clearNotificationStorage(); navigate('/demo'); }; const handleExtendSession = async () => { const sessionId = apiClient.getDemoSessionId(); if (!sessionId) return; setExtending(true); try { const updatedSession = await extendDemoSession({ session_id: sessionId }); localStorage.setItem('demo_expires_at', updatedSession.expires_at); setExpiresAt(updatedSession.expires_at); if (updatedSession.remaining_extensions === 0) { setCanExtend(false); } } catch (error) { console.error('Error extending session:', error); alert('No se pudo extender la sesión'); } finally { setExtending(false); } }; const handleEndSession = async () => { setShowExitModal(true); }; const confirmEndSession = async () => { const sessionId = apiClient.getDemoSessionId(); if (!sessionId) return; try { await destroyDemoSession({ session_id: sessionId }); } catch (error) { console.error('Error destroying session:', error); } finally { await handleExpiration(); } }; const handleCreateAccount = () => { trackTourEvent({ event: 'conversion_cta_clicked', timestamp: Date.now(), }); navigate('/register?from=demo_banner'); }; const handleStartTour = () => { if (tourState && tourState.currentStep > 0 && !tourState.completed) { resumeTour(); } else { startTour(); } }; if (!isDemo) { console.log('[DemoBanner] Not demo mode, returning null'); return null; } return ( <>
{/* Left section - Demo info */}
Sesión Demo Activa
{timeRemaining}
{tourState && !tourState.completed && tourState.currentStep > 0 && (
Tutorial pausado en paso {tourState.currentStep}
)}
{/* Right section - Actions */}
{/* Tour button */} {/* Create account CTA */} {/* Extend session */} {canExtend && ( )} {/* End session */}
{/* Exit confirmation modal */} {showExitModal && (

¿Seguro que quieres salir?

Aún te quedan {timeRemaining} de sesión demo.

¿Te gusta lo que ves?

Crea una cuenta gratuita para acceder a todas las funcionalidades sin límites de tiempo y guardar tus datos de forma permanente.

)} ); }; export default DemoBanner;