черновая шапка и первый скрол с лого завершено
This commit is contained in:
+90
-7
@@ -8,6 +8,13 @@ declare(strict_types=1);
|
||||
/** @var string $metaKeywords */
|
||||
/** @var array<int, array{title: string, url?: string}> $breadcrumbs */
|
||||
/** @var bool $showBackButton */
|
||||
$megaCategories = [];
|
||||
|
||||
try {
|
||||
$megaCategories = (new \App\Repositories\CategoryRepository())->tree();
|
||||
} catch (\Throwable) {
|
||||
$megaCategories = [];
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
@@ -27,12 +34,12 @@ declare(strict_types=1);
|
||||
<header class="site-topbar">
|
||||
<div class="site-topbar-inner">
|
||||
<a class="brand-link" href="/">
|
||||
<?php if (is_file(base_path('public/assets/images/logo_300.png'))): ?>
|
||||
<img src="/assets/images/logo_300.png" alt="Рыбсток">
|
||||
<?php if (is_file(base_path('public/assets/images/logo-rybstock.svg'))): ?>
|
||||
<img src="/assets/images/logo-rybstock.svg" alt="Рыбсток">
|
||||
<?php else: ?>
|
||||
<span>Рыбсток</span>
|
||||
<span>РЫБ<span>СТОК</span></span>
|
||||
<small>Качественные продукты по стоковым ценам</small>
|
||||
<?php endif; ?>
|
||||
<small>Качественные продукты по стоковым ценам</small>
|
||||
</a>
|
||||
<nav class="main-nav" aria-label="Главное меню">
|
||||
<a href="/">Главная</a>
|
||||
@@ -48,6 +55,22 @@ declare(strict_types=1);
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="smart-search-bar" aria-label="Поиск по каталогу">
|
||||
<div class="smart-search-inner">
|
||||
<form class="smart-search-form" action="/catalog" method="get">
|
||||
<label class="smart-search-label" for="site-search">Умный поиск</label>
|
||||
<div class="smart-search-control">
|
||||
<input id="site-search" name="q" type="search" placeholder="Например: форель стейки, креветки 1 кг, красная рыба, что взять на ужин">
|
||||
<button class="voice-search-button" type="button" aria-label="Голосовой ввод" title="Голосовой ввод">Голос</button>
|
||||
<button class="smart-search-submit" type="submit">Найти</button>
|
||||
</div>
|
||||
<p>Понимает склонения, похожие запросы и бытовые формулировки. Обучаемый поиск подключим к товарам после загрузки каталога.</p>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php require base_path('views/partials/mega-category-menu.php'); ?>
|
||||
|
||||
<header class="site-utility">
|
||||
<?php if ($showBackButton): ?>
|
||||
<button class="back-button" type="button" onclick="history.length > 1 ? history.back() : location.href='/'">Вернуться назад</button>
|
||||
@@ -64,13 +87,12 @@ declare(strict_types=1);
|
||||
<div class="site-footer-inner">
|
||||
<section class="footer-brand">
|
||||
<a class="footer-logo" href="/">
|
||||
<?php if (is_file(base_path('public/assets/images/logo_300.png'))): ?>
|
||||
<img src="/assets/images/logo_300.png" alt="Рыбсток">
|
||||
<?php if (is_file(base_path('public/assets/images/logo-rybstock.svg'))): ?>
|
||||
<img src="/assets/images/logo-rybstock.svg" alt="Рыбсток">
|
||||
<?php else: ?>
|
||||
<span>Рыбсток</span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<p>Качественные продукты по стоковым ценам</p>
|
||||
</section>
|
||||
|
||||
<section class="footer-column">
|
||||
@@ -113,5 +135,66 @@ declare(strict_types=1);
|
||||
<p>Информация на сайте носит справочный характер и не является публичной офертой. Наличие, фасовки, цены и условия доставки подтверждаются менеджером при обработке заказа.</p>
|
||||
</div>
|
||||
</footer>
|
||||
<script>
|
||||
(() => {
|
||||
const button = document.querySelector('.voice-search-button');
|
||||
const input = document.querySelector('#site-search');
|
||||
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||
|
||||
if (!button || !input) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SpeechRecognition) {
|
||||
button.addEventListener('click', () => {
|
||||
input.focus();
|
||||
input.placeholder = 'Голосовой ввод не поддерживается этим браузером';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const recognition = new SpeechRecognition();
|
||||
recognition.lang = 'ru-RU';
|
||||
recognition.interimResults = false;
|
||||
|
||||
button.addEventListener('click', () => {
|
||||
button.classList.add('is-listening');
|
||||
recognition.start();
|
||||
});
|
||||
|
||||
recognition.addEventListener('result', (event) => {
|
||||
const phrase = event.results[0]?.[0]?.transcript || '';
|
||||
input.value = phrase;
|
||||
input.focus();
|
||||
});
|
||||
|
||||
recognition.addEventListener('end', () => {
|
||||
button.classList.remove('is-listening');
|
||||
});
|
||||
})();
|
||||
(() => {
|
||||
const nodes = document.querySelectorAll('[data-temperature]');
|
||||
|
||||
if (nodes.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
||||
|
||||
nodes.forEach((node) => {
|
||||
let current = Number(node.dataset.temperature || node.textContent || 0);
|
||||
const min = Number(node.dataset.min || current - 1);
|
||||
const max = Number(node.dataset.max || current + 1);
|
||||
|
||||
const update = () => {
|
||||
const drift = (Math.random() - 0.5) * 0.28;
|
||||
current = clamp(current + drift, min, max);
|
||||
node.textContent = current.toFixed(1);
|
||||
};
|
||||
|
||||
window.setInterval(update, 4200 + Math.random() * 2400);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user