- 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>
- 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>
- 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>
- 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>
- 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>
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>
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>
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>
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>
- 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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
- 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>
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>
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>
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>
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>
- 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>
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>