Initial commit: Hoomat storefront with Meshkee API and static-image slots.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user