Commit graph

62 commits

Author SHA1 Message Date
Vadym Samoilenko
d327c841d7 feat(groups): add heroImage field to GroupVisitsPage global + connect to 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
2026-06-03 14:52:44 +01:00
Vadym Samoilenko
69675851f8 fix(groups): connect amenities array to CMS — was hardcoded, now reads label+image from global 2026-06-03 14:49:38 +01:00
Vadym Samoilenko
a2fb01ea11 fix(ui): center CTA buttons (no full-width stretch), move birthday hero title to bottom
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-06-03 14:33:21 +01:00
Vadym Samoilenko
0ef399c2f5 fix(seed-forms): always run updateGlobal — fixes re-link on partial state
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 early-return guard that skipped global linking when both forms already existed. Per-form idempotency is handled by the '?? await payload.create()' pattern, so we can safely always run updateGlobal to ensure forms are linked to their globals even after re-runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 14:06:02 +01:00
Vadym Samoilenko
41593c8edc fix(seed-forms): add confirmationMessage to both form creates
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 forms plugin requires a Lexical rich-text confirmationMessage
when confirmationType is 'message'; omitting it caused a 500 on seed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 14:02:28 +01:00
Vadym Samoilenko
b5c34f6f0b fix(seed-forms): tighten auth guard + per-form idempotency to handle partial failures
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
- Fix auth bypass when SYNC_SECRET env var is unset: now defaults to empty string
- Change idempotency check from totalDocs >= 2 to per-form existence checks
- Allow reuse of existing forms instead of creating duplicates if one creation fails
- Handles partial seed state gracefully (e.g., birthday form exists but group form missing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 13:59:06 +01:00
Vadym Samoilenko
65498e2da5 feat(cms): add seed-forms route — creates birthday + group-visits forms and links to globals 2026-06-03 13:56:58 +01:00
Vadym Samoilenko
cd8d5673d1 perf: compress loc- images, fix hero fetchpriority, fix layout broken tag, Binotel SEO links
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-06-02 21:39:02 +01:00
Vadym Samoilenko
deead80f2a perf: compress all images (-70MB), preload LCP hero, convert PNG→JPEG, remove dead files
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-06-02 21:32:49 +01:00
Vadym Samoilenko
208e0506e8 fix(telegram): correct Ukrainian grammar (Нове замовлення), show tariff name + customer name/phone in order alert
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-06-02 20:01:16 +01:00
Vadym Samoilenko
f2a560f9e6 feat: kvytky 1:1 redesign, CMS-driven pages, blog/group/birthday updates, green-wave pattern, image optimization
- /kvytky: combo grid (cart add), tabbed catalog with Figma chips/photos, CMS-editable (TicketsPage global)
- Tariffs collection: infoChips, badgeLabel, category zone/attraction/program, manual tickets
- Birthday & Group pages: Figma design + real photos, pricing sections removed (form-only), unified form style
- Thank-you page (pidtverdzhennya) from Figma; combo cards redesigned (4-up grid)
- Reviews coverflow slider; blog photos fixed (relative media URLs for next/image)
- JSON-LD (WebPage/LocalBusiness/CollectionPage/Service) on home/lokatsii/birthday/group
- Footer: photo bg + AImpress credit link; green wave pattern on green sections; consistent footer
- Imported 3 real blog posts from staging; fixed text artifacts
- Optimized 118 images 563MB -> 72MB (resize 1920px + re-encode)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 16:46:52 +01:00
Vadym Samoilenko
a3618448a8 feat(dynopark): hero banner, 5-dino wheel, silhouette dinos + deploy assets
- DinoPageContent: wheel shows exactly 5 dinos in the bottom bowl (fixed 30°
  slot, decoupled from CMS dino count; far nodes parked off-screen)
- non-active dinos darkened to silhouettes, active stays full color
- hero banner swapped to blue T-Rex, height 1096px, 12px gap below header
- optimize heavy CMS images (61MB -> 9MB) and commit media + public assets
  so git holds everything needed for deploy

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:33:40 +01:00
Vadym Samoilenko
4575717c73 fix: DinoWheel — bigger wheel, correct initial angle (active top), 4-photo gallery, orange segments
- Wheel size increased: 1500px at 1440vw, overflows and clips correctly
- Fixed initial wheelAngle from 270 → -(180/n) so item[0] is at top on load
- Segment colors: unified warm orange, only active+adjacent highlighted
- Removed pagination dots/arrows (not in Figma)
- Gallery: 4 photos in grid, no border, rounded corners
- page.tsx: use FALLBACK when CMS has < 20 dinos (maps epoch→latinName, weight→height)
2026-05-31 13:43:04 +01:00
Vadym Samoilenko
83d274f0ba feat(pages): implement all 6 pages from Figma + fix nav dropdown
Pages implemented:
- grupovi-vidviduvannia: tilted polaroid banners, amenity grid, wave pricing, correct Figma tile pattern
- dni-narodzhennia: hero, package cards, pricing, order form
- kvytky: horizontal ticket rows with photos, tabs, combo, benefits accordion
- kvytky/dyakuiemo: SVG ticket shape with perforations
- dynozavry: DinoWheel 25 dinosaurs with real images + gallery (node 2004:560/568)
- HeroSlider: vertical slider with 6 slides

Components:
- DinoWheel: complete 25-dino dataset from Figma, orange semicircle SVG rotation, gallery below
- KvytkyTicketsClient: rewritten to horizontal row layout matching Figma
- HeaderClient: remove overflow-hidden clipping dropdown; add chevron indicator
- Header: inherit DEFAULT_NAV children when CMS has no children for that item

Fixes:
- Nav dropdown: CMS was overriding DEFAULT_NAV without children — now inherits
- Wave pattern: use correct Figma wave tile (wave-tile-correct.png, 657x868px) for .wave-bg-pricing
- Lokatsii nav links: ДиноПарк → /lokatsii/dynozavry, ДивоЛіс → /lokatsii/dyvolis

Assets: 35+ new images (dino-*, group-*, birthday-*, ticket-*, gallery)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 20:02:50 +01:00
Vadym Samoilenko
f317de7b0f feat(assets): connect static images as fallbacks; fix location slug mapping
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
- DinoGallery: add real park photos as static fallback (T-Rex, aerial, arch)
- DinoHero: use T-Rex PNG as fallback when no CMS heroImage uploaded
- Locations/lokatsii: add DB slug aliases (dzerkalnyi-labiryt→maze, tyr→tir,
  maiydanchyk→playground) so all 5 locations get correct images

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 17:04:57 +01:00
Vadym Samoilenko
ef693589bc fix(header,accordion): liquid-glass header + progress bar animation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 16:51:24 +01:00
Vadym Samoilenko
6863f5022d feat(pages): redesign all 6 pages to match Figma designs with full CMS coverage
- Birthday: new pricing structure (component breakdown instead of packages),
  packageItems with image upload per card, why/accordion CMS fields
- GroupVisits: all text/prices/images CMS-editable (heroDescription, amenities,
  featureImages, workingHours, price, bottomImages, etc.)
- DyvoLis: fixed 404 (seed location record), combo tickets now show (600/1500/1800/2000)
- ThankYou: DyvoLis topiary background, 'Купити квиток' button text
- Tariffs: updated to match Figma (300/150/300/50 dyno + 4 combo variants)
- Seed: add DyvoLis location, correct hero text and section titles for home

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 16:27:24 +01:00
Vadym Samoilenko
0e732bfbd5 feat(home): apply Figma design — new hero + location photos, WhyParents gallery
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: "Започаткуйте традицію:" title at 96px, subtitle 48px/Black
  (щороку фотографуйтесь біля улюбленого динозавра); removed separate
  T-Rex/family overlays — T-Rex now baked into hero-bg2
- WhyParents: replaced desktop auto-scroll photo gallery with 3 static
  video thumbnail cards with play buttons (Figma Gallery_holder layout)
- Assets: replace hero + 5 location images with real 2026 park photos
  from Figma; add why-parents-video.webp thumbnail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 15:01:19 +01:00
Vadym Samoilenko
ef629dbdbe feat(pages): add dinosaur park page + redesign birthday, group visits, thank-you
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 pages:
- /lokatsii/dynozavry — DinosaurPage (static ISR): DinoHero, DinoWheel (interactive
  8-species arc selector, auto-rotate 4s), DinoGallery, DinoActivities, DinoWhyVisit,
  DinoTickets (ezy API dyno+combo categories)
- /kvytky/dyakuiemo — thank-you page with ticket-shaped card design

Redesigned pages:
- /dni-narodzhennia — new hero, "Що входить" 6-card section, WhyVisit accordion,
  pricing grid from BirthdayPackages CMS, form preserved
- /grupovi-vidviduvannia — new hero overlay, description band, amenity 2x2 grid,
  350 грн ticket card, bottom CTA section, form preserved

New CMS:
- DinosaurPage global (slug: dinosaur-page) with 7 array sub-tables
- migration 0006_dinosaur_page.sql — idempotent, creates all tables + dynozavry location
- seed/route.ts — seeds DinosaurPage global with 8 dino species defaults
- payload.config.ts — registers DinosaurPage in globals, seoPlugin, livePreview

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:28:52 +01:00
Vadym Samoilenko
5ca72de20f fix(seed): fix TS cast for home-page guard
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-18 13:31:15 +01:00
Vadym Samoilenko
c07fd6913c fix(seed): guard home-page update by checking existing content
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
Avoids invalid relationship errors when home-page already has data.
Only updates home-page on first seed when hero is absent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:29:58 +01:00
Vadym Samoilenko
1f752a57b0 fix(seed): skip home-page update when media files unavailable in Docker
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
Prevents 500 error on prod where public/images/* aren't in the container.
Forms seeding and site-settings init can now proceed unblocked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:26:37 +01:00
Vadym Samoilenko
85d2f7d16e fix(forms): fix message render, confirmation text, radio disabled, placeholder, replyTo
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
- Replace dangerouslySetInnerHTML with extractLexicalText helper for message blocks
- Show CMS confirmationMessage text on success instead of hardcoded string
- Disable radio field in plugin config (not rendered in FormBlock)
- Remove placeholder from text/number/textarea/date seed fields (plugin ignores them)
- Replace {{email}} replyTo template with static manager email fallback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:13:22 +01:00
Vadym Samoilenko
3ea4d95cc7 feat(seed): add GroupRequest and BirthdayBooking forms + assign to page globals 2026-05-18 12:08:34 +01:00
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
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
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
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
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
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
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
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
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
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
Vadym Samoilenko
91d11c1009 fix(nav): fix dropdown hover gap + add location page buttons
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
- HeaderClient: wrap dropdown in pt-2 bridge div so hover never lost
  when moving mouse from nav item to dropdown list
- Locations, Header: dyvolis href → /lokatsii/dyvolis (dedicated page)
- lokatsii page: add "Детальніше" button for locations with own page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 11:03:13 +01:00
Vadym Samoilenko
d8a443fe7f feat(dyvolis): add DyvoLis location page with sections
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 page route /lokatsii/dyvolis
- DyvoLisHero: title, subtitle, CTA, X-badge + 3 green info tips, topiary cat image
- DyvoLisGallery: quote banner + 4 Figma gallery photos
- DyvoLisWhyVisit: interactive accordion (3 items) + video cards + description
- DyvoLisTickets: working hours banner, 4 ticket cards, 4 combo cards
- Downloaded Figma assets to public/images/dyvolis/
- Fix .gitignore: scope *.png/jpg/jpeg to root-level only (was blocking public/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 10:57:24 +01:00
Vadym Samoilenko
b628a2bfb9 fix: set #f1fbeb background everywhere except hero and footer
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-11 16:33:04 +01:00
Vadym Samoilenko
54d00080ff fix: lokatsii page unique images + video gallery-width container
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
- lokatsii/page.tsx: per-slug FALLBACK_IMAGES map prevents all cards showing dinopark photo
- VideoSection: constrain to max-w-[1204px] gallery-width container

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 15:57:20 +01:00
Vadym Samoilenko
f8421ed42d feat: blog posts, redesigned sections, video full-width, reviews hover pause
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
- Blog listing: force-dynamic SSR, new photo cards with date badge + hover animation
- Blog article: custom typography (h1-h3 styling, lists, blockquotes) without plugin
- News.tsx: fix hero image mapping (direct upload, not .image sub-field)
- Reviews.tsx: hover pauses auto-scroll, resumes on mouse leave; fix poster 404
- VideoSection: full viewport width, no container constraint
- next.config.ts: add shumi.ai-impress.com to remotePatterns (fixes 400 on blog images)
- Seed: add _status published for Payload drafts; force-posts flag; real blog photos
- Locations.tsx: per-slug fallback images (fixes all cards showing dinopark photo)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 15:52:08 +01:00
Vadym Samoilenko
2fa4040114 fix: media uploads 500 error + add video review card to Reviews
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: create /app/media dir with nextjs ownership before USER switch
- docker-compose.prod.yml: mount named volume shumiland-media-uploads → /app/media
- Reviews: add VideoReviewCard component with 9:16 portrait inline player
- Add review-video.mp4 (93s, 720×1280, 15MB) + poster from IMG_8336.MOV

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 14:17:05 +01:00
Vadym Samoilenko
9562db84e3 feat(blog): add 3 real articles + blog image placeholders to seed
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 seed data for 3 Shumiland articles (Сезон пригод, Капсула часу, Травень)
- Create public/images/blog/ with placeholder hero images
- Full Lexical body content for each post
- Add makeLexical() helper for paragraph formatting in seed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 14:08:37 +01:00
Vadym Samoilenko
574b125626 fix: production UI fixes + brand color #396817 + new page backgrounds
- Replace all #223e0d → #396817 across 24 files
- Page bg: #f1fbeb (lightest green tint), BirthdayPricing: #fefaf6 (warm cream)
- Hero: raise text to z-[25] above T-Rex, reduce font clamp, narrow max-w
- PageHero: remove negative z-index that hid photo background
- GallerySlider: replace setInterval+state with rAF+pauseRef, seamless half-wrap reset
- Reviews: fix sub-pixel scroll (speed 0.3 → 1, intervalMs 16 → 20)
- BtnPrimary: gradient background orange→yellow→orange with hover scale
- Footer: add static fallback contacts (phone, address, metro, hours, Instagram, Facebook)

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