Files
decoda/app/src/App.jsx
2026-06-24 21:00:19 -03:00

131 lines
5.5 KiB
JavaScript

/**
* @fileoverview React component for App.jsx
*
* @module App
*/
import { lazy, Suspense, useEffect } from "react";
import { HashRouter as Router, Routes, Route, useLocation } from "react-router-dom";
import "./App.css";
import HomePage from "./pages/HomePage/HomePage";
import LabPython from "./pages/LabPython/LabPython";
import ScrollToTop from "./components/ScrollToTop";
import { trackPageView } from "./services/plausible";
const Playground = lazy(() => import("./pages/Playground/Playground"));
const About = lazy(() => import("./pages/About/About"));
const Faq = lazy(() => import("./pages/Faq/Faq"));
const Atividades = lazy(() => import("./pages/Atividades/Atividades"));
const Educadores = lazy(() => import("./pages/Educadores/Educadores"));
const Iniciativas = lazy(() => import("./pages/Iniciativas/Iniciativas"));
const IniciativaDetalhe = lazy(() => import("./pages/Iniciativas/IniciativaDetalhe"));
const PrimeirosPassos = lazy(() => import("./pages/PrimeirosPassos/PrimeirosPassos"));
const CategoriaLetramentoView = lazy(() => import("./pages/PrimeirosPassos/CategoriaLetramentoView"));
//Atividades
const AspiradorGame = lazy(() => import("./atividades/programacao/aspirador/AspiradorGame"));
const AutomatoGame = lazy(() => import("./atividades/programacao/automato/AutomatoGame"));
const SemaforoGame = lazy(() => import("./atividades/programacao/semaforo/SemaforoGame"));
const MoleMashGame = lazy(() => import("./atividades/programacao/mole-mash/MoleMash"));
const OrdenacaoGame = lazy(() => import("./atividades/programacao/ordenacao/OrdenacaoGame"));
const PuzzleGame = lazy(() => import("./atividades/programacao/puzzle/PuzzleGame"));
const TurtleGame = lazy(() => import("./atividades/programacao/turtle/TurtleGame"));
const CriptoGame = lazy(() => import("./atividades/programacao/cripto/CriptoGame"));
const ExemploGame = lazy(() => import("./atividades/programacao/exemplo/ExemploGame"));
const ExemploGame2 = lazy(() => import("./atividades/programacao/exemplo2/ExemploGame2"));
const LoadingFallback = () => (
<div
className="primary-gradient text-white"
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100vh",
fontSize: "1.5rem",
fontWeight: "600",
}}
>
<div style={{ textAlign: "center" }}>
<div
style={{
width: "50px",
height: "50px",
border: "4px solid rgba(255,255,255,0.3)",
borderTop: "4px solid white",
borderRadius: "50%",
animation: "spin 1s linear infinite",
margin: "0 auto 20px",
}}
></div>
Carregando...
</div>
</div>
);
// Separated so we can call useLocation (requires being inside Router)
function AppRoutes() {
const location = useLocation();
// When navigating to a letramento category, the caller passes
// { state: { backgroundLocation: location } } so the previous page
// keeps rendering behind the modal overlay.
const backgroundLocation = location.state?.backgroundLocation;
useEffect(() => {
trackPageView(location.pathname);
}, [location.pathname]);
return (
<>
<ScrollToTop />
{/* Main routes — rendered at the background location when a modal is open */}
<Routes location={backgroundLocation ?? location}>
<Route path="/" element={<HomePage />} />
<Route path="/playground" element={<Playground />} />
<Route path="/laboratorio" element={<Playground />} />
<Route path="/laboratorio-python" element={<LabPython />} />
<Route path="/sobre" element={<About />} />
<Route path="/faq" element={<Faq />} />
<Route path="/atividades" element={<Atividades />} />
<Route path="/educadores" element={<Educadores />} />
<Route path="/iniciativas" element={<Iniciativas />} />
<Route path="/iniciativas/:id" element={<IniciativaDetalhe />} />
<Route path="/primeiros-passos" element={<PrimeirosPassos />} />
{/* Fallback: direct URL access without backgroundLocation */}
<Route path="/primeiros-passos/:categoria" element={<CategoriaLetramentoView />} />
<Route path="/atividades/programacao/aspirador" element={<AspiradorGame />} />
<Route path="/atividades/programacao/automato" element={<AutomatoGame />} />
<Route path="/atividades/programacao/cripto" element={<CriptoGame />} />
<Route path="/atividades/programacao/ordenacao" element={<OrdenacaoGame />} />
<Route path="/atividades/programacao/puzzle" element={<PuzzleGame />} />
<Route path="/atividades/programacao/semaforo" element={<SemaforoGame />} />
<Route path="/atividades/programacao/molemash" element={<MoleMashGame />} />
<Route path="/atividades/programacao/turtle" element={<TurtleGame />} />
<Route path="/atividades/programacao/exemplo" element={<ExemploGame />} />
<Route path="/atividades/programacao/exemplo2" element={<ExemploGame2 />} />
</Routes>
{/* Modal overlay routes — rendered on top of the background page */}
{backgroundLocation && (
<Routes>
<Route path="/primeiros-passos/:categoria" element={<CategoriaLetramentoView />} />
</Routes>
)}
</>
);
}
export default function App() {
return (
<Router>
<Suspense fallback={<LoadingFallback />}>
<AppRoutes />
</Suspense>
</Router>
);
}
// Note: many imports are used only via lazy() or in route elements.
// If ESLint still reports unused vars here, we prefer keeping changes minimal
// and addressing remaining warnings in targeted files.