Files
dmenu-plus-front/src/app/[name]/(Main)/cart/CartPage.tsx
T
hamid zarghami 75e23237e6
Build and Deploy Docker Images / build_and_deploy (push) Has been cancelled
cart item food
2026-06-06 16:11:17 +03:30

197 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useGetFoods } from "@/app/[name]/(Main)/hooks/useMenuData";
import { useGetProfile } from "@/app/[name]/(Profile)/profile/hooks/userProfileData";
import Button from "@/components/button/PrimaryButton";
import NotificationBellIcon from "@/components/icons/NotificationBellIcon";
import MenuItem from "@/components/listview/MenuItem";
import MenuItemRenderer from "@/components/listview/MenuItemRenderer";
import PagerModal from "@/components/pager/PagerModal";
import Prompt from "@/components/utils/Prompt";
import { ArrowLeft, Trash } from "iconsax-react";
import Image from "next/image";
import { useRouter } from "next/navigation";
import React from "react";
import { useTranslation } from "react-i18next";
import { useGetAbout } from "../about/hooks/useAboutData";
import CartSkeleton from "./components/CartSkeleton";
import CartSummary from "./components/CartSummary";
import { useCart } from "./hook/useCart";
import { useGetCartItems } from "./hooks/useCartData";
import {
cartItemsToFoods,
guestCartItemsToFoods,
hasCartEntries,
} from "./lib/cartUtils";
const CartPage = () => {
const { t } = useTranslation("parallels", { keyPrefix: "Cart" });
const router = useRouter();
const { isSuccess } = useGetProfile();
const { clearCart, items } = useCart();
const { data: cartData, isPending: cartPending } = useGetCartItems(isSuccess);
const { data: foodsResponse } = useGetFoods();
const { data: aboutData } = useGetAbout();
const [showClearConfirm, setShowClearConfirm] = React.useState(false);
const [showPagerModal, setShowPagerModal] = React.useState(false);
const isPremium = aboutData?.data?.plan === "premium";
const cartFoods = React.useMemo(() => {
const foods = foodsResponse?.data ?? [];
if (isSuccess) {
const apiItems = cartData?.data?.items ?? [];
return cartItemsToFoods(apiItems, foods);
}
return guestCartItemsToFoods(items, foods);
}, [isSuccess, cartData?.data?.items, items, foodsResponse?.data]);
const hasItems = React.useMemo(() => {
if (isSuccess) {
return (cartData?.data?.totalItems ?? 0) > 0 || hasCartEntries(items);
}
return hasCartEntries(items);
}, [isSuccess, cartData?.data?.totalItems, items]);
const guestAwaitingMenu =
!isSuccess && hasItems && cartFoods.length === 0 && !foodsResponse?.data;
const showInitialCartLoad = isSuccess && cartPending && !cartData && hasItems;
const isCartEmpty = !hasItems;
const handleClearCart = (e: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
clearCart();
setShowClearConfirm(false);
};
const toggleClearConfirm = (e: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
setShowClearConfirm(false);
};
return (
<div className="overflow-y-auto h-full noscrollbar flex flex-col bg-background">
<div className="grid grid-cols-3 items-center mt-6">
{isCartEmpty ? (
<span></span>
) : (
<Trash
className="cursor-pointer place-self-start"
size="24"
color="currentColor"
onClick={() => setShowClearConfirm(true)}
/>
)}
<h1 className="text-sm2 place-self-center font-medium">
{t("Heading")}
</h1>
<ArrowLeft
className="cursor-pointer place-self-end"
size="24"
color="currentColor"
onClick={() => router.back()}
/>
</div>
<div className="mt-8 flex-1 h-full">
{showInitialCartLoad || guestAwaitingMenu ? (
<CartSkeleton />
) : isCartEmpty ? (
<div className="flex flex-col items-center justify-center gap-4 h-full">
<Image
src="/assets/images/cart.png"
alt="cart"
width={120}
height={120}
className="object-contain"
/>
<div className="flex flex-col items-center gap-2 text-sm2 text-muted-foreground">
<p>
{t("EmptyStateTitle", {
defaultValue: "سبد خرید شما خالی است",
})}
</p>
<p className="text-xs">
{t("EmptyStateDescription", {
defaultValue: "برای افزودن غذا، به منوی رستوران برگردید.",
})}
</p>
</div>
</div>
) : (
<div className="flex flex-col gap-4 pb-24">
{!isPremium && (
<div className="bg-container rounded-container p-4 border border-border shadow-sm">
<div className="flex items-start gap-3 mb-4">
<div className="shrink-0 mt-0.5">
<NotificationBellIcon
width={24}
height={24}
className="currentColor"
/>
</div>
<div className="flex-1">
<p className="text-sm font-medium text-foreground mb-1">
ثبت سفارش
</p>
<p className="text-xs text-muted-foreground leading-5">
برای ثبت سفارش، لطفاً گارسون را صدا کنید
</p>
</div>
</div>
<Button
onClick={() => setShowPagerModal(true)}
className="w-full dark:bg-white! dark:text-black! flex items-center justify-center gap-2"
>
<NotificationBellIcon
width={18}
height={18}
className="text-white dark:text-black!"
/>
<span>صدا کردن گارسون</span>
</Button>
</div>
)}
{cartFoods.map((food) => (
<MenuItemRenderer key={food.id}>
<MenuItem food={food} />
</MenuItemRenderer>
))}
<CartSummary isPremium={isPremium} hasItems={hasItems} />
</div>
)}
</div>
<div
className={
showClearConfirm
? "fixed inset-0 z-1001"
: "pointer-events-none fixed inset-0 z-1001"
}
>
<Prompt
title="پاک کردن سبد خرید"
description="آیا از پاک کردن تمامی آیتم‌های سبد خرید اطمینان دارید؟"
textConfirm="بله"
textCancel="خیر"
onConfirm={handleClearCart}
onCancel={toggleClearConfirm}
visible={showClearConfirm}
onClick={toggleClearConfirm}
/>
</div>
<PagerModal
visible={showPagerModal}
onClose={() => setShowPagerModal(false)}
/>
</div>
);
};
export default CartPage;