Главная
Все проекты

Bitcar

Кастомный онлайн-каталог аренды транспорта в Таиланде

Роль

Frontend/Fullstack-разработчик

Год

2021

Стек

HTMLSCSSJavaScriptGulpPHPWordPressWooCommerce

Bitcar

Задача

Заказчику требовался онлайн-каталог, где пользователь может выбрать транспорт, даты, локацию и оставить заявку менеджеру (без интеграции платежных шлюзов).

Этапы

01

Проектирование архитектуры и БД

  • Настройка WooCommerce под задачи каталога.
  • Создание таксономий, атрибутов (раздельных для машин и яхт) и кастомных метаполей для сложного ценообразования.
  • Регистрация строк интерфейса через pll_register_string для централизованного перевода в админке без хардкода в шаблонах.
02

Frontend-сборка и UI/UX

  • Итеративная разработка дизайна совместно с заказчиком и дизайнером.
  • Сборка интерфейса на SCSS + Gulp (минификация в app.min.js).
  • Интеграция Swiper с поддержкой WebP (через <picture>), кастомных select-компонентов и sticky-блоков для заявок.
  • Создание отдельного маркетингового шаблона для страницы Трансфера (page-transfer.php).
03

Бэкенд-логика и бронирование

  • Реализация AJAX-фильтров с поддержкой URL-стейта.
  • Интеграция FullCalendar в админку и AirDatepicker на фронтенд с логикой кросс-языковой блокировки дат.
  • Настройка Contact Form 7 с кастомной валидацией телефонов и локализацией ошибок.
04

Динамические цены и корзина-избранное

Написание скриптов для пересчета стоимости аренды "на лету" в зависимости от длительности. Адаптация конвертации 5 валют для нестандартных полей цен. Настройка YITH Wishlist для работы без регистрации на базе сессий пользователя. Подключение Google Tag и Meta Pixel для аналитики конверсий.

Процесс

Под капотом (Реализация)

Визуальная часть

Дизайн-система (цветовая палитра, композиция карточек, адаптивные брейкпоинты) формировалась в тесной итеративной связке с заказчиком — без готового ТЗ на дизайн, макеты уточнялись по ходу разработки.

Архитектура каталога

Транспорт и яхты реализованы как товары WooCommerce — это дало готовую систему таксономий и атрибутов вместо кастомных таблиц:

  • Категории/подкатегории — стандартная таксономия product_cat (Авто → Новый/пикап/хэтчбэк и т.д., Мото, Яхты).
  • Локации (Хуахин, Бангкок, Паттайя, Пхукет, Самуи) — реализованы через product_tag, что позволило переиспользовать фильтрацию по локации во всех разделах каталога и на страницах партнёров/трансфера.
  • Характеристики техники — через нативные атрибуты WooCommerce (pa_brand, pa_transmission, pa_drive-unit, pa_insurance и др.), для яхт — отдельный набор (вместимость, крейсерская скорость, число кают, длина, год постройки), не пересекающийся с авто/мото.
  • Для полей, которых не было в WooCommerce «из коробки» (цена за неделю/месяц, депозиты по периодам, ограничение по пробегу, флаг показа на главной), добавлены кастомные метаполя товара через woocommerce_product_options_general_product_data.

Мультиязычность

Реализована на Polylang: 3 языковые версии (RU/EN/TH) для товаров, категорий и статических текстов интерфейса. Строки интерфейса, не завязанные на контент (заголовки блоков, лейблы фильтров, тексты ошибок валидации), зарегистрированы через pll_register_string и переводятся централизованно через админку Polylang, без дублирования в шаблонах.

Мультивалютность

Конвертация в 5 валют (THB, USD, EUR, RUB, KZT) через плагин мультивалютности WooCommerce. Так как курс из плагина применяется только к основной цене товара, для кастомных полей (цена за неделю/месяц, депозиты) написана собственная логика пересчёта по курсу текущей валюты пользователя — и на сервере (при рендере карточек и страницы товара), и на клиенте (при пересчёте итоговой суммы бронирования в реальном времени).

Фильтрация каталога (~13 параметров)

Для каждой категории (авто, мото, яхты) реализован отдельный AJAX-обработчик фильтрации на PHP (WP_Query с комбинацией tax_query/meta_query), не перезагружающий страницу:

  • Общие для авто/мото: категория, бренд, коробка передач, привод, страховка, пункт выдачи/возврата, вместимость (пассажиры/объём двигателя), диапазон цены (слайдер на noUiSlider), диапазон года выпуска, локация, язык;
  • Для яхт — отдельный набор: верфь/производитель, вместимость, крейсерская скорость, количество кают, длина, год постройки, цена.

Состояние фильтров синхронизируется с URL и localStorage (выбранная локация сохраняется между переходами по каталогу), что снижает число повторных запросов при навигации.

Динамическое ценообразование

Цена аренды пересчитывается на клиенте в зависимости от выбранного периода:

  • до 7 дней — суточная ставка;
  • 7–30 дней — недельная ставка, пересчитанная на факт дней;
  • от 30 дней — месячная ставка, пересчитанная на факт дней (либо «цена по запросу», если ставка не задана).

Итоговая сумма пересчитывается «на лету» при выборе дат в календаре и сразу подставляется как в карточке товара, так и в форме заявки.

Календарь бронирования и доступность дат

  • В админке на странице редактирования товара встроен календарь (FullCalendar): менеджер выделяет диапазон дат и блокирует его через AJAX — запись сохраняется в отдельную таблицу БД, привязанную к товару.
  • Поскольку у каждого товара есть языковые дубли (RU/EN/TH), при создании бронирования оно синхронизируется по всем языковым версиям через pll_get_post_translations, чтобы даты были заблокированы независимо от того, на каком языке товар открыт.
  • На фронтенде даты бронирования подтягиваются в date-picker (AirDatepicker): уже занятые и прошедшие даты недоступны для выбора, с явной подсказкой пользователю.

Карточка транспорта и отдельная страница яхты

Шаблон карточки товара ветвится в зависимости от категории: для авто/мото — блок с суточной/недельной/месячной ставкой, депозитами и пробегом; для яхт — отдельная компоновка с более широкой галереей, детальным описанием и специфичными характеристиками (вместимость, узлы, каюты, год постройки), плюс отдельная форма заявки на аренду яхты через Contact Form 7 (со своим набором полей, отличным от формы бронирования авто/мото).

Страница избранного

Реализована через YITH WooCommerce Wishlist — работает для гостей без регистрации, в рамках сессии/браузера. На странице избранного цены пересчитываются в текущую валюту так же, как в каталоге, что обеспечивает единообразие данных на всех страницах.

Посадочная страница трансфера

Отдельный шаблон страницы (page-transfer.php) с самостоятельной маркетинговой структурой: УТП сервиса, блок «раннее бронирование — ниже цена», таблица ориентировочных цен по типу транспорта, отдельная форма заявки.

Фронтенд и вёрстка

  • SCSS + Gulp-сборка, вывод в минифицированные bundle-файлы (app.min.js).
  • Галереи товаров — Swiper с поддержкой WebP через <picture>/<source> и ленивой загрузкой изображений.
  • Кастомные UI-компоненты: слайдер диапазона цены (noUiSlider), доработанные select (select2 / кастомный select), sticky-блок с ценой и формой заявки на странице товара.
  • Интеграция Contact Form 7 с кастомной валидацией телефона и локализованными сообщениями об ошибках через Polylang.
  • Подключена аналитика (Google tag / gtag.js, Meta Pixel) для отслеживания конверсий по заявкам.

Результаты

13

независимых параметров AJAX-фильтрации, работающих без перезагрузки страницы (с кэшированием состояния в URL и localStorage).

5

валют (THB, USD, EUR, RUB, KZT) с написанной с нуля логикой пересчета нестандартных полей (депозиты, ставки) «на лету» как на сервере, так и на клиенте.

3

архитектурные ветки каталога (Авто, Мото, Яхты), работающие на едином ядре WooCommerce, но с полностью изолированными наборами атрибутов и кастомными шаблонами.

100%

кросс-языковая синхронизация: бронирование дат мгновенно блокирует слоты во всех 3 языковых версиях сайта (RU, EN, TH) через единую базу.

Экраны