From 83283ed43c3ad0c09dd74fee19e318da77e26c5c Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Fri, 5 Jun 2026 12:39:05 +0100 Subject: [PATCH] feat(home): CMS-managed birthday card background patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Admins can now upload custom pattern images for green and orange pricing cards via Home Page → День народження → Паттерн зелених/оранжевої карток. Falls back to static /images/figma/card-pattern-*.png if not set. Co-Authored-By: Claude Sonnet 4.6 --- migrations/0014_birthday_patterns.sql | 15 +++++++++ src/app/(frontend)/page.tsx | 7 ++++- src/components/sections/BirthdayPricing.tsx | 35 +++++++++++++++++---- 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 migrations/0014_birthday_patterns.sql diff --git a/migrations/0014_birthday_patterns.sql b/migrations/0014_birthday_patterns.sql new file mode 100644 index 0000000..afaf318 --- /dev/null +++ b/migrations/0014_birthday_patterns.sql @@ -0,0 +1,15 @@ +-- 0014: birthday card background pattern media fields on home_page global + +-- Live table: two nullable FK columns referencing media +ALTER TABLE "home_page" + ADD COLUMN IF NOT EXISTS "birthday_intro_pattern_green_id" integer + REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION, + ADD COLUMN IF NOT EXISTS "birthday_intro_pattern_orange_id" integer + REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION; + +-- Versions table: same columns on the version snapshot table +ALTER TABLE "_home_page_v" + ADD COLUMN IF NOT EXISTS "version_birthday_intro_pattern_green_id" integer + REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION, + ADD COLUMN IF NOT EXISTS "version_birthday_intro_pattern_orange_id" integer + REFERENCES "media"("id") ON DELETE SET NULL ON UPDATE NO ACTION; diff --git a/src/app/(frontend)/page.tsx b/src/app/(frontend)/page.tsx index 33a8eae..af68a0b 100644 --- a/src/app/(frontend)/page.tsx +++ b/src/app/(frontend)/page.tsx @@ -73,15 +73,20 @@ export default async function HomePage() { src={home?.video?.src ?? undefined} /> ) - case 'birthday': + case 'birthday': { + const pg = home?.birthdayIntro?.patternGreen + const po = home?.birthdayIntro?.patternOrange return ( 0 ? birthdayPackages : undefined} title={home?.sectionTitles?.birthday ?? undefined} intro={home?.birthdayIntro?.text ?? undefined} + patternGreen={pg && typeof pg === 'object' ? (pg.url ?? undefined) : (pg ?? undefined)} + patternOrange={po && typeof po === 'object' ? (po.url ?? undefined) : (po ?? undefined)} /> ) + } case 'gallery': return ( @@ -37,7 +47,12 @@ export function BirthdayPricing({ packages, title, intro }: BirthdayPricingProps {/* Figma 1:231 — non-featured wrappers get pt-84 so featured card stands 84px taller */}
{activePackages.map((pkg) => ( - + ))}
@@ -49,7 +64,15 @@ function formatPrice(price: number, currency: string | null | undefined): string return `${price.toLocaleString('uk-UA')} ${currency ?? '₴'}` } -function PricingCard({ pkg }: { pkg: BirthdayPackageCMS }) { +function PricingCard({ + pkg, + imgPatternGreen, + imgPatternOrange, +}: { + pkg: BirthdayPackageCMS + imgPatternGreen: string + imgPatternOrange: string +}) { const { name, price, @@ -116,7 +139,7 @@ function PricingCard({ pkg }: { pkg: BirthdayPackageCMS }) { aria-hidden="true" className="pointer-events-none absolute inset-0" style={{ - backgroundImage: `url('${featured ? IMG_PATTERN_ORANGE : IMG_PATTERN_GREEN}')`, + backgroundImage: `url('${featured ? imgPatternOrange : imgPatternGreen}')`, backgroundSize: '100% auto', backgroundRepeat: 'repeat', opacity: 0.2,