Files
new.rybstock.ru/views/pages/home.php
T
2026-06-08 10:58:47 +03:00

433 lines
23 KiB
PHP

<?php
declare(strict_types=1);
/** @var string $dbStatus */
/** @var array<int, array<string, mixed>> $categories */
/** @var array<int, array<string, mixed>> $catalogProducts */
/** @var array<int, array<string, mixed>> $popularProducts */
/** @var array<int, array<string, mixed>> $homeCatalogSections */
/** @var array<string, mixed> $settings */
/** @var string|null $notice */
/** @var string $buildVersion */
$timezone = new DateTimeZone('Europe/Moscow');
$now = new DateTimeImmutable('now', $timezone);
$lastArrival = new DateTimeImmutable('today', $timezone);
$previousWorkingDay = static function (DateTimeImmutable $date): DateTimeImmutable {
do {
$date = $date->modify('-1 day');
} while ((int) $date->format('N') >= 6);
return $date;
};
while ((int) $lastArrival->format('N') >= 6) {
$lastArrival = $previousWorkingDay($lastArrival);
}
$arrivalSeed = (int) sprintf('%u', crc32($lastArrival->format('Y-m-d') . '|rybstock-arrival'));
$arrivalSecond = (4 * 3600) + ($arrivalSeed % (3 * 3600 + 1));
$arrivalRefreshAt = $lastArrival->setTime(
intdiv($arrivalSecond, 3600),
intdiv($arrivalSecond % 3600, 60),
$arrivalSecond % 60
);
if ($now < $arrivalRefreshAt) {
$lastArrival = $previousWorkingDay($lastArrival);
}
$months = [
1 => 'января',
2 => 'февраля',
3 => 'марта',
4 => 'апреля',
5 => 'мая',
6 => 'июня',
7 => 'июля',
8 => 'августа',
9 => 'сентября',
10 => 'октября',
11 => 'ноября',
12 => 'декабря',
];
$arrivalDate = $lastArrival->format('j') . ' ' . $months[(int) $lastArrival->format('n')] . ' ' . $lastArrival->format('Y');
?>
<section class="start-screen wide">
<section class="home-value-system" aria-label="Преимущества Рыбсток">
<div class="home-value-head">
<p class="eyebrow">Интернет-склад для дома и бизнеса</p>
<h1>Рыбсток</h1>
<p>Рыба, морепродукты, мясо, сыры, овощи, ягоды и бакалея по стоковым ценам для большого домашнего стола, дачи, магазина и кухни.</p>
<div class="hero-actions">
<a class="primary-button hero-button" href="/catalog">Смотреть каталог</a>
<a class="secondary-button" href="tel:+79777363363">+7-977-736-33-63</a>
</div>
</div>
<div class="home-benefit-grid">
<article class="home-benefit-card is-wide" style="--benefit-image: var(--home-hero-picnic)">
<div>
<span>Дом, дача, большой стол</span>
<h2>Запас продуктов без переплаты</h2>
<p>Берете коробками и фасовками со склада, а не с витрины. Удобно набрать рыбу, мясо, морепродукты и полуфабрикаты для семьи и гостей.</p>
</div>
</article>
<article class="home-benefit-card" style="--benefit-image: var(--home-warehouse-fish)">
<div>
<span>Выгода за наличные</span>
<h2>Корзина считает сама</h2>
<p>Минус 300 руб. от 7000 руб., -5% от 20000 руб. и -7% от 50000 руб. Покупателю не нужно считать вручную.</p>
</div>
</article>
<article class="home-benefit-card" style="--benefit-image: var(--home-banner-meat)">
<div>
<span>Доставка и оплата</span>
<h2>Без предоплаты</h2>
<p>Внутри МКАД бесплатно от 5000 руб., за МКАД - от 10000 руб. до 10 км. Заказ оплачивается только при получении.</p>
</div>
</article>
</div>
</section>
<section class="audience-system" aria-label="Для кого работает Рыбсток">
<div class="audience-heading">
<p class="eyebrow">Для кого мы работаем</p>
<h2>Закрываем разные задачи одной поставкой</h2>
<p>От домашнего морозильного запаса до понятного прилавка и стабильной кухни: подбираем позиции под реальный спрос, бюджет и объем.</p>
</div>
<div class="audience-grid">
<article class="audience-card" style="--audience-image: var(--home-warehouse-cold)">
<span>Частным покупателям</span>
<h3>Наполнить морозильник и спокойно кормить семью</h3>
<p>Решаем главную боль: чем накормить домочадцев, гостей и дачу без ежедневных закупок и лишней наценки.</p>
</article>
<article class="audience-card" style="--audience-image: var(--home-warehouse-fish)">
<span>Магазинам</span>
<h3>Собрать ходовой рыбный прилавок</h3>
<p>Не люкс-витрина ради картинки, а понятные позиции, за которыми покупатель возвращается и встает в очередь.</p>
</article>
<article class="audience-card" style="--audience-image: var(--home-banner-seafood)">
<span>HoReCa</span>
<h3>Поддержать полную посадку кухни</h3>
<p>Рыба, мясо, морепродукты, полуфабрикаты и бакалея в одной закупке, чтобы меню не зависело от разрозненных поставок.</p>
</article>
</div>
</section>
<section class="warehouse-showcase" aria-label="Склад Рыбсток">
<div class="warehouse-copy">
<p class="eyebrow">Склад и хранение</p>
<h2>Реальный склад, холодовая цепь и свежие поступления</h2>
<p>Мы показываем склад без лишней витринности: коробки, паллеты, камеры хранения и продукция, которая дальше уезжает к домашнему столу.</p>
</div>
<div class="storage-status" aria-label="Температура хранения и поступление товара">
<div class="arrival-card">
<span>Последнее поступление</span>
<strong><?= e((string) $arrivalDate) ?></strong>
<p>Свежие позиции принимаем по будням утром, после приемки и проверки качества.</p>
</div>
<div class="temperature-card freezer">
<span>Морозильная камера</span>
<strong><span data-temperature="-18.6" data-min="-19.4" data-max="-17.8">-18.6</span> °C</strong>
<p>Рабочий режим глубокой заморозки.</p>
</div>
<div class="temperature-card chiller">
<span>Холодильная камера</span>
<strong><span data-temperature="2.4" data-min="1.6" data-max="3.8">2.4</span> °C</strong>
<p>Температура для охлажденной продукции.</p>
</div>
</div>
<div class="warehouse-photo-grid">
<figure class="warehouse-photo-card large" style="--warehouse-image: var(--home-warehouse-main)">
<figcaption>
<span>Склад Рыбсток</span>
<strong>Паллеты, коробки и рабочий порядок</strong>
</figcaption>
</figure>
<figure class="warehouse-photo-card" style="--warehouse-image: var(--home-warehouse-arrival)">
<figcaption>
<span>Поступления</span>
<strong>Рыба и готовая продукция</strong>
</figcaption>
</figure>
<figure class="warehouse-photo-card" style="--warehouse-image: var(--home-warehouse-cold)">
<figcaption>
<span>Хранение</span>
<strong>Камеры и фасовки</strong>
</figcaption>
</figure>
</div>
</section>
<section class="price-request-panel" id="price-request">
<div class="price-request-cover" aria-hidden="true">
<span>Для магазинов, кафе, ресторанов и закупщиков</span>
</div>
<div class="price-request-content">
<div class="price-request-copy">
<p class="eyebrow">Запрос проходных цен</p>
<h2>Для бизнеса</h2>
<p>Запросите у нас цену на продукцию. Просто напишите позиции, которые Вас интересуют, необходимый объем и цену, которая Вам нужна. Наш менеджер оптового отдела постарается помочь Вам.</p>
<div class="business-only-badge">Только для юридических лиц, ИП, HoReCa и закупщиков</div>
</div>
<?php if (($_GET['price_request'] ?? '') === 'sent'): ?>
<div class="status-box success">Спасибо, запрос принят. Менеджер оптового отдела свяжется с Вами после обработки заявки.</div>
<?php elseif (($_GET['price_request'] ?? '') === 'error'): ?>
<div class="status-box danger">Не удалось отправить запрос. Проверьте обязательные поля и попробуйте еще раз.</div>
<?php endif; ?>
<form class="price-request-form" action="/price-request" method="post" enctype="multipart/form-data">
<label>
<span>Название организации</span>
<input type="text" name="company_name" placeholder="Например: кафе, магазин, ИП или ООО" required>
</label>
<fieldset>
<legend>Форма оплаты</legend>
<label class="choice-pill">
<input type="radio" name="payment_type" value="cash" checked>
<span>Нал</span>
</label>
<label class="choice-pill">
<input type="radio" name="payment_type" value="invoice">
<span>Расчетный счет</span>
</label>
</fieldset>
<label>
<span>Телефон</span>
<input type="tel" name="phone" placeholder="+7 ___ ___-__-__">
</label>
<label>
<span>Email</span>
<input type="email" name="email" placeholder="mail@example.ru">
</label>
<label>
<span>Тип деятельности</span>
<input type="text" name="activity_type" placeholder="Ресторан, магазин, производство, кейтеринг">
</label>
<label class="wide">
<span>Позиции, объем и нужная цена</span>
<textarea name="request_text" rows="6" placeholder="Например: форель 10 кг до 1200 руб./кг, креветки 5 кг до 900 руб./кг" required></textarea>
</label>
<label class="file-field wide">
<span>Прикрепить файлы</span>
<input type="file" name="request_files[]" multiple>
<small>Можно приложить список, прайс, таблицу или фото заявки.</small>
</label>
<button class="primary-button wide" type="submit">Отправить запрос</button>
</form>
</div>
</section>
<?php if ($notice !== null): ?>
<div class="status-box danger"><?= e($notice) ?></div>
<?php endif; ?>
<section class="home-catalog-showcase" aria-label="Витрина каталога Рыбсток">
<div class="home-catalog-heading">
<div>
<p class="eyebrow">Каталог продукции</p>
<h2>Акции и новые поступления</h2>
</div>
<a class="home-catalog-main-link" href="/catalog">Перейти во весь каталог</a>
</div>
<?php if (($homeCatalogSections ?? []) === []): ?>
<div class="panel">
<p class="muted">После наполнения каталога товары появятся здесь по категориям.</p>
</div>
<?php else: ?>
<?php foreach ($homeCatalogSections as $section): ?>
<?php
$sectionProducts = $section['products'] ?? [];
if ($sectionProducts === []) {
continue;
}
$sectionKind = (string) ($section['kind'] ?? 'category');
?>
<section class="home-product-section is-<?= e($sectionKind) ?>" id="home-<?= e((string) ($section['key'] ?? 'section')) ?>">
<div class="home-product-section-head">
<h3><?= e((string) ($section['title'] ?? 'Категория')) ?></h3>
<div class="home-product-section-actions">
<?php if (!empty($section['url'])): ?>
<a href="<?= e((string) $section['url']) ?>">Показать <?= e((string) ($section['count'] ?? count($sectionProducts))) ?> товаров</a>
<?php endif; ?>
<div class="home-strip-controls" aria-label="Прокрутка подборки">
<button type="button" data-home-strip-prev aria-label="Назад">&larr;</button>
<button type="button" data-home-strip-next aria-label="Вперед">&rarr;</button>
</div>
</div>
</div>
<div class="home-products-strip" aria-label="<?= e((string) ($section['title'] ?? 'Категория')) ?>">
<?php foreach ($sectionProducts as $product): ?>
<?php require base_path('views/partials/product-card.php'); ?>
<?php endforeach; ?>
</div>
</section>
<?php endforeach; ?>
<?php endif; ?>
</section>
<script>
document.querySelectorAll('[data-home-strip-prev], [data-home-strip-next]').forEach((button) => {
button.addEventListener('click', () => {
const section = button.closest('.home-product-section');
const strip = section ? section.querySelector('.home-products-strip') : null;
if (!strip) {
return;
}
const direction = button.hasAttribute('data-home-strip-prev') ? -1 : 1;
strip.scrollBy({
left: direction * Math.max(260, strip.clientWidth * 0.86),
behavior: 'smooth',
});
});
});
</script>
<section class="wishlist-request-panel" id="wishlist-request">
<div class="wishlist-request-copy">
<p class="eyebrow">Запрос позиции</p>
<h2>Одна голова хорошо, две лучше</h2>
<p>Нужна позиция, но нигде не можете ее найти? Отправьте нам наименование и объем. Если сможем помочь с поиском, менеджер свяжется с Вами.</p>
<span>Для частных покупателей и бизнеса</span>
</div>
<div class="wishlist-request-card">
<form class="wishlist-request-form" action="/wishlist-request" method="post" enctype="multipart/form-data">
<label>
<span>Имя</span>
<input type="text" name="customer_name" placeholder="Как к Вам обращаться" required>
</label>
<label>
<span>Телефон</span>
<input type="tel" name="phone" placeholder="+7 ___ ___-__-__">
</label>
<label>
<span>Email</span>
<input type="email" name="email" placeholder="mail@example.ru">
</label>
<label class="wide">
<span>Что нужно найти</span>
<textarea name="request_text" rows="5" placeholder="Например: филе судака 10 кг, икра в стеклянной банке, креветки нужного размера" required></textarea>
</label>
<label class="file-field wide">
<span>Прикрепить файлы</span>
<input type="file" name="wishlist_files[]" multiple>
<small>Можно приложить фото, список или пример товара.</small>
</label>
<p class="form-hint wide">Телефон или email - достаточно одного контакта.</p>
<button class="primary-button wide" type="submit">Отправить запрос</button>
</form>
</div>
</section>
<section class="home-delivery-summary" aria-label="Доставка и выгода Рыбсток">
<div>
<p class="eyebrow">Перед оформлением заказа</p>
<h2>Доставка, оплата при получении и подарок за наличный расчет</h2>
<p>Мы привозим заказы после подтверждения по телефону, а оплату принимаем только при получении. При оплате наличными сайт сам пересчитает выгоду в корзине: считать вручную ничего не нужно.</p>
</div>
<div class="home-delivery-benefits">
<article>
<span>от 7 000 руб.</span>
<strong>-300 руб.</strong>
<p>Подарок при оплате наличными.</p>
</article>
<article>
<span>внутри МКАД</span>
<strong>0 руб.</strong>
<p>Бесплатно от 5000 руб., иначе 599 руб.</p>
</article>
<article>
<span>за МКАД</span>
<strong>по адресу</strong>
<p>Сайт рассчитает предварительную стоимость доставки.</p>
</article>
</div>
<a class="primary-button" href="/delivery">Посмотреть условия доставки</a>
</section>
<?php if (false): ?>
<div class="content-grid">
<section class="panel">
<h2>Каталог</h2>
<?php if ($categories === []): ?>
<p class="muted">Категории пока не найдены. Если схема уже применена, проверьте `database/seed.sql`.</p>
<?php else: ?>
<?php
$items = $categories;
$depth = 0;
$currentSlug = '';
require base_path('views/partials/category-tree.php');
?>
<?php endif; ?>
</section>
<section class="panel">
<h2>Доставка</h2>
<dl class="settings-list">
<div>
<dt>Бесплатно внутри МКАД от</dt>
<dd><?= e((string) ($settings['inside_mkad_free_from'] ?? '5000')) ?> руб.</dd>
</div>
<div>
<dt>Доставка внутри МКАД</dt>
<dd><?= e((string) ($settings['inside_mkad_paid_price'] ?? '599')) ?> руб.</dd>
</div>
<div>
<dt>За МКАД</dt>
<dd><?= e((string) ($settings['outside_mkad_base_price'] ?? '199')) ?> руб. + <?= e((string) ($settings['outside_mkad_km_price'] ?? '60')) ?> руб./км</dd>
</div>
<div>
<dt>Подъем</dt>
<dd><?= e((string) ($settings['lift_price'] ?? '390')) ?> руб.</dd>
</div>
</dl>
</section>
</div>
<section class="panel products-panel">
<div class="section-heading">
<div>
<p class="eyebrow">Каталог продукции</p>
<h2>Товары на главной</h2>
</div>
<a class="subtle-link" href="/catalog">Весь каталог</a>
</div>
<?php if ($catalogProducts === []): ?>
<p class="muted">После наполнения базы товары будут отображаться здесь сразу на главной странице.</p>
<?php else: ?>
<div class="product-grid">
<?php foreach ($catalogProducts as $product): ?>
<?php require base_path('views/partials/product-card.php'); ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
</section>
<section class="panel products-panel">
<h2>Популярные товары</h2>
<?php if ($popularProducts === []): ?>
<p class="muted">Товары появятся здесь после наполнения каталога и публикации фасовок.</p>
<?php else: ?>
<div class="product-grid">
<?php foreach ($popularProducts as $product): ?>
<?php require base_path('views/partials/product-card.php'); ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
</section>
<?php endif; ?>
</section>