Commit graph

107 commits

Author SHA1 Message Date
Vadym Samoilenko
42cb554de4 feat(forms): use FormBlock when form is set in CMS, fallback to hardcoded
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:07:04 +01:00
Vadym Samoilenko
32ca1dcd2a fix(forms): use ternary className to preserve md:col-span-2 for full-width fields 2026-05-18 12:05:41 +01:00
Vadym Samoilenko
6e5e624345 feat(forms): add FormBlock component for form-builder rendering 2026-05-18 12:05:17 +01:00
Vadym Samoilenko
0925ab2052 fix(migration): make 20260518_115657 idempotent — recreate missing group_visits_page and birthday_page tables
Tables group_visits_page, birthday_page and their _v counterparts were missing from the DB
despite prior migrations being marked applied. The updated migration uses CREATE TABLE IF NOT EXISTS,
DO/EXCEPTION blocks for enum types and FK constraints, and ADD COLUMN IF NOT EXISTS to recover
the full schema before adding form_id relationship columns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:03:36 +01:00
Vadym Samoilenko
ff4ae6934c feat(cms): add form relationship field to GroupVisitsPage and BirthdayPage 2026-05-18 11:58:21 +01:00
Vadym Samoilenko
5e998daa8d chore(migrations): add form_builder tables
Creates forms, form_submissions and all related block tables for the @payloadcms/plugin-form-builder integration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:55:38 +01:00
Vadym Samoilenko
7223200d42 feat(cms): add @payloadcms/plugin-form-builder 2026-05-18 11:48:04 +01:00
Vadym Samoilenko
4bda57b903 fix(cms): remove site-settings from livePreview + add label 2026-05-18 11:43:45 +01:00
Vadym Samoilenko
5374105e06 feat(seed): DyvoLis location record — enables /lokatsii/dyvolis
Some checks failed
CI / Type Check (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
Deploy / Build & Push Image (push) Has been cancelled
Deploy / Deploy to VPS (push) Has been cancelled
Inserts the ДивоЛіс location into locations table with showDetailPage=true
plus heroTips and whyVisitItems child records. Idempotent (ON CONFLICT/DELETE+INSERT).
Run by the psql migrator on next deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 19:10:29 +01:00
Vadym Samoilenko
d1268c47a8 feat(deploy): SQL delta migration + NEXT_PUBLIC_SITE_URL build arg
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- migrations/0002_delta.sql: idempotent SQL extracted from 20260515_162527.ts
  (redirects table, locations detail fields, globals versioning, new pages)
  so the psql migrator container applies it on next deploy
- Dockerfile: ARG/ENV NEXT_PUBLIC_SITE_URL in builder stage so the URL is
  baked into the Next.js bundle (fixes postMessage origin warning in admin)
- docker-compose.prod.yml: pass build arg NEXT_PUBLIC_SITE_URL=https://shumi.ai-impress.com

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 18:56:56 +01:00
Vadym Samoilenko
965ffc2084 fix(live-preview): fallback serverURL to localhost instead of empty string
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
postMessage with empty string origin throws "Invalid target origin ''"
Use same fallback as payload.config.ts — http://localhost:3000.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 18:46:55 +01:00
Vadym Samoilenko
1defcc13b0 fix(build): commit payload-types.ts and untrack from gitignore
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
payload-types.ts was gitignored so Docker builder had no file to compile
against — caused TS2307 "Cannot find module @/payload-types" in production
build. Regenerated types from current schema and removed from .gitignore
so it is always available in the build context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 18:39:01 +01:00
Vadym Samoilenko
66f9a0d645 fix(build): remove .js extensions from payload.config imports + fix TS errors
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
payload.config.ts used explicit .js extensions on local imports which Turbopack
and webpack cannot resolve to .ts files without extensionAliases config. Revert
to extension-less imports (original pattern from first Payload commit) that both
bundlers handle natively.

Also fix two TypeScript strict-mode errors:
- seed/route.ts: doc.id (number) cast to string via String() instead of `as string`
- getHomeData.ts: Payload HomePage vs HomePageGlobal cast via `as unknown as`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 18:34:38 +01:00
Vadym Samoilenko
83c4f7973a feat(migrations): delta migration — versions, redirects, new globals, locations fields
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Auto-generated by Payload CLI (pnpm migrate:create) against prod DB.
Adds: locations_hero_tips/why_visit_items/review_videos tables, versions
for 6 globals (home, group_visits, birthday, tickets, locations_page,
blog_index), redirects collection, birthday_page + tickets_page tables,
meta columns on all globals, show_detail_page + rich fields on locations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:32:31 +01:00
Vadym Samoilenko
55a3aafc27 feat(cms): admin UX — groups, timezone, title suffix
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Add admin.group to all 24 globals/collections so the Payload Admin
sidebar is organized into logical sections (Сторінки, Контент сайту,
Каталог, Блог, Заявки та замовлення, Медіа, Система). Add admin.meta
titleSuffix '— Шуміленд CMS', defaultTimezone Europe/Kyiv, dateFormat
dd.MM.yyyy HH:mm.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:58:47 +01:00
Vadym Samoilenko
bf084e37c9 feat(cms): add redirects plugin + middleware for 301/302 handling
Install @payloadcms/plugin-redirects, configure for 'pages' collection
with 301/302 types. Create src/middleware.ts that reads the redirects
collection via REST API (cached 5 min) and applies them before Next.js
renders — editors can manage redirects from the CMS admin.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:56:30 +01:00
Vadym Samoilenko
f808ad6b42 feat(cms): add Live Preview RefreshRouteOnSave to key pages
Install @payloadcms/live-preview-react and add RefreshRouteOnSave
component to home, lokatsii/[slug], dni-narodzhennia, grupovi-vidviduvannia,
kvytky — Payload Admin live preview now triggers client router.refresh().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:55:41 +01:00
Vadym Samoilenko
b1fd23d9a2 feat(cms): enable drafts + autosave for key globals
Enable versions with draft autosave (interval 2000ms, max 20) for
HomePage, GroupVisitsPage, BirthdayPage, TicketsPage, LocationsPage,
BlogIndexPage — editors can now save drafts without publishing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:54:09 +01:00
Vadym Samoilenko
a134be0df0 feat(cms): dynamic locations routing + missing page globals
- Locations collection: add rich fields for detail pages (showDetailPage,
  heroStat, heroTips, galleryQuote, whyVisitItems, reviewVideos, etc.)
  organized in tabs (Загальне / Сторінка локації)
- Create /lokatsii/[slug]/page.tsx — CMS-driven dynamic route replacing
  static /lokatsii/dyvolis; reuses DyvoLis section components
- Remove /lokatsii/dyvolis/ static folder (traffic via [slug] now)
- Remove hardcoded LOCATION_PAGES map; use loc.showDetailPage instead
- Add LocationsPage global — hero title/subtitle + SEO for /lokatsii
- Add BlogIndexPage global — hero title/subtitle + SEO for /blog
- Update lokatsii/page.tsx and blog/page.tsx: dynamic hero from CMS,
  generateMetadata from plugin
- Checkout: server page wrapper reads title from checkout-page global,
  client logic extracted to CheckoutClient.tsx
- Add korzyna/layout.tsx with noindex/nofollow metadata
- Fix payload.ts getGlobal signature to use GlobalSlug union type
- Regenerate payload-types.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:50:24 +01:00
Vadym Samoilenko
efeeeca8f5 feat(cms): unify SEO via plugin for all globals + fix migrate CLI
- seoPlugin extended to cover 7 globals (home, dyvolis, group-visits,
  birthday, tickets, checkout, thank-you) with tabbedUI, generateURL,
  generateTitle from heroTitle, generateDescription from heroSubtitle
- Remove manual metaTitle/metaDescription fields from 4 globals
  (BirthdayPage, GroupVisitsPage, TicketsPage, DyvoLisPage)
- Update 5 page files to read meta?.title/description from seoPlugin
- blog/[slug] now uses post.meta?.title from plugin instead of raw title
- pnpm migrate/migrate:create/migrate:status scripts fixed with
  NODE_OPTIONS='--import tsx' (resolves Node.js v26 + tsx incompatibility)
- Initial full-schema migration 20260515_153940.ts created as baseline

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:43:36 +01:00
Vadym Samoilenko
2ec8393de9 feat(cms): full CMS control — remove hardcoded content, add globals and SEO meta
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- New BirthdayPage global: hero, form titles, meta SEO for /dni-narodzhennia
- New TicketsPage global: hero, section titles, meta SEO for /kvytky
- SiteSettings: add tariffCategoryLabels array (key→label mapping for ezy API categories)
- DyvoLisPage + GroupVisitsPage: add metaTitle/metaDescription + revalidate hook
- /kvytky: fetch birthday packages from CMS, groups from CMS, category labels from SiteSettings
- /grupovi-vidviduvannia: remove DEFAULT_GROUPS fallback, CMS-driven meta
- /dni-narodzhennia: connect to BirthdayPage global (hero, form titles, meta)
- /lokatsii/dyvolis: use CMS meta description from DyvoLisPage global
- pnpm override tsx→4.22.0 for Node.js v26 compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 13:55:28 +01:00
Vadym Samoilenko
2a535671b6 fix(widget): move Binotel button to bottom-left
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:20:20 +01:00
Vadym Samoilenko
1378b9a809 feat(widget): replace Binotel smart-button with styled GetCall widget
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Switch to getcall widget script, position button bottom-right, apply
Shumiland brand colors (green #396817 / orange #f28b4a), and use
Shumi mascot photo as button icon.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:12:50 +01:00
Vadym Samoilenko
79b24ef3d9 fix(migrator): replace payload migrate with direct psql runner
Some checks failed
CI / Type Check (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
Deploy / Build & Push Image (push) Has been cancelled
Deploy / Deploy to VPS (push) Has been cancelled
tsx@4.21.0 + Node.js v22 has two unfixable interop bugs:
- --import tsx/esm hook: importSyncForRequire fails on @/ path aliases
- tsx runner: @next/env has __esModule:true but no .default export → TypeError

Solution: run SQL migrations directly via psql (alpine + postgresql-client).
All migration files use IF NOT EXISTS guards so they're idempotent on re-run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:12:02 +01:00
Vadym Samoilenko
a26a9c05ae fix(migrator): use tsx as runner instead of hook to fix Node.js v22 ESM interop
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
NODE_OPTIONS="--import tsx/esm" registers tsx as a hook, which exposes the
tsx@4.21.0 + Node.js v22 importSyncForRequire bug (named export not found).
Running tsx directly as the process runner handles TypeScript module loading
at a higher level, avoiding the CJS/ESM interop conflict.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:00:39 +01:00
Vadym Samoilenko
cff1baa871 fix(cms): add SEO plugin components to importMap, remove broken generate:importmap step
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
tsx@4.21.0 + Node.js v22 ESM/CJS interop bug prevents running `payload generate:importmap`
at Docker build time. Removed the failing RUN step and manually added the 5 SEO plugin
client components using the correct MD5-hashed identifier format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 19:51:58 +01:00
Vadym Samoilenko
c2e5db62a2 fix(docker): add .pnpmfile.mjs for pnpm 11 ESM import compatibility
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
pnpm 11 unconditionally tries to import .pnpmfile.mjs via dynamic ESM
import, throwing ERR_MODULE_NOT_FOUND when absent. Add empty hook file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 19:22:00 +01:00
Vadym Samoilenko
c707a70065 feat(migrations): remove push:true, run migrations automatically on deploy
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- Remove push:true from postgres adapter (unreliable for new columns)
- Remove profile:tools from migrate service so it runs on every deploy
- Add restart:no to migrate service (one-shot runner)
- App now depends on migrate with service_completed_successfully condition:
  postgres healthy → migrate applies pending → app starts

Workflow for future schema changes:
  1. Add field to collection/global TypeScript
  2. ssh server: docker-compose run --rm migrate migrate:create --name <field>
  3. git pull the generated .ts migration file
  4. commit + push → next deploy applies it automatically

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 19:11:50 +01:00
Vadym Samoilenko
1c08076963 feat(video): add video reviews to DyvoLis + homepage, fix importMap & ISR
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- Dockerfile: run generate:importmap before next build (fixes admin "Nothing found" and SEO fields)
- lokatsii/page.tsx: revalidate 3600→60 (fixes empty page after deploy)
- DyvoLisWhyVisit: replace 5 static image posters with 7 actual clickable videos; accept reviewVideos prop from CMS
- DyvoLisPage global: add reviewVideos array (text src/poster/label fields, CMS-editable)
- Reviews collection: add videoUrl + videoPoster text fields
- Reviews component: VideoReviewCard accepts src/poster props, renders dynamically from CMS reviews with videoUrl
- types/globals.ts: add videoUrl/videoPoster to ReviewCMS interface
- public/videos/dyvolis/: 7 converted MP4s (720p crf28) + 7 poster JPGs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 18:53:23 +01:00
Vadym Samoilenko
d5977e3215 feat(cms): add email-resend adapter, add defaultValues to checkout/thank-you globals
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 18:23:25 +01:00
Vadym Samoilenko
daf90b1127 fix(migrator): node:22 + NODE_OPTIONS tsx/esm for ESM bare specifier resolution
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 18:20:33 +01:00
Vadym Samoilenko
d9cc08d7f1 fix(migrator): use node:20 — tsx 4.21 ESM resolution broken on node:22
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 18:14:59 +01:00
Vadym Samoilenko
7c5b5979bd feat(cms): wire DyvoLis gallery to CMS, fix eslint config
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Add galleryImages array field to DyvoLisPage global so the photo gallery
is editable from Payload admin. Component falls back to 24 static images
when no CMS images are uploaded. Fix eslint flat-config error caused by
referencing @typescript-eslint plugin without an explicit import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 18:01:45 +01:00
Vadym Samoilenko
03c7640874 feat(migrations): add Payload migrator infrastructure
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Add Dockerfile.migrator (node:22-alpine + full source) and
docker-compose.prod.yml `migrate` service (profile: tools) so
migrations can be generated and applied on the server without
Node.js v26/tsx compatibility issues.

Workflow:
  # generate migration:
  docker compose --profile tools run --rm migrate migrate:create --name <desc>
  # apply pending migrations:
  docker compose --profile tools run --rm migrate

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 17:45:21 +01:00
Vadym Samoilenko
50c58674fb fix(orders): store name & phone in Order for complete checkout record
Previously name/phone were only in Lead, email only in Order — two
unlinked records. Now Order has all contact fields, enabling standalone
CRM view per purchase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 17:12:56 +01:00
Vadym Samoilenko
d0434dda9b feat(cms): upgrade Payload 3.33→3.84, add SEO plugin, connect hardcoded pages to CMS
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- Upgrade payload + all @payloadcms/* packages to 3.84.1
- Update minor/patch deps: drizzle-kit, tailwind-merge, vitest, playwright, etc.
- Fix eslint config: remove duplicate @typescript-eslint plugin registration
- Add @payloadcms/plugin-seo for pages, blog-posts, locations collections
- Remove manual meta fields from Pages (replaced by SEO plugin)
- Add DyvoLisPage global: hero, gallery quote, working hours, whyVisit items
- Add GroupVisitsPage global: hero, form texts, group types with discounts
- Connect /dni-narodzhennia to birthday-packages collection (was hardcoded)
- Connect /lokatsii/dyvolis to dyvolis-page global (was hardcoded)
- Connect /grupovi-vidviduvannia to group-visits-page global (was hardcoded)
- Remove STATIC_LOCATIONS fallback from /lokatsii (use DB or empty state)
- Refactor DyvoLisHero/Gallery/WhyVisit/Tickets to accept CMS props w/ fallbacks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 16:36:18 +01:00
Vadym Samoilenko
277a240359 feat(kvytky): add birthday & group visit sections with enquiry CTA
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Combo bundle tariffs moved to their own 'combo' category via DB.
Static sections for Дні народження (3 packages) and Групові відвідування
(3 types) added at the bottom with "Дізнатися ціну" buttons linking to
the respective booking forms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 15:48:43 +01:00
Vadym Samoilenko
380776fb03 fix(tariffs): include DB-only visible tariffs missing from ezy API
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Dyvolis tariffs (ezy_id 2001/2002) exist in DB but ezy returns only
the "Online" 3xxx-series tariffs from its activity endpoint. The merge
loop silently dropped anything not in the ezy response, leaving the
DyvoLis ticket section empty.

Now after building the ezy-merged list, DB-visible tariffs absent from
ezy are appended so every visible tariff shows up regardless of which
ezy activity it belongs to.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 15:32:18 +01:00
Vadym Samoilenko
e4b259afdc feat(cart): add persistent cart flow with /korzyna checkout page
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- CartContext + localStorage persistence across page navigation
- CartIcon with badge count in header (desktop + mobile)
- TariffCardClient: −/+ counter + "До кошика" on /kvytky
- DyvoLisTickets: fetch live tariffs, each card adds to cart
- PricingBlockComponent: split server/client, addToCart button
- /korzyna page: items, total, name/phone/email form, terms checkbox,
  "Оплатити N ₴" button — parallel POST to /api/leads + /api/tickets/checkout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 15:22:05 +01:00
Vadym Samoilenko
5035370cb2 fix(locations): always route dyvolis slug to /lokatsii/dyvolis page
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
CMS stores old href /lokatsii#dyvolis — override at component level for dyvolis slug.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 14:38:08 +01:00
Vadym Samoilenko
7b07fad924 feat(dyvolis): add Dyvo Lis 250 UAH ticket first, set hours to щодня
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
2026-05-13 14:10:07 +01:00
Vadym Samoilenko
d97a75882e feat(dyvolis): add Dyvo Lis 250 UAH ticket first, set hours to щодня
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 14:09:03 +01:00
Vadym Samoilenko
531185ab4b perf(dyvolis): compress 24 park photos for web (1200px max, JPEG 82%)
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
214 MB of RAW photos → 8 MB total (~97% reduction).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:40:59 +01:00
Vadym Samoilenko
1cd26c1749 feat(dyvolis): shift cat right, 60+ badge, real photos, colorful logo
- Hero: move cat panel right (left 15%, ellipse 20%) so it doesn't
  cover the left text column; adjust badge text Х→60+ with proper
  font size (50px) for 3-character label
- Gallery: replace 4 placeholder images with 24 real Dyvolis park
  photos (March 2026 shoot)
- WhyVisit carousel: use 5 real park photos as posters, increase
  card size from 505px to 600px with 4:3 aspect ratio
- Header: replace 3-SVG fallback logo with full-color brand PNG

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:36:22 +01:00
Vadym Samoilenko
722db0bb76 style: prettier class order in DyvoLisWhyVisit
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:00:15 +01:00
Vadym Samoilenko
9497cf6187 fix(dyvolis): fix X badge clamp values + add colorful favicon
- Fix negative clamp for marginRight: was returning -40px at 1440px
  instead of -101px (min/max were backwards for CSS negative clamp)
- Fix badge size: 11.11vw now hits 160px at lg (1440px)
- Fix font: 6.67vw now hits 96px at lg (was 86px)
- Fix paddingLeft of tip box: 10.28vw hits 148px at lg (was 137px)
- Add favicon.ico (multi-size 16/32/48/64) and icon.png (512x512)
  from the colorful Shumiland Ш brand mark (cropped from Figma asset)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 13:00:02 +01:00
Vadym Samoilenko
098339e23e feat(dyvolis): pixel-perfect update from Figma — video reviews, quote block, ticket redesign
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- Hero: bg #fdf2e8 → #f1fbeb (matches Figma page root)
- WhyVisit: replace auto-scroll photo gallery with single-card video-review
  carousel (poster + play btn, prev/next + dots, 5s auto-advance); add
  closing quote block per Figma node 4:202
- Tickets: first ticket relabelled "Вхід до ДиноПарку" per Figma; card bg
  #f1fbeb → #fdf2e8 (cream); combo subtitle order matches Figma node 4:160

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 12:35:46 +01:00
Vadym Samoilenko
1dab458ef9 fix(dyvolis): revert page wrapper bg to #f1fbeb (matches main page)
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 12:08:37 +01:00
Vadym Samoilenko
f9b122ed16 feat(dyvolis): pixel-perfect hero — cream bg, Figma-proportioned cat + orange ellipse
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
Positions derived from Figma node 3-546 (1920px frame): right panel=64vw,
cat at left=-20.1% top=-20.7% w=126.9%, ellipse container at left=-12.5% top=8% size=184.6%.
Adds ellipse-orange.svg gradient asset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 12:04:59 +01:00
Vadym Samoilenko
3ae7ff4bad feat(dyvolis): visual overhaul — bg color, 3D gallery, why-visit, compact tickets
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
- Change all #fdf2e8 → #f1fbeb (matches homepage light-green background)
- Hero: fix badge border color, add orange decorative glow ellipse behind cat
- Gallery: replace static grid with 3D coverflow carousel (auto-rotate + nav arrows)
- WhyVisit: redesign to match WhyParents layout (auto-rotate accordion + RAF scroll gallery)
- Tickets: compact cards with flex justify-between so CTA button is always at card bottom

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 11:18:18 +01:00