Commit graph

18 commits

Author SHA1 Message Date
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
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
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
ff4ae6934c feat(cms): add form relationship field to GroupVisitsPage and BirthdayPage 2026-05-18 11:58:21 +01:00
Vadym Samoilenko
4bda57b903 fix(cms): remove site-settings from livePreview + add label 2026-05-18 11:43:45 +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
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
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
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
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
d015c07f7f fix: TS non-null assertion in seed + formatting cleanup across components
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
Fixes Object possibly undefined TS2532 in findOrUploadMedia (seed/route.ts:50)
that was blocking production build. All other changes are whitespace/ordering
only (Tailwind class order, SVG attribute expansion).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:40:23 +01:00
Vadym Samoilenko
8b018ffa47 feat(cms): add hero overlays, pageHero bg, news subtitle, map group to HomePage global 2026-05-11 13:08:24 +01:00
Vadym Samoilenko
1cd20291d0 feat: wire all sections to Payload CMS + header dropdown + deploy config
- New collections: Locations, Reviews, BirthdayPackages
- New lib: getHomeData() — single cache-wrapped data fetch for homepage
- All sections now read from CMS with static fallbacks
- Header dropdown auto-populates 5 locations from Locations collection
- Seed API at /api/admin/seed creates all collections + uploads media
- docker-compose.prod.yml: replaced nginx/certbot with Traefik labels (shumi.ai-impress.com)
- Fixed image assignments: Locations 3-5 use gallery images (not news-bg)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 21:39:29 +01:00
Vadym Samoilenko
9b41fa447a feat: complete backend B1-B7 — Payload CMS, ezy payments, leads, 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
- B1: Next.js 15 + Payload CMS 3.0 + Postgres 16, ESLint, Prettier, Husky, Vitest
- B2: 9 collections, 6 globals, 12 Page Builder blocks, access control, slugify/revalidate hooks
- B3: ezy.com.ua payments, Binotel HMAC webhook, leads API, Telegram bot, Resend email, rate limiting
- B4: Tariffs collection with ezy API sync (cron + manual), dynamic pricing source-of-truth
- B5: 13 test files covering unit libs and all API routes
- B6: Dockerfile multi-stage, docker-compose.prod.yml, nginx.conf SSL, GitHub Actions CI/CD, health endpoint
- B7: docs/admin-guide-ua.md (marketer guide), docs/deploy.md (VPS instructions), README quickstart

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 19:14:54 +01:00