Import source: global/src/global-app
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { ToastProvider, NavProvider, AuthProvider, useNav, Header, Footer, PushPrompt } from './global-ui.jsx';
|
||||
import HomePage from './global-home.jsx';
|
||||
import ArticlePage, { ArticlesListPage } from './global-articles.jsx';
|
||||
import { AboutPage, PrivacyPage, TermsPage, EditorialPage, NotFoundPage, PersianOnlyPage, CategoryPage } from './global-pages.jsx';
|
||||
|
||||
function getRoute() {
|
||||
const path = window.location.pathname;
|
||||
const search = window.location.search;
|
||||
if (path === '/' || path === '') return { page: 'home' };
|
||||
if (path === '/articles') return { page: 'articles', q: new URLSearchParams(search).get('q') || '' };
|
||||
if (path.startsWith('/article/')) return { page: 'article', slug: path.replace('/article/', '').replace(/\/$/, '') };
|
||||
if (path.startsWith('/category/')) return { page: 'category', cat: path.replace('/category/', '').replace(/\/$/, '') };
|
||||
if (path === '/about') return { page: 'about' };
|
||||
if (path === '/privacy') return { page: 'privacy' };
|
||||
if (path === '/terms') return { page: 'terms' };
|
||||
if (path === '/editorial-policy') return { page: 'editorial' };
|
||||
if (path === '/persian-only') return { page: 'persian-only' };
|
||||
return { page: '404' };
|
||||
}
|
||||
|
||||
function AppInner() {
|
||||
const { page: navPage, navigate } = useNav();
|
||||
const [route, setRoute] = useState(getRoute());
|
||||
|
||||
useEffect(() => {
|
||||
function onPop() { setRoute(getRoute()); }
|
||||
window.addEventListener('popstate', onPop);
|
||||
return () => window.removeEventListener('popstate', onPop);
|
||||
}, []);
|
||||
|
||||
// Keep route in sync when NavProvider navigate() is called
|
||||
useEffect(() => { setRoute(getRoute()); }, [navPage]);
|
||||
|
||||
function renderPage() {
|
||||
switch (route.page) {
|
||||
case 'home': return <HomePage />;
|
||||
case 'articles': return <ArticlesListPage initQ={route.q} />;
|
||||
case 'article': return <ArticlePage slug={route.slug} />;
|
||||
case 'category': return <CategoryPage cat={route.cat} />;
|
||||
case 'about': return <AboutPage />;
|
||||
case 'privacy': return <PrivacyPage />;
|
||||
case 'terms': return <TermsPage />;
|
||||
case 'editorial': return <EditorialPage />;
|
||||
case 'persian-only': return <PersianOnlyPage />;
|
||||
default: return <NotFoundPage />;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column' }}>
|
||||
<Header />
|
||||
<main style={{ flex: 1 }}>{renderPage()}</main>
|
||||
<Footer />
|
||||
<PushPrompt />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<ToastProvider>
|
||||
<NavProvider>
|
||||
<AuthProvider>
|
||||
<AppInner />
|
||||
</AuthProvider>
|
||||
</NavProvider>
|
||||
</ToastProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user