Initial commit: Hoomat storefront with Meshkee API and static-image slots.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-04 15:00:41 +03:30
co-authored by Cursor
commit cfabf3e327
95 changed files with 12651 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
"use client";
import Image from "next/image";
import { useCart } from "@/app/providers/cart-provider";
import { useAuth } from "@/app/providers/auth-provider";
import { formatPrice } from "@/lib/meshkee/format";
import { customerContinueCheckoutUrl } from "@/lib/meshkee/urls";
export function CartDrawer() {
const { cart, open, setOpen, updateQuantity, removeItem, guestItems, loading } =
useCart();
const { isAuthenticated } = useAuth();
if (!open) return null;
const continueUrl = customerContinueCheckoutUrl(
isAuthenticated,
isAuthenticated ? [] : guestItems,
);
return (
<div className="cart-drawer-root">
<button
type="button"
className="cart-drawer-backdrop"
aria-label="بستن سبد خرید"
onClick={() => setOpen(false)}
/>
<aside className="cart-drawer" role="dialog" aria-modal="true" aria-label="سبد خرید">
<div className="cart-drawer-head">
<div>
<h2>سبد خرید</h2>
<p>
{cart.items.length
? `${new Intl.NumberFormat("fa-IR").format(
cart.items.reduce((sum, line) => sum + line.quantity, 0),
)} کالا`
: "سبد خرید خالی است"}
</p>
</div>
<button type="button" className="icon-btn" onClick={() => setOpen(false)}>
✕
</button>
</div>
<div className="cart-drawer-body">
{cart.items.length === 0 ? (
<p className="empty-note">هنوز محصولی به سبد اضافه نشده است.</p>
) : (
cart.items.map((item) => (
<article key={item.id} className="cart-line">
<div className="cart-line-media">
{item.image ? (
<Image src={item.image} alt={item.name} width={72} height={72} />
) : (
<div className="cart-line-fallback" />
)}
</div>
<div className="cart-line-info">
<h3>{item.name}</h3>
{item.optionLabel ? <p>{item.optionLabel}</p> : null}
<strong className="ltr-number" dir="ltr" lang="en">
{formatPrice(item.price)}
</strong>
<div className="cart-line-actions">
<button
type="button"
onClick={() => void updateQuantity(item.id, item.quantity - 1)}
disabled={loading}
>
−
</button>
<span className="ltr-number" dir="ltr" lang="en">
{item.quantity}
</span>
<button
type="button"
onClick={() => void updateQuantity(item.id, item.quantity + 1)}
disabled={loading}
>
+
</button>
<button
type="button"
className="text-btn"
onClick={() => void removeItem(item.id)}
disabled={loading}
>
حذف
</button>
</div>
</div>
</article>
))
)}
</div>
<div className="cart-drawer-foot">
<div className="cart-total">
<span>جمع</span>
<strong className="ltr-number" dir="ltr" lang="en">
{formatPrice(cart.total)}
</strong>
</div>
<a className="primary-btn cart-continue" href={continueUrl}>
ادامه
</a>
</div>
</aside>
</div>
);
}