Per api.meshkee.com/docs/website/AI_PROMPT.md's hard rules (which an
earlier pass on this branch missed): login, register, OTP, the real
cart, addresses, and payment are the customer dashboard's job
(customer.sanihome.ir), not this storefront's. This site should only
ever run a local guest mini-cart and hand off to the dashboard.
- Remove: AuthContext, LoginModal, lib/auth.ts, lib/cart.ts (the real
/businesses/{id}/cart integration), and the /checkout page entirely.
- Add lib/guestCart.ts: localStorage + shared cookie
(meshkee-guest-cart, Domain=.sanihome.ir) cart, storeItemVariantId
keyed, matching the spec's line shape and ~3500-char cookie-size
cutoff.
- CartContext is now a thin React wrapper over the guest cart (no
server round-trip, so add/update/remove are synchronous); CartPopup's
"Continue" builds the exact customer.sanihome.ir/checkout/cart
(or /login?redirect=...) URL from the spec, base64url-encoding the
cart and detecting an existing dashboard session via the shared
meshkee_customer_access_token cookie.
- ProductCard and ProductPurchasePanel add to the guest cart directly;
no login gate on add-to-cart anymore.
- Comments panel is a plain guest name/email/text form again (the
comments API never required auth — gating it on the now-removed
login system was wrong regardless).
- CONTEXT.md rewritten to document the guest-cart contract explicitly
and flag this exact mistake so it doesn't get reintroduced.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import { Carousel } from "@/components/ui/Carousel";
|
|
import { ProductCard } from "@/components/ui/ProductCard";
|
|
import { getProducts, productHref, type Product } from "@/lib/meshkee";
|
|
|
|
export async function SimilarProducts({
|
|
categoryId,
|
|
excludeProductId,
|
|
contactPhone,
|
|
}: {
|
|
categoryId?: string;
|
|
excludeProductId: string;
|
|
contactPhone?: string;
|
|
}) {
|
|
if (!categoryId) return null;
|
|
|
|
const { items } = await getProducts({ categoryId, pageSize: 9 });
|
|
const products: Product[] = items.filter((p) => p.id !== excludeProductId).slice(0, 8);
|
|
|
|
if (products.length === 0) return null;
|
|
|
|
return (
|
|
<div className="mt-12 border-t border-border pt-10">
|
|
<h2 className="mb-5 flex items-center gap-2 text-lg font-bold">
|
|
<span className="h-2 w-2 shrink-0 rounded-full bg-red" aria-hidden />
|
|
محصولات مشابه
|
|
</h2>
|
|
<Carousel ariaLabel="محصولات مشابه">
|
|
{products.map((product) => (
|
|
<ProductCard
|
|
key={product.id}
|
|
name={product.name}
|
|
brand={product.brand ?? ""}
|
|
price={product.price}
|
|
oldPrice={product.oldPrice}
|
|
discount={product.discount}
|
|
image={product.image ?? "/images/placeholder.svg"}
|
|
href={productHref(product)}
|
|
contactPhone={contactPhone}
|
|
variantId={product.variantId}
|
|
slug={product.slug}
|
|
/>
|
|
))}
|
|
</Carousel>
|
|
</div>
|
|
);
|
|
}
|