Files
sanihome/src/components/product/SimilarProducts.tsx
T
amirhosein.ashourlooandClaude Sonnet 5 5152b16d61 Revert to guest-cart architecture, drop in-site auth/checkout
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>
2026-09-06 15:01:22 +03:30

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>
);
}