Connect product/blog pages, mega menu, and instant search to Meshkee backend
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>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
1f81236d0a
commit
2b5f4e437b
@@ -4,11 +4,14 @@ import { formatPrice } from "@/data/sample";
|
||||
type ProductCardProps = {
|
||||
name: string;
|
||||
brand: string;
|
||||
price: number;
|
||||
oldPrice?: number;
|
||||
price: number | null;
|
||||
oldPrice?: number | null;
|
||||
discount?: number;
|
||||
image: string;
|
||||
variant?: "sale" | "default" | "brand";
|
||||
href?: string;
|
||||
fluid?: boolean;
|
||||
contactPhone?: string;
|
||||
};
|
||||
|
||||
export function ProductCard({
|
||||
@@ -19,17 +22,19 @@ export function ProductCard({
|
||||
discount,
|
||||
image,
|
||||
variant = "default",
|
||||
href,
|
||||
fluid = false,
|
||||
contactPhone,
|
||||
}: ProductCardProps) {
|
||||
return (
|
||||
<article className="group w-[220px] shrink-0 overflow-hidden rounded-xl border border-border bg-surface transition-shadow hover:shadow-md md:w-[240px]">
|
||||
const info = (
|
||||
<>
|
||||
<div className="relative">
|
||||
<Placeholder
|
||||
src={image}
|
||||
alt={name}
|
||||
width="100%"
|
||||
height="200px"
|
||||
label="240×200"
|
||||
className="w-full rounded-none border-0 border-b border-dashed"
|
||||
fit="contain"
|
||||
className="aspect-square w-full rounded-none border-0 border-b border-dashed"
|
||||
/>
|
||||
{discount && (
|
||||
<span className="absolute top-3 right-3 rounded-md bg-red px-2 py-0.5 text-xs font-bold text-white">
|
||||
@@ -42,7 +47,7 @@ export function ProductCard({
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<div className="p-4 pb-0">
|
||||
<p className="font-display mb-1 text-[11px] tracking-wide text-muted uppercase">
|
||||
{brand}
|
||||
</p>
|
||||
@@ -51,8 +56,14 @@ export function ProductCard({
|
||||
</h3>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className="text-base font-bold text-red-dark">
|
||||
{formatPrice(price)}
|
||||
<span className="mr-0.5 text-xs font-normal text-muted">تومان</span>
|
||||
{price != null ? (
|
||||
<>
|
||||
{formatPrice(price)}
|
||||
<span className="mr-0.5 text-xs font-normal text-muted">تومان</span>
|
||||
</>
|
||||
) : (
|
||||
<span className="text-sm font-normal text-muted">تماس با فروشگاه</span>
|
||||
)}
|
||||
</span>
|
||||
{oldPrice && (
|
||||
<span className="text-xs text-muted line-through">
|
||||
@@ -60,12 +71,40 @@ export function ProductCard({
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="mt-3 w-full rounded-lg bg-red py-2 text-sm font-medium text-white transition-colors hover:bg-red-dark"
|
||||
>
|
||||
افزودن به سبد
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<article
|
||||
className={`group ${fluid ? "w-full" : "w-[220px] shrink-0 md:w-[240px]"} overflow-hidden rounded-xl border border-border bg-surface transition-shadow hover:shadow-md`}
|
||||
>
|
||||
{href ? <a href={href}>{info}</a> : info}
|
||||
<div className="p-4">
|
||||
{price != null ? (
|
||||
<button
|
||||
type="button"
|
||||
className="w-full rounded-lg bg-red py-2 text-sm font-medium text-white transition-colors hover:bg-red-dark"
|
||||
>
|
||||
افزودن به سبد
|
||||
</button>
|
||||
) : contactPhone ? (
|
||||
<a
|
||||
href={`tel:${contactPhone}`}
|
||||
className="flex w-full items-center justify-center gap-1.5 rounded-lg bg-red py-2 text-sm font-medium text-white transition-colors hover:bg-red-dark"
|
||||
>
|
||||
<span aria-hidden>📞</span>
|
||||
تماس با فروشگاه
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
disabled
|
||||
className="w-full cursor-not-allowed rounded-lg bg-red/60 py-2 text-sm font-medium text-white"
|
||||
>
|
||||
تماس با فروشگاه
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user