atdc-buyer-svelte-kit Svelte Themes

Atdc Buyer Svelte Kit

ATDC buyer storefront — SvelteKit + Tailwind + Flowbite, SSR, i18n (ru/en/es), cart, checkout

atdc-buyer-svelte-kit

Фронтенд покупательских страниц ATDC (SPA на SvelteKit).

Отдельный от админки (../atdc-svelte-kit) SvelteKit-проект, обслуживающий витрину магазина: главная, продукция, бренды, трансмиссии, сотрудничество, контакты, корзина и оформление заказа.

Стек

Архитектура

src/
├── app.css / app.html / app.d.ts
├── lib/
│   ├── api/                  REST-клиент (тот же BASE_URL, что в admin)
│   │   ├── index.ts          getData / postData
│   │   ├── urls.ts           endpoint-ы (products, brands, transmissions, orders)
│   │   └── types/            типы ответов и сущностей
│   ├── components/
│   │   ├── Header.svelte
│   │   ├── Footer.svelte
│   │   ├── LanguageSwitcher.svelte
│   │   ├── Accordion.svelte
│   │   └── SearchBar.svelte
│   ├── constants/navigation.ts  URL-ы и навигационное меню
│   ├── i18n/
│   │   ├── index.ts          загрузчик + стор `locale` + функция `t`
│   │   └── locales/          ru.yml / en.yml / es.yml — тексты в YAML
│   ├── stores/
│   │   ├── collection.ts     общий writable-стор для коллекций из API
│   │   ├── products.ts
│   │   ├── brands.ts
│   │   ├── transmissions.ts
│   │   └── cart.ts           локальная корзина в localStorage
│   └── utils/format.ts
└── routes/
    ├── +layout.svelte        Header + Footer + main, гидратация локали/корзины
    ├── +layout.ts            ssr=true (рендерим на сервере, чтобы шапка и футер
    │                         приходили в первом байте и не «прыгали» при загрузке)
    ├── +page.svelte          Главная
    ├── about/                О нас
    ├── products/             Продукция (из API)
    ├── brands/               Бренды (из API)
    ├── transmissions/        Трансмиссии (из API)
    ├── cooperation/          Сотрудничество: как заказать, оплата, доставка,
    │                         сертификаты, гарантия, возврат, обмен
    ├── contacts/             Контакты
    ├── cart/                 Корзина
    └── checkout/             Оформление заказа (POST /orders)

Данные из API

Динамические данные (берутся из сервера):

  • GET /admin/products — список товаров
  • GET /admin/brands — список брендов
  • GET /admin/transmissions — трансмиссии

Отправка заказа:

BASE_URL задаётся в src/lib/api/urls.ts.

Моковые данные

Пока публичный API ещё не подключён, фронт работает на встроенных мок-данных: src/lib/api/mocks/ — реалистичные бренды (ALTO, PRECISION, TRANSTEC, STK, LINTEX, SONNAX, AISIN, RAYBESTOS), трансмиссии (6L80, 722.9, 09G, JF011E, DSG DQ250/DQ200, ZF 8HP и др.) и продукты (ремкомплекты, фильтры, фрикционные диски, соленоиды, гидротрансформаторы).

Управление флагом — в src/lib/api/config.ts:

  • По умолчанию USE_MOCKS = true. Каждый стор-коллекция (products, brands, transmissions) при load() возвращает данные из моков с искусственной задержкой MOCK_LATENCY_MS (350 мс), чтобы отрабатывал loading-скелетон.
  • Чек-аут POST /orders тоже мокирован — заказ имитирует успех и пишет payload в console.info('[mock] POST …').
  • При USE_MOCKS = false (или PUBLIC_USE_MOCKS=false в .env) — все запросы идут в BASE_URL. Если реальный API недоступен и моки указаны — фронт делает graceful fallback на моки, чтобы UI не показывал «API is not reachable».

Чтобы переключиться на реальный API:

# .env (или .env.production)
PUBLIC_USE_MOCKS=false

Или просто поменять fallback = true → false в src/lib/api/config.ts.

Всё остальное (тексты, структура страниц, последовательность шагов заказа, раскладка блоков) — зафиксировано в вёрстке.

Рендеринг и навигация

  • SSR включён в корневом +layout.ts (ssr = true). Сервер отдаёт полный HTML с шапкой, футером и контентом сразу — браузер не видит пустого шелла, шапка/футер не «плавают» при прямой загрузке или перезагрузке страницы.
  • Статические страницы (/, /about, /cooperation, /contacts) — пререндерятся в HTML на этапе vite build, отдаются как статика.
  • Страницы с данными из API (/products, /brands, /transmissions) рендерятся на сервере как скелетон-плейсхолдеры (animated blocks), клиент дозагружает данные в onMount.
  • /cart и /checkout рендерятся на сервере как «пустая корзина», клиент в onMount гидрирует состояние из localStorage; ранний первый рендер совпадает с SSR, так что гидратация Svelte проходит без mismatch-ов.
  • SPA-навигация по меню (<a href> внутри SvelteKit) — клиентская, layout (Header/Footer) сохраняется, меняется только <main>.

Локализация (i18n)

Все строки лежат в отдельных YAML-файлах локалей — аналог config/locales/*.yml в Rails:

src/lib/i18n/locales/
├── ru.yml
├── en.yml
└── es.yml

Компоненты используют функцию t из стора:

<script lang="ts">
  import { t } from '$lib/i18n';
</script>
<h1>{$t('home.hero.title')}</h1>

Выбор языка — в шапке (LanguageSwitcher.svelte). Сохраняется в localStorage (ключ atdc.locale).

Стор locale инициализируется дефолтом (ru), чтобы SSR и первый клиентский рендер совпадали и гидратация Svelte проходила чисто. Функция hydrateLocale() вызывается из +layout.svelte в onMount и при необходимости переключает язык на сохранённый (localStorage) или на navigator.language.

Добавить новый язык — положить <code>.yml (fr.yml, de.yml, …) в src/lib/i18n/locales/. Переключатель подхватит его автоматически (Vite import.meta.glob).

Ключ структурирован иерархически (products.table.code); доступ — через точку ($t('products.table.code')).

Корзина

  • Стор src/lib/stores/cart.ts (writable + derived).
  • Данные хранятся в localStorage (ключ atdc.cart).
  • SSR: стор стартует с пустой корзиной, чтобы серверный HTML совпадал с первым клиентским рендером. Функция hydrateCart() вызывается из +layout.svelte в onMount и наполняет корзину из localStorage уже после гидратации; с этого момента каждое изменение автоматически сохраняется обратно.
  • API: cart.add(product, qty), cart.setQuantity(id, qty), cart.remove(id), cart.clear().
  • Количество и итого — через cartCount, cartSubtotal.

Форма заказа

Поля: имя, компания (не обязательно), телефон, email, город, адрес, способ доставки, способ оплаты, комментарий, согласие на ОПД. Все способы доставки/оплаты синхронизированы с i18n-ключами из cooperation.delivery.* / cooperation.payment.*.

Разработка

npm install
npm run dev

Открыть http://localhost:5173.

Продакшен-сборка:

npm run build
node build

Что не сделано (оставлено как placeholder)

  • Страница «Услуги» / отдельные подстраницы ремонта — сейчас только аккордеоны на главной и в «Сотрудничество». Вынести в отдельные страницы при необходимости.
  • Карта Яндекс в /contacts — заглушка (нужен iframe, когда появится ссылка).
  • Сертификаты / галерея фото офиса / фото команды — пока placeholder-блоки.
  • Авторизация покупателя (Login/регистрация) — в мокапе есть кнопка, но в API ещё нет публичных ручек; после добавления — использовать стор auth по аналогии с админкой.

Связь с админкой

Админка — соседний проект ../atdc-svelte-kit. Оба проекта:

  • ходят в один BASE_URL (api.dev.atdc.ru);
  • используют общую палитру Tailwind (primary-orange);
  • используют одинаковый тип ответов сервера (ObjectsResponse<T>).

Логика отображения у них независимая: у админки — CRUD-таблицы + авторизация, у витрины — только публичное чтение + форма заказа.

Top categories

Loading Svelte Themes