import { Toaster } from "@/components/ui/toaster"; import { Toaster as Sonner } from "@/components/ui/sonner"; import { TooltipProvider } from "@/components/ui/tooltip"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { BrowserRouter, Routes, Route, Navigate, useNavigate, useLocation } from "react-router-dom"; import ScrollRestoration from "./ScrollRestoration"; import { AuthProvider, useAuth } from "@/contexts/AuthContext"; import { useState, useEffect } from "react"; import { notificationListener } from "@/lib/notification-listener"; import { notificationService } from "@/lib/notification-service"; import { notificationOpenService } from "@/lib/notification-open-handler"; // Client Layout & Pages import ClientLayout from "@/components/client/ClientLayout"; import HomePage from "@/pages/client/HomePage"; import MoviesPage from "@/pages/client/MoviesPage"; import SeriesPage from "@/pages/client/SeriesPage"; import TVChannelsPage from "@/pages/client/TVChannelsPage"; import TVChannelDetailPage from "@/pages/client/TVChannelDetailPage"; import SearchPage from "@/pages/client/SearchPage"; import ProfilePage from "@/pages/client/ProfilePage"; import ProfileFavoritesPage from "@/pages/client/ProfileFavoritesPage"; import PlansPage from "@/pages/client/PlansPage"; import ContentDetailPage from "@/pages/client/ContentDetailPage"; import EventsPage from "@/pages/client/EventsPage"; import EventDetailPage from "@/pages/client/EventDetailPage"; import NotificationsPage from "@/pages/client/NotificationsPage"; // Admin Layout & Pages import AdminLayout from "@/components/admin/AdminLayout"; import AdminDashboardPage from "@/pages/admin/AdminDashboardPage"; import AdminContentPage from "@/pages/admin/AdminContentPage"; import AdminUsersPage from "@/pages/admin/AdminUsersPage"; import AdminPlansPage from "@/pages/admin/AdminPlansPage"; import AdminEventsPage from "@/pages/admin/AdminEventsPage"; import SliderManagementPage from "@/pages/admin/SliderManagementPage"; import AdminAdsPage from "@/pages/admin/AdminAdsPage"; import TeamLogoManagement from "@/pages/admin/TeamLogoManagement"; import AdminTVChannelsPage from "@/pages/admin/AdminTVChannelsPage"; import AdminReportsPage from "@/pages/admin/AdminReportsPage"; import AnnouncementsPage from "@/pages/admin/AnnouncementsPage"; import AdBlockerPage from "@/pages/admin/AdBlockerPage"; import AdminNotificationsPage from "@/pages/admin/AdminNotificationsPage"; import AdminTerraAdsPage from "@/pages/admin/AdminTerraAdsPage"; import MigrationPage from "@/pages/admin/MigrationPage"; import StorageSettingsPage from "@/pages/admin/StorageSettingsPage"; import CacheSettingsPage from "@/pages/admin/CacheSettingsPage"; // Auth Pages import LoginPage from "@/pages/auth/LoginPage"; import RegisterPage from "@/pages/auth/RegisterPage"; import NotFound from "@/pages/NotFound"; // Protected Route Component const ProtectedRoute = ({ children }: { children: JSX.Element }) => { const { currentUser, loading } = useAuth(); const [redirecting, setRedirecting] = useState(false); useEffect(() => { if (!loading && !currentUser) { setRedirecting(true); // Pequeno atraso para garantir que o layout seja renderizado antes do redirecionamento const timer = setTimeout(() => { window.location.href = '/login'; }, 100); return () => clearTimeout(timer); } }, [currentUser, loading]); if (loading) { return
Carregando...
; } if (!currentUser) { return (

Acesso Restrito

Você precisa estar logado para acessar esta página.

Redirecionando para a página de login...

); } return children; }; // Admin Route Component const AdminRoute = ({ children }: { children: JSX.Element }) => { const { currentUser, loading, isAdmin } = useAuth(); if (loading) { return
Carregando...
; } if (!currentUser || !isAdmin) { return ; } return children; }; const queryClient = new QueryClient(); const AuthCheck = () => { const { currentUser, loading } = useAuth(); const navigate = useNavigate(); const location = useLocation(); // Lista de páginas que requerem autenticação const protectedPaths = [ '/profile', '/profile/favorites', '/plans', '/notifications', '/admin' ]; // Verifica se está em uma página protegida que requer autenticação const isProtectedPage = protectedPaths.some(path => location.pathname.startsWith(path)); // Verifica se está em uma página de autenticação (login ou registro) const isAuthPage = location.pathname === '/login' || location.pathname === '/register'; useEffect(() => { // Redireciona para login apenas se estiver em uma página protegida e não estiver logado if (!loading && !currentUser && isProtectedPage) { navigate('/login'); } }, [currentUser, loading, navigate, isProtectedPage]); // Se estiver em uma página de autenticação ou não protegida, não exibe nada if (isAuthPage || !isProtectedPage) { return null; } if (loading) { return
Carregando...
; } if (!currentUser) { return null; // Não exibe a mensagem de acesso restrito, apenas redireciona silenciosamente } // Não renderizar nada, apenas verificar autenticação return null; }; const AppRoutes = () => ( {/* Client Routes */} }> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* Auth Routes */} } /> } /> {/* Admin Routes */} } > } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* Configurações de cache */} } /> {/* 404 Route */} } /> ); import { Capacitor, PluginListenerHandle } from "@capacitor/core"; const EXIT_ROUTES = ["/", "/home"]; const TO_HOME_ROUTES = [ "/tv-channels", "/series", "/movies", "/profile" ]; function AppBackButtonHandler() { const location = useLocation(); const navigate = useNavigate(); useEffect(() => { const setupBackButton = async () => { if (Capacitor.isNativePlatform && Capacitor.isNativePlatform()) { try { const { App } = await import("@capacitor/app"); const listener = await App.addListener("backButton", () => { // Verificar primeiro se há um elemento em tela cheia if (document.fullscreenElement) { // Se estiver em tela cheia, apenas sair da tela cheia document.exitFullscreen().catch(err => console.error('Erro ao sair da tela cheia:', err) ); return; // Importante: não executar a navegação } // Se não estiver em tela cheia, seguir com o comportamento normal const pathname = location.pathname; if (EXIT_ROUTES.includes(pathname)) { App.exitApp(); } else if (TO_HOME_ROUTES.includes(pathname)) { navigate("/", { replace: true }); } else { navigate(-1); } }); return listener; } catch (error) { console.error('Erro ao configurar o listener do botão voltar:', error); return null; } } return null; }; // Configurar o listener e armazenar para limpeza posterior const listenerPromise = setupBackButton(); return () => { // Limpar o listener quando o componente for desmontado listenerPromise.then(listener => { if (listener) listener.remove(); }).catch(err => { console.error('Erro ao remover o listener do botão voltar:', err); }); }; }, [location, navigate]); return null; } import SplashScreen from "@/components/SplashScreen"; const App = () => { const [showSplash, setShowSplash] = useState(true); // Splash dura pelo menos 800ms, mas some assim que tudo estiver pronto useEffect(() => { // Aguarda o carregamento mínimo e o próximo tick de render const timeout = setTimeout(() => setShowSplash(false), 800); return () => clearTimeout(timeout); }, []); // Inicializa o serviço de escuta de notificações useEffect(() => { // Inicializa o serviço de notificações notificationService.initialize(); // Limpa o serviço quando o componente for desmontado return () => { }; }, []); return ( {showSplash ? ( setShowSplash(false)} /> ) : ( )} ); }; export default App;