import React, { useEffect } from 'react'; import { BrowserRouter, Route, Routes, useLocation } from 'react-router-dom'; import { AnimatePresence, motion } from 'framer-motion'; import { Preloader } from './components/Preloader'; import { Header } from './components/Header'; import { Footer } from './components/Footer'; import { FloatingContact } from './components/FloatingContact'; import { Home } from './pages/Home'; import { About } from './pages/About'; import { ServicesPage } from './pages/ServicesPage'; import { Projects } from './pages/Projects'; import { ProjectDetail } from './pages/ProjectDetail'; import { Investment } from './pages/Investment'; import { Blog } from './pages/Blog'; import { ArticleDetail } from './pages/ArticleDetail'; import { FaqPage } from './pages/FaqPage'; import { ContactPage } from './pages/ContactPage'; import { SiteProvider, useSiteData, useSite } from './api'; import { applySeo, seoKeyForPath } from './seo'; import { AdminProvider, useAdmin } from './admin/AdminContext'; import { AdminBar } from './admin/AdminBar'; import { AdminLoginPage } from './admin/AdminLoginPage'; import { ArticleWritePage } from './admin/ArticleWritePage'; import { LangProvider, useLang } from './i18n/lang'; // مسیرهای عمومی یک بار تعریف می‌شوند و دو بار سرو می‌شوند: ریشه فارسی و /en انگلیسی const PUBLIC_ROUTES: { path: string; element: React.ReactElement }[] = [ { path: '/', element: }, { path: '/about', element: }, { path: '/services', element: }, { path: '/projects', element: }, { path: '/projects/:slug', element: }, { path: '/investment', element: }, { path: '/blog', element: }, { path: '/blog/:slug', element: }, { path: '/faq', element: }, { path: '/contact', element: }, ]; function LocaleRoutes({ prefix }: { prefix: '' | '/en' }) { return ( <> {PUBLIC_ROUTES.map(({ path, element }) => ( ))} {prefix === '' && } />} ); } function ScrollToTop() { const { pathname } = useLocation(); useEffect(() => { window.scrollTo({ top: 0, behavior: 'auto' }); }, [pathname]); return null; } function AnimatedRoutes() { const location = useLocation(); return ( } /> } /> } /> ); } function AppChrome() { const { pathname } = useLocation(); const { isAuthenticated } = useAdmin(); const data = useSite(); const { lang } = useLang(); const isAdminPage = pathname.startsWith('/admin'); // عنوان و توضیح متای هر صفحه از دیتابیس (سئو) — جز صفحه‌های جزئیات که خودشان ست می‌کنند useEffect(() => { if (isAdminPage) return; const key = seoKeyForPath(pathname); if (!key) return; const meta = data.seo_meta?.find((s) => s.page_key === key); const brand = data.brand.name; const navLabel = data.nav.find((n) => n.href === `/${key}`)?.label; applySeo({ title: meta?.title || (key === 'home' ? brand : navLabel ? `${navLabel} | ${brand}` : brand), description: meta?.description ?? '', path: pathname, lang, }); }, [pathname, data, isAdminPage, lang]); return ( <> {!isAdminPage &&
} {!isAdminPage &&