100 lines
3.3 KiB
TypeScript
100 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import React from 'react';
|
|
import Link from 'next/link';
|
|
import { getImageUrl } from '../lib/utils';
|
|
|
|
interface PromoBanner {
|
|
id: string;
|
|
title: string;
|
|
subtitle: string;
|
|
cta: string;
|
|
href: string;
|
|
image: string;
|
|
bgColor: string;
|
|
}
|
|
|
|
const DEFAULT_BANNERS: PromoBanner[] = [];
|
|
|
|
interface PromoBannersSectionProps {
|
|
config?: any;
|
|
}
|
|
|
|
function mapConfigBanners(raw: any[]): PromoBanner[] {
|
|
return raw.slice(0, 2).map((b: any, idx: number) => {
|
|
return {
|
|
id: String(b.id || `banner-${idx + 1}`),
|
|
title: String(b.title || ''),
|
|
subtitle: String(b.subtitle || ''),
|
|
cta: String(b.cta || b.buttonText || b.button_text || 'Shop Now'),
|
|
href: String(
|
|
b.buttonUrl || b.button_url || b.link || b.href || '/shop'
|
|
),
|
|
image: getImageUrl(b.image || b.image_url) || '',
|
|
bgColor: String(b.bgColor || b.bg_color || '#F2F4F3'),
|
|
};
|
|
});
|
|
}
|
|
|
|
export const PromoBannersSection: React.FC<PromoBannersSectionProps> = ({
|
|
config,
|
|
}) => {
|
|
const fromConfig =
|
|
config?.metadata_json?.banners || config?.metadata?.banners;
|
|
const banners =
|
|
Array.isArray(fromConfig) && fromConfig.length > 0
|
|
? mapConfigBanners(fromConfig)
|
|
: DEFAULT_BANNERS;
|
|
|
|
if (banners.length === 0) return null;
|
|
|
|
return (
|
|
<section className="pt-2 pb-6 bg-white font-sans">
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-[1400px]">
|
|
{config?.title && (
|
|
<div className="text-left mb-5">
|
|
<h2 className="text-xl md:text-2xl font-bold text-[#222] tracking-tight">
|
|
{config.title}
|
|
</h2>
|
|
</div>
|
|
)}
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-5">
|
|
{banners.map((banner) => (
|
|
<Link
|
|
key={banner.id}
|
|
href={banner.href}
|
|
className="group flex overflow-hidden rounded-xl min-h-[200px] md:min-h-[220px] transition-transform duration-300 hover:-translate-y-0.5"
|
|
style={{ backgroundColor: banner.bgColor }}
|
|
>
|
|
<div className="relative z-10 flex w-[54%] shrink-0 flex-col justify-center items-start text-left pl-7 md:pl-9 pr-4 py-7">
|
|
<h3 className="text-[18px] md:text-[20px] lg:text-[22px] font-bold text-[#1a1a1a] leading-[1.3] mb-2 break-words">
|
|
{banner.title}
|
|
</h3>
|
|
{banner.subtitle ? (
|
|
<p className="text-[13px] md:text-[14px] text-gray-500 mb-5">
|
|
{banner.subtitle}
|
|
</p>
|
|
) : null}
|
|
<span className="text-[14px] font-bold text-[#1a1a1a] underline underline-offset-4 decoration-1 group-hover:text-primary transition-colors">
|
|
{banner.cta}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="relative w-[46%] min-h-[200px] md:min-h-[220px] overflow-hidden flex items-end justify-center bg-gray-100">
|
|
{banner.image ? (
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img
|
|
src={banner.image}
|
|
alt={banner.title}
|
|
className="absolute inset-0 w-full h-full object-cover object-center"
|
|
/>
|
|
) : null}
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|