2026-05-15 18:42:05 +00:00
|
|
|
import { ThemeListener } from './components/layout/ThemeListener';
|
2026-05-13 22:24:26 +00:00
|
|
|
import React, { lazy, Suspense } from 'react';
|
|
|
|
|
import { BrowserRouter, Routes, Route, Navigate, useParams } from 'react-router-dom';
|
|
|
|
|
import { HelmetProvider } from 'react-helmet-async';
|
|
|
|
|
import { Layout } from './components/Layout';
|
|
|
|
|
import Home from './pages/Home';
|
|
|
|
|
import BlogList from './pages/BlogList';
|
|
|
|
|
import PostDetail from './pages/PostDetail';
|
|
|
|
|
|
|
|
|
|
// Wrapper to handle language validation and layout injection
|
|
|
|
|
const LangWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
|
|
|
const { lang } = useParams<{ lang: string }>();
|
|
|
|
|
const validLangs = ['en', 'pt', 'es'];
|
|
|
|
|
|
|
|
|
|
if (!lang || !validLangs.includes(lang)) {
|
|
|
|
|
return <Navigate to="/pt" replace />;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return <Layout>{children}</Layout>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const Contact = lazy(() => import('./pages/Contact'));
|
|
|
|
|
const Legal = lazy(() => import('./pages/Legal'));
|
|
|
|
|
|
|
|
|
|
import { ScrollToTop } from './components/ScrollToTop';
|
|
|
|
|
|
|
|
|
|
export default function App() {
|
|
|
|
|
return (
|
|
|
|
|
<HelmetProvider>
|
2026-05-19 21:59:17 +00:00
|
|
|
<ThemeListener />
|
2026-05-13 22:24:26 +00:00
|
|
|
<BrowserRouter>
|
|
|
|
|
<ScrollToTop />
|
2026-05-15 18:42:05 +00:00
|
|
|
<Suspense fallback={<div className="overflow-x-hidden min-h-screen bg-white flex items-center justify-center font-mono text-[10px] uppercase tracking-widest text-tech-muted animate-pulse">
|
2026-05-19 21:59:17 +00:00
|
|
|
loading_module...</div>}>
|
2026-05-13 22:24:26 +00:00
|
|
|
<Routes>
|
|
|
|
|
<Route path="/" element={<Navigate to="/pt" replace />} />
|
|
|
|
|
|
|
|
|
|
<Route path="/:lang" element={<LangWrapper><Home /></LangWrapper>} />
|
|
|
|
|
<Route path="/:lang/blog" element={<LangWrapper><BlogList /></LangWrapper>} />
|
|
|
|
|
<Route path="/:lang/blog/category/:category" element={<LangWrapper><BlogList /></LangWrapper>} />
|
|
|
|
|
<Route path="/:lang/blog/:slug" element={<LangWrapper><PostDetail /></LangWrapper>} />
|
|
|
|
|
|
|
|
|
|
<Route path="/:lang/contact" element={<LangWrapper><Contact /></LangWrapper>} />
|
|
|
|
|
<Route path="/:lang/privacy" element={<LangWrapper><Legal /></LangWrapper>} />
|
|
|
|
|
<Route path="/:lang/terms" element={<LangWrapper><Legal /></LangWrapper>} />
|
|
|
|
|
<Route path="/:lang/ethics" element={<LangWrapper><Legal /></LangWrapper>} />
|
|
|
|
|
|
|
|
|
|
<Route path="*" element={<Navigate to="/pt" replace />} />
|
|
|
|
|
</Routes>
|
|
|
|
|
</Suspense>
|
|
|
|
|
</BrowserRouter>
|
|
|
|
|
</HelmetProvider>
|
|
|
|
|
);
|
|
|
|
|
}
|