Add /products (list + detail) and /blog (list + detail) routes backed by the real Meshkee API, a real category-hierarchy mega menu (level 2/3 only), debounced instant search proxied through a same-origin API route, and tel:-link fallbacks on product cards when no price is set. Also fixes Product price normalization to read the real API shape instead of a guessed one, and hardens product linking against catalog sources that don't expose a slug. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { Carousel } from "@/components/ui/Carousel";
|
|
import { ProductCard } from "@/components/ui/ProductCard";
|
|
import { SectionTitle } from "@/components/ui/SectionTitle";
|
|
import { EmptyState } from "@/components/ui/EmptyState";
|
|
import { productHref, type Product } from "@/lib/meshkee";
|
|
|
|
export function TopSellingCarousel({
|
|
products,
|
|
contactPhone,
|
|
}: {
|
|
products: Product[];
|
|
contactPhone?: string;
|
|
}) {
|
|
return (
|
|
<section className="py-10 md:py-14">
|
|
<div className="mx-auto max-w-7xl px-4">
|
|
<SectionTitle
|
|
title="پرفروشترینها"
|
|
enTitle="Top Selling"
|
|
action="مشاهده همه"
|
|
/>
|
|
{products.length === 0 ? (
|
|
<EmptyState message="هنوز محصولی ثبت نشده است." />
|
|
) : (
|
|
<Carousel ariaLabel="کاروسل پرفروشترینها">
|
|
{products.map((product) => (
|
|
<ProductCard
|
|
key={product.id}
|
|
name={product.name}
|
|
brand={product.brand ?? ""}
|
|
price={product.price}
|
|
image={product.image ?? "/images/placeholder.svg"}
|
|
href={productHref(product)}
|
|
contactPhone={contactPhone}
|
|
/>
|
|
))}
|
|
</Carousel>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|