Commit graph

132 commits

Author SHA1 Message Date
Vadym Samoilenko
00a3ae163a Merge remote-tracking branch 'origin/main'
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-01 21:36:07 +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
ab4ca5ea64 fix: DinoWheel — sync 25 dino FALLBACK data with Figma + add Quetzalcoatlus asset
- Fixed subtitles for all 25 dinosaurs per Figma dino_slider variants
- Added missing latinNames (Baryonyx, Oviraptor, Spinosaurus, Carnotaurus, etc.)
- Fixed Quetzalcoatlus: real Figma asset downloaded, length 6.5m
- Fixed Карнотавр ДиноРодео imageUrl to carnotaurus_1.jpg
- Fixed Тиранозавр що прогулюються парком imageUrl
- Removed duplicate brackets from subtitle display (data carries brackets)
- Added all 35 dynopark image assets to public/dynopark/
2026-05-31 13:30:12 +01:00
Vadym Samoilenko
2d82e39e25 feat: DinoWheel — arc segments with active highlight, gradient yellow→dark, colored active dino photo
- Replaced flat gradient circle with individual arc segments using arcPath SVG helper
- Active segment: bright yellow #F5D169, fades to dark brown at edges (6-level palette)
- Active dino icon: 12% wheelSize (was 10%), uses DINO_ACTIVE_RADIUS for positioning
- segFill() computes color by distance from active index (circular wrap)
- Fixed angleForItem() → -((i+0.5)*360/n) so active segment always at 12 o'clock
- naturalDeg for icons = (i+0.5)*step to center icon within segment
- Added Baryonyx and Kosmoceratops real photo imageUrls
2026-05-31 13:14:19 +01:00
Vadym Samoilenko
abdef5e0bb fix: DinoHero — correct bg #F2F5E8, dark text, green pills, T-Rex right col only 2026-05-31 12:53:41 +01:00
Vadym Samoilenko
b02954ef77 feat(dynopark): pixel-perfect Figma redesign of all 6 DinoXxx sections
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
- DinoHero: dark bg (#1e1e1e), white text, T-Rex from /dynopark/, orange-amber circle
- DinoWheel: vertical layout (info → arch → photos), 25 dinos with real /dynopark/ images,
  orange-framed photo gallery at bottom, responsive wheel size via useRef
- DinoGallery: updated fallback images to /dynopark/ real park photos
- DinoActivities: photo-overlay portrait cards, gradient, price badges, exact UA text;
  sm:grid-cols-2 md:grid-cols-3 (project uses --breakpoint-lg: 1440px)
- DinoWhyVisit: photo carousel (Gemini park photos) replaces video default,
  "ЗАРАЗ МИ ДІЗНАЄМОСЯ..." label overlay, exact accordion text from Figma
- DinoTickets: dark green #396817 + wave bg pattern, large price typography (64px/900),
  "Забронювати пригоду" CTA, working hours banner, keeps cart functionality

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 12:39:41 +01:00
Vadym Samoilenko
7a26ace8e4 feat(dynopark): pixel-perfect Figma redesign of all 6 DinoXxx sections
- DinoHero: dark bg (#1e1e1e), white text, T-Rex from /dynopark/, orange-amber circle
- DinoWheel: vertical layout (info → arch → photos), 25 dinos with real /dynopark/ images,
  orange-framed photo gallery at bottom, responsive wheel size via useRef
- DinoGallery: updated fallback images to /dynopark/ real park photos
- DinoActivities: photo-overlay portrait cards, gradient, price badges, exact UA text;
  sm:grid-cols-2 md:grid-cols-3 (project uses --breakpoint-lg: 1440px)
- DinoWhyVisit: photo carousel (Gemini park photos) replaces video default,
  "ЗАРАЗ МИ ДІЗНАЄМОСЯ..." label overlay, exact accordion text from Figma
- DinoTickets: dark green #396817 + wave bg pattern, large price typography (64px/900),
  "Забронювати пригоду" CTA, working hours banner, keeps cart functionality

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 12:33:53 +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
32e0f688d1 fix(header,sliders): solid green header + fix coverflow overflow clipping
- Header: remove liquid-glass transparency; solid #396817 background so header
  no longer bleeds orange from the hero background
- GallerySlider/DinoGallery/DyvoLisGallery: change overflow-hidden to
  overflowX:clip so side cards in 3D coverflow are visible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 16:35:15 +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
095beb0303 fix(assets): rename assets to v2 to bust immutable browser cache; fix /images/ cache header
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
- Rename all new Figma 2026 assets to *-v2.webp so browsers load fresh
  copies instead of serving year-old cached originals
- Change Cache-Control for /images/ from immutable (1 year) to
  must-revalidate (1 day) — public/ files are mutable, not hashed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 15:13:44 +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
492f7934b6 feat(home): update hero typography + locations slider layout
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: larger title (clamp to 120px), wider text block, adjusted padding
- LocationsSlider: overlay moved to left side, white text color, larger description

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:33:06 +01:00
Vadym Samoilenko
4cc6586366 fix(gallery): replace CSS scroll with 3D coverflow slider everywhere; fix migration SEO columns
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
- GallerySlider: rewrite to 3D coverflow (rotateY perspective, 3.5s auto-rotate,
  dots + arrows, lightbox on center click) — matches DyvoLisGallery style
- migration 0006: add meta_title/description/image_id columns for seoPlugin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 14:17:12 +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
f3c3d2c978 feat(migration): 0005 — add site_settings_tariff_category_labels table
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
Sub-table for the tariffCategoryLabels array field added to SiteSettings
global. Was missing from prod DB causing query failures on every page load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:36:54 +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
fd55afd773 feat(migration): add 0004_form_builder.sql for prod SQL migrator
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
Extracts forms + form_submissions schema from TS migrations into
idempotent SQL so Dockerfile.migrator can apply it on production.
Also updates generated payload-types after form-builder plugin.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:21:06 +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
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