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;