From 44fb0be87571dc73bb11829a83a48b6b708ee3df Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sun, 15 Feb 2026 10:39:31 +0330 Subject: [PATCH] show variant in carts --- src/app/[name]/(Dialogs)/cart/hook/useCart.ts | 47 +++++++++++++++---- src/app/[name]/(Dialogs)/cart/page.tsx | 12 ++--- src/app/[name]/(Dialogs)/cart/types/Types.ts | 2 + src/components/CartQuantityControl.tsx | 2 +- src/components/listview/MenuItem.tsx | 28 +++++++++-- src/config/const.ts | 4 +- 6 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/app/[name]/(Dialogs)/cart/hook/useCart.ts b/src/app/[name]/(Dialogs)/cart/hook/useCart.ts index 13ceab1..6b931a4 100644 --- a/src/app/[name]/(Dialogs)/cart/hook/useCart.ts +++ b/src/app/[name]/(Dialogs)/cart/hook/useCart.ts @@ -8,20 +8,39 @@ import { useGetCartItems, useIncrementCart, } from "../hooks/useCartData"; +import { toast } from "@/components/Toast"; +import { extractErrorMessage } from "@/lib/func"; export const useCart = () => { const { isSuccess } = useGetProfile(); const params = useParams(); const currentSlug = (params.name as string) || null; - const { clear, increment, decrement, items, slug, setSlug } = useReceiptStore(); - const { mutate: mutateIncrementCart, isPending: isIncrementPending } = useIncrementCart(); - const { mutate: mutateDecrementCart, isPending: isDecrementPending } = useDecrementCart(); + const { + clear, + increment, + decrement, + items, + slug, + setSlug, + } = useReceiptStore(); + const { + mutate: mutateIncrementCart, + isPending: isIncrementPending, + } = useIncrementCart(); + const { + mutate: mutateDecrementCart, + isPending: isDecrementPending, + } = useDecrementCart(); const { mutate: mutateClearCart } = useClearCart(); const { data: cartItems } = useGetCartItems(isSuccess); const addToCart = (id: string | number) => { if (isSuccess) { - mutateIncrementCart(id); + mutateIncrementCart(id, { + onError: (error) => { + toast(extractErrorMessage(error), "error"); + }, + }); } else { // تنظیم slug هنگام افزودن آیتم به سبد (فقط برای کاربران لاگین نشده) if (currentSlug && slug !== currentSlug) { @@ -33,7 +52,11 @@ export const useCart = () => { const removeFromCart = (id: string | number) => { if (isSuccess) { - mutateDecrementCart(id); + mutateDecrementCart(id, { + onError: (error) => { + toast(extractErrorMessage(error), "error"); + }, + }); } else { decrement(id); } @@ -41,7 +64,11 @@ export const useCart = () => { const clearCart = useCallback(() => { if (isSuccess) { - mutateClearCart(); + mutateClearCart(undefined, { + onError: (error) => { + toast(extractErrorMessage(error), "error"); + }, + }); } else { clear(); } @@ -53,9 +80,13 @@ export const useCart = () => { return {}; } return cartItems.data.items.reduce((acc, item) => { - acc[item.variantId] = { quantity: item.quantity }; + acc[item.variantId] = { + quantity: item.quantity, + ...(item.variantValue != null && { variantValue: item.variantValue }), + ...(item.image != null && { image: item.image }), + }; return acc; - }, {} as Record); + }, {} as Record); } else { return items; } diff --git a/src/app/[name]/(Dialogs)/cart/page.tsx b/src/app/[name]/(Dialogs)/cart/page.tsx index da6e23e..205f605 100644 --- a/src/app/[name]/(Dialogs)/cart/page.tsx +++ b/src/app/[name]/(Dialogs)/cart/page.tsx @@ -11,7 +11,6 @@ import Prompt from '@/components/utils/Prompt'; import { useGetProducts } from '@/app/[name]/(Main)/hooks/useMenuData'; import MenuItem from '@/components/listview/MenuItem'; import MenuItemRenderer from '@/components/listview/MenuItemRenderer'; -import type { Product } from '@/app/[name]/(Main)/types/Types'; const CartIndex = () => { const { t } = useTranslation('parallels', { keyPrefix: 'Cart' }); @@ -26,13 +25,14 @@ const CartIndex = () => { if (!products.length) return []; return Object.entries(items) .filter(([, detail]) => detail?.quantity && detail.quantity > 0) - .map(([variantId]) => { + .map(([variantId, detail]) => { const product = products.find((p) => p.variants?.some((v) => v.id === variantId) ); - return product ? { product, variantId } : null; + const variantValue = (detail as { variantValue?: string } | undefined)?.variantValue; + return product ? { product, variantId, variantValue } : null; }) - .filter((x): x is { product: Product; variantId: string } => Boolean(x)); + .filter((x): x is NonNullable => x != null); }, [products, items]); const isCartEmpty = cartProducts.length === 0; @@ -98,9 +98,9 @@ const CartIndex = () => { ) : (
- {cartProducts.map(({ product, variantId }) => ( + {cartProducts.map(({ product, variantId, variantValue }) => ( - + ))} diff --git a/src/app/[name]/(Dialogs)/cart/types/Types.ts b/src/app/[name]/(Dialogs)/cart/types/Types.ts index d2256be..74974b3 100644 --- a/src/app/[name]/(Dialogs)/cart/types/Types.ts +++ b/src/app/[name]/(Dialogs)/cart/types/Types.ts @@ -10,6 +10,8 @@ export type BulkCartItem = { export interface CartItem { variantId: string; productTitle: string; + variantValue?: string; + image?: string; quantity: number; price: number; discount: number; diff --git a/src/components/CartQuantityControl.tsx b/src/components/CartQuantityControl.tsx index 2049290..25feff4 100644 --- a/src/components/CartQuantityControl.tsx +++ b/src/components/CartQuantityControl.tsx @@ -31,7 +31,7 @@ export function CartQuantityControl({ isMutating = false, addDisabled = false, addLabel = 'افزودن', - addingLabel = 'در حال افزودن...', + addingLabel = '', fullWidth = false, }: CartQuantityControlProps) { return ( diff --git a/src/components/listview/MenuItem.tsx b/src/components/listview/MenuItem.tsx index feafd81..d4fb1a1 100644 --- a/src/components/listview/MenuItem.tsx +++ b/src/components/listview/MenuItem.tsx @@ -19,11 +19,13 @@ interface MenuItemProps { product: Product; /** در صفحه سبد هر خط با variantId مشخص می‌شود */ variantId?: string | null; + /** مقدار تنوع (مثلاً «قرمز»، «تنوع سوم») — برای نمایش در سبد خرید */ + variantValue?: string | null; /** حالت نمایش: list = یک ستونه (پیش‌فرض)، grid = دو ستونه */ viewMode?: MenuItemViewMode; } -const MenuItem = ({ product, variantId: variantIdProp, viewMode = 'list' }: MenuItemProps) => { +const MenuItem = ({ product, variantId: variantIdProp, variantValue: variantValueProp, viewMode = 'list' }: MenuItemProps) => { const { items, addToCart, removeFromCart, isCartMutating } = useCart(); const params = useParams<{ name: string }>(); const name = params?.name || ""; @@ -61,6 +63,10 @@ const MenuItem = ({ product, variantId: variantIdProp, viewMode = 'list' }: Menu [product.name, product.title] ); + /** فقط در سبد خرید تنوع نمایش داده شود */ + const isInCart = variantIdProp != null; + const variantValueDisplay = isInCart ? (variantValueProp ?? selectedVariant?.value ?? null) : null; + const productContent = useMemo(() => { const content = product.content; if (!content) return ''; @@ -126,10 +132,15 @@ const MenuItem = ({ product, variantId: variantIdProp, viewMode = 'list' }: Menu alt={productName} /> - -
+ +
{productName}
+ {variantValueDisplay && ( + + {variantValueDisplay} + + )}
@@ -184,8 +195,15 @@ const MenuItem = ({ product, variantId: variantIdProp, viewMode = 'list' }: Menu
-
- {productName} +
+
+ {productName} +
+ {variantValueDisplay && ( + + {variantValueDisplay} + + )}
{(productContent || productDescription) && (
diff --git a/src/config/const.ts b/src/config/const.ts index d724ca3..d598884 100644 --- a/src/config/const.ts +++ b/src/config/const.ts @@ -1,5 +1,5 @@ // export const API_BASE_URL = "https://dmenuplus-api.dev.danakcorp.com"; -export const API_BASE_URL = "https://dkala-api.danakcorp.com"; -// export const API_BASE_URL = "http://10.191.241.88:4000"; +// export const API_BASE_URL = "https://dkala-api.danakcorp.com"; +export const API_BASE_URL = "http://10.191.241.88:4000"; export const TOKEN_NAME = "dkala-t"; export const REFRESH_TOKEN_NAME = "dkala-rt";