Connect storefront to backend catalog, search, and home slots.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
2f857f1a90
commit
0074ab6629
@@ -0,0 +1,172 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
type PromoVariant = "sale" | "discount" | "autumn";
|
||||
|
||||
export type PromoSlotOverride = {
|
||||
image?: string;
|
||||
nameFa?: string;
|
||||
nameEn?: string;
|
||||
subtext?: string;
|
||||
link?: string;
|
||||
};
|
||||
|
||||
type PromoCardProps = {
|
||||
variant: PromoVariant;
|
||||
href?: string;
|
||||
className?: string;
|
||||
slot?: PromoSlotOverride | null;
|
||||
};
|
||||
|
||||
const META: Record<
|
||||
PromoVariant,
|
||||
{ href: string; labelFa: string }
|
||||
> = {
|
||||
sale: { href: "/products?sale=1", labelFa: "" },
|
||||
discount: { href: "/products?sale=1", labelFa: "بهترین مانتوهای ما" },
|
||||
autumn: {
|
||||
href: "/products?collection=autumn",
|
||||
labelFa: "کالکشن پاییزه",
|
||||
},
|
||||
};
|
||||
|
||||
const CARD_SHELL =
|
||||
"relative flex h-[491px] w-full flex-col overflow-hidden rounded-[19px] border border-[#8e8e8e]/30";
|
||||
|
||||
/** Full-bleed creative when Website Images provides a slot image. */
|
||||
function FullImagePromo({
|
||||
href,
|
||||
image,
|
||||
alt,
|
||||
className,
|
||||
}: {
|
||||
href: string;
|
||||
image: string;
|
||||
alt: string;
|
||||
className: string;
|
||||
}) {
|
||||
return (
|
||||
<Link href={href} className={`${CARD_SHELL} bg-white ${className}`}>
|
||||
<Image
|
||||
src={image}
|
||||
alt={alt}
|
||||
fill
|
||||
sizes="(max-width: 768px) 50vw, 324px"
|
||||
className="object-cover object-center"
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PromoCard({
|
||||
variant,
|
||||
href,
|
||||
className = "",
|
||||
slot,
|
||||
}: PromoCardProps) {
|
||||
const meta = META[variant];
|
||||
const to = slot?.link || href || meta.href;
|
||||
|
||||
if (slot?.image) {
|
||||
return (
|
||||
<FullImagePromo
|
||||
href={to}
|
||||
image={slot.image}
|
||||
alt={slot.nameFa || slot.nameEn || slot.subtext || "promo"}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === "sale") {
|
||||
return (
|
||||
<Link href={to} dir="ltr" className={`${CARD_SHELL} bg-ink text-white ${className}`}>
|
||||
<div className="relative flex flex-1 items-center justify-center px-6 pt-10">
|
||||
<div className="relative h-[200px] w-[140px]">
|
||||
<Image
|
||||
src="/images/home/banners/sale-script.png"
|
||||
alt=""
|
||||
fill
|
||||
className="object-contain opacity-45"
|
||||
sizes="140px"
|
||||
/>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<Image
|
||||
src="/images/home/icons/sale-wordmark.svg"
|
||||
alt="Sale"
|
||||
width={200}
|
||||
height={100}
|
||||
unoptimized
|
||||
className="h-auto w-[170px] max-w-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-6 pb-8 text-center">
|
||||
<p className="whitespace-nowrap font-montserrat text-[15px] font-normal tracking-[0.2em] uppercase sm:text-lg">
|
||||
Our Season Finale
|
||||
</p>
|
||||
<p className="mt-1 whitespace-nowrap font-montserrat text-xl font-semibold tracking-[0.18em] uppercase sm:text-2xl">
|
||||
Up to 70% OFF
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === "discount") {
|
||||
return (
|
||||
<Link
|
||||
href={to}
|
||||
dir="ltr"
|
||||
className={`${CARD_SHELL} bg-white px-6 py-8 text-ink sm:px-8 sm:py-10 ${className}`}
|
||||
>
|
||||
<div className="flex flex-1 flex-col items-center justify-center text-center uppercase">
|
||||
<p className="whitespace-nowrap text-[24px] font-light tracking-[0.7em] sm:text-[30px] sm:tracking-[0.84em]">
|
||||
Up TO
|
||||
</p>
|
||||
<p className="-mt-1 font-montserrat text-[64px] font-medium leading-none tracking-[0.12em] sm:text-[80px] sm:tracking-[0.19em]">
|
||||
70%
|
||||
</p>
|
||||
<p className="-mt-1 whitespace-nowrap font-montserrat text-[24px] font-light tracking-[0.1em] sm:text-[30px] sm:tracking-[0.13em]">
|
||||
Discount
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-center text-[18px] font-light sm:text-[23px]">
|
||||
{slot?.nameFa || meta.labelFa}
|
||||
</p>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={to}
|
||||
dir="ltr"
|
||||
className={`${CARD_SHELL} bg-white px-6 py-8 sm:px-8 sm:py-10 ${className}`}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center">
|
||||
<div className="relative size-[140px] sm:size-[160px]">
|
||||
<Image
|
||||
src="/images/home/banners/autumn-leaf.png"
|
||||
alt=""
|
||||
fill
|
||||
className="object-contain mix-blend-darken"
|
||||
sizes="160px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center text-center uppercase">
|
||||
<p className="whitespace-nowrap font-montserrat text-[18px] font-light tracking-[0.04em]">
|
||||
i wanted it for
|
||||
</p>
|
||||
<p className="font-montserrat text-[32px] font-medium tracking-[0.2em]">
|
||||
Autumn
|
||||
</p>
|
||||
<p className="mt-3 text-[18px] font-light normal-case sm:text-[20px]">
|
||||
{slot?.nameFa || meta.labelFa}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user