42 lines
1.6 KiB
JavaScript
42 lines
1.6 KiB
JavaScript
import { useEffect } from 'react';
|
||
import { Outlet, useLocation } from 'react-router-dom';
|
||
import Header from './Header.jsx';
|
||
import Footer from './Footer.jsx';
|
||
import CookieBanner from './CookieBanner.jsx';
|
||
import { SiteDataProvider } from '../context/SiteData.jsx';
|
||
import { LeadModalProvider } from '../context/LeadModalContext.jsx';
|
||
import { getConsent, hit, startMetrika } from '../lib/metrika.js';
|
||
|
||
export default function Layout() {
|
||
const { pathname, search, state } = useLocation();
|
||
|
||
// Метрика — только если посетитель уже согласился раньше; иначе ждём выбора в баннере.
|
||
useEffect(() => {
|
||
if (getConsent() === 'all') startMetrika();
|
||
}, []);
|
||
|
||
// SPA не сбрасывает прокрутку сама: без этого новая страница открывалась бы с середины.
|
||
// Переходы внутри одной страницы (направления в «Ценах») передают keepScroll — там
|
||
// прокруткой управляет сама страница.
|
||
useEffect(() => {
|
||
if (!state?.keepScroll) window.scrollTo(0, 0);
|
||
hit();
|
||
}, [pathname, search]);
|
||
|
||
return (
|
||
<SiteDataProvider>
|
||
<LeadModalProvider>
|
||
<div className="app">
|
||
<a className="skip-link" href="#main">Перейти к содержанию</a>
|
||
<Header />
|
||
<main id="main" className="app__main">
|
||
<Outlet />
|
||
</main>
|
||
<Footer />
|
||
<CookieBanner />
|
||
</div>
|
||
</LeadModalProvider>
|
||
</SiteDataProvider>
|
||
);
|
||
}
|