Новый пакет src/food-market.public/ — отдельный фронт для маркетинга и
самостоятельной регистрации магазинов-клиентов в SaaS Food Market.
Существующая админка food-market.web НЕ затронута.
Стек: Astro 4 + React 19 islands + Tailwind v3 (палитра идентична
food-market.web — единый бренд), TypeScript 6, content collections для
юр.документов. Static-сайт через nginx, gzip + immutable cache на assets.
Карта страниц (23):
- / — главная (Hero + 3 выгоды + скриншот +
6 вертикалей + 6 модулей + Касса +
Интеграции + 3 тарифа + соцпруф +
FAQ + финальный CTA)
- /features — модули по сценариям
- /pricing — тарифы + интерактивный конструктор
«Бизнес» (per-unit: 10000 база +
2000/магазин + 500/касса + 500/склад,
слайдеры, передача params в /signup)
- /pos — УТП лендинг кассы для Windows + весов
- /migration-from-other-system — УТП лендинг миграции с сторонняя система
(сравнительная таблица + 3 шага)
- /integrations — список интеграций
- /for-grocery|pharmacy|cafe|alcohol|clothing|household — 6 вертикалей
с уникальными фишками (весовой,
серии/сроки, модификаторы и комбо,
акцизные марки, размерные сетки,
гарантийные сроки)
- /signup — регистрация (React-island форма)
- /about /contacts /kb /blog /status /changelog — компания + ресурсы
- /legal/{offer,privacy,consent,requisites} — реальные юр.документы
из /tmp/legal/ как Astro content
collection (markdown с frontmatter,
динамический [slug].astro template,
720px max-width, line-height 1.7,
prose-legal стили)
- /sitemap.xml — ручной генератор (sitemap-плагин
конфликтует с Astro 4.16, заменён
на простой APIRoute)
React-острова (3):
- BusinessTariffBuilder — слайдеры + расчёт total + ссылка на signup
- SignupForm — email/password/orgName/phone/plan + валидация + agree
- FAQ — accordion 7 вопросов
API: новый POST /api/auth/signup создаёт Organization + AppUser
(Identity Admin role) + Owner Employee + полный bootstrap через
DevDataSeeder.SeedTenantReferencesAsync (units, price-types, store,
cassa, 6 ролей). Токены НЕ выпускает — фронт сразу делает обычный
/connect/token (password grant) и получает access/refresh без
дублирования OpenIddict-логики. На signup-форме — auth-bridge:
токены передаются через URL fragment в админку
APP_URL/auth-bridge#access=...&refresh=...&welcome=1, AuthBridgePage
кладёт в localStorage и редиректит на /?welcome=signup.
URL-домены через env-переменные (юзер ещё выбирает финальный):
- PUBLIC_SITE_URL — canonical/OG/sitemap (default https://food-market.kz)
- PUBLIC_APP_URL — admin/API endpoint (default https://food-market.zat.kz)
Nginx-конфиг для деплоя сайта — заготовка-template в
deploy/nginx/food-market-public.conf.template, не применён —
ждёт решения по домену.
Dockerfile multi-stage (node:20-alpine build → nginx:1.27 runtime),
build-args PUBLIC_SITE_URL/PUBLIC_APP_URL, deploy/nginx.conf gzip +
immutable cache + try_files для pretty URLs.
SEO: OG-теги, twitter-card, canonical, JSON-LD SoftwareApplication
схема, robots.txt → sitemap-index, lang=ru-KZ.
Admin-side: /auth-bridge route в food-market.web — принимает токены
из URL fragment, кладёт в localStorage (fm.access_token / fm.refresh_token),
редиректит на /. Fragment чтобы access_token не попадал в Referer.
23 страницы билдятся без ошибок. Контейнер собирается. Деплой на
конкретный домен — отдельным шагом после решения юзера.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
54 lines
3.1 KiB
Plaintext
54 lines
3.1 KiB
Plaintext
---
|
||
import BaseLayout from '@/layouts/BaseLayout.astro'
|
||
import BusinessTariffBuilder from '@/components/BusinessTariffBuilder.tsx'
|
||
---
|
||
<BaseLayout title="Тарифы" description="Простые тарифы Food Market: Старт от 5 000 ₸/мес, Бизнес-конструктор, Сеть по запросу. 90 дней бесплатно без банковской карты.">
|
||
<section class="max-w-6xl mx-auto px-4 sm:px-6 py-12">
|
||
<h1 class="text-4xl font-extrabold text-center">Тарифы Food Market</h1>
|
||
<p class="text-center text-slate-500 mt-3">Никаких скрытых доплат. CRM, финансы, лояльность включены во все тарифы.</p>
|
||
|
||
<div class="grid lg:grid-cols-3 gap-5 mt-10">
|
||
<div class="rounded-xl border border-slate-200 p-6 bg-white">
|
||
<h2 class="font-bold text-lg">Старт</h2>
|
||
<p class="text-3xl font-bold mt-2">5 000 ₸<span class="text-sm font-normal text-slate-500">/мес</span></p>
|
||
<p class="text-xs text-slate-500 mt-1">90 дней бесплатно, без карты</p>
|
||
<ul class="text-sm space-y-1.5 mt-5 text-slate-700">
|
||
<li>✓ 1 магазин · 1 касса · 1 склад</li>
|
||
<li>✓ 2 сотрудника</li>
|
||
<li>✓ Без лимита товаров</li>
|
||
<li>✓ Касса с весами Масса-К</li>
|
||
<li>✓ Импорт из МойСклад</li>
|
||
<li>✓ Интеграции Kaspi / ОФД</li>
|
||
<li class="text-slate-400">— API</li>
|
||
<li class="text-slate-400">— SLA</li>
|
||
</ul>
|
||
<a href="/signup?plan=start" class="block text-center mt-6 px-4 py-2.5 bg-brand text-white rounded-md font-semibold">Начать</a>
|
||
</div>
|
||
|
||
<div class="lg:row-span-2">
|
||
<BusinessTariffBuilder client:load />
|
||
</div>
|
||
|
||
<div class="rounded-xl border border-slate-200 p-6 bg-white">
|
||
<h2 class="font-bold text-lg">Сеть</h2>
|
||
<p class="text-3xl font-bold mt-2">По запросу</p>
|
||
<p class="text-xs text-slate-500 mt-1">Демо + индивидуальный SLA</p>
|
||
<ul class="text-sm space-y-1.5 mt-5 text-slate-700">
|
||
<li>✓ Unlimited магазины / кассы / склады</li>
|
||
<li>✓ Unlimited сотрудники</li>
|
||
<li>✓ Расширенный API</li>
|
||
<li>✓ Выделенный менеджер</li>
|
||
<li>✓ Гарантии доступности</li>
|
||
<li>✓ Приоритетная поддержка</li>
|
||
</ul>
|
||
<a href="/contacts" class="block text-center mt-6 px-4 py-2.5 border border-slate-300 rounded-md font-semibold">Связаться</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-12 rounded-xl bg-brand-light/30 p-6 text-center">
|
||
<h3 class="font-bold">Никаких доплат за модули</h3>
|
||
<p class="text-sm text-slate-600 mt-2">CRM, финансы, лояльность, импорт, поддержка — всё включено в каждый тариф. Без сюрпризов в счёте.</p>
|
||
</div>
|
||
</section>
|
||
</BaseLayout>
|