Connect storefront to backend catalog, search, and home slots.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-27 18:30:52 +03:30
co-authored by Cursor
parent 2f857f1a90
commit 0074ab6629
106 changed files with 5920 additions and 81 deletions
+127
View File
@@ -0,0 +1,127 @@
"use client";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useRef, useState } from "react";
import { BLACK_ITEMS } from "@/data/home";
export type BlackItemData = {
id: string;
image: string;
alt: string;
nameFa: string;
nameEn: string;
href: string;
};
type BlackCollectionProps = {
items?: BlackItemData[];
};
export default function BlackCollection({ items }: BlackCollectionProps) {
const list: BlackItemData[] =
items?.length
? items
: BLACK_ITEMS.map((item) => ({
id: item.id,
image: item.image,
alt: item.alt,
nameFa: item.nameFa,
nameEn: item.nameEn,
href: `/products?color=black&item=${item.id}`,
}));
const ref = useRef<HTMLElement>(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
setVisible(true);
return;
}
const io = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setVisible(true);
io.disconnect();
}
},
{ threshold: 0.15, rootMargin: "0px 0px -6% 0px" },
);
io.observe(el);
return () => io.disconnect();
}, []);
return (
<section
ref={ref}
className="relative mx-auto w-full max-w-[1710px] px-4 py-10 sm:px-6 lg:px-[120px] lg:py-14"
>
<div
className="seq-fade-item relative mb-8 flex items-center justify-center text-center lg:mb-10"
style={{
transitionDelay: visible ? "0ms" : "0ms",
opacity: visible ? 1 : 0,
transform: visible ? "translate3d(0,0,0)" : "translate3d(0,20px,0)",
}}
>
<p
dir="ltr"
aria-hidden
className="pointer-events-none absolute inset-0 flex items-center justify-center font-doran text-[clamp(2.5rem,8vw,6.25rem)] font-normal leading-none tracking-[0.1em] text-ink/10"
>
i Like it Black
</p>
<h2 className="font-doran relative translate-y-[0.12em] text-[clamp(1.75rem,4vw,3.125rem)] font-light leading-none text-ink">
من عاشق رنگ <span className="font-medium">مشکی</span> هستم
</h2>
</div>
<ul className="grid grid-cols-2 gap-[14px] lg:grid-cols-4 lg:gap-[22px]">
{list.map((item, i) => (
<li
key={item.id}
className="seq-fade-item"
style={{
transitionDelay: visible ? `${(i + 1) * 110}ms` : "0ms",
opacity: visible ? 1 : 0,
transform: visible
? "translate3d(0,0,0)"
: "translate3d(0,28px,0)",
}}
>
<Link
href={item.href}
className="group relative block aspect-[410/717] overflow-hidden bg-[#f3f3f3]"
>
<Image
src={item.image}
alt={item.alt}
fill
sizes="(max-width: 1024px) 50vw, 25vw"
className="object-cover transition-transform duration-700 group-hover:scale-[1.03]"
/>
<div className="absolute inset-x-3 bottom-3 z-10 overflow-hidden bg-white px-3 py-2.5 text-center sm:inset-x-4 sm:bottom-4 sm:px-4 sm:py-3">
<span
aria-hidden
className="pointer-events-none absolute inset-0 origin-bottom scale-y-0 bg-ink transition-transform duration-[400ms] ease-out group-hover:scale-y-100"
/>
<p className="relative z-10 font-doran text-base font-medium text-ink transition-colors duration-[400ms] ease-out group-hover:text-white sm:text-lg lg:text-xl">
{item.nameFa}
</p>
<p
dir="ltr"
className="relative z-10 mt-0.5 font-montserrat text-[10px] font-light uppercase tracking-[0.28em] text-[#898989] transition-colors duration-[400ms] ease-out group-hover:text-white sm:text-[11px]"
>
{item.nameEn}
</p>
</div>
</Link>
</li>
))}
</ul>
</section>
);
}