payble fix with discount
This commit is contained in:
@@ -9,6 +9,7 @@ import type { Food } from '@/app/[name]/(Main)/types/Types';
|
||||
import { useCart } from '../hook/useCart';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useGetCartItems } from '../hooks/useCartData';
|
||||
|
||||
interface CartSummaryProps {
|
||||
description?: string;
|
||||
@@ -24,6 +25,7 @@ const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps
|
||||
const { data: foodsResponse } = useGetFoods();
|
||||
const foods = React.useMemo(() => foodsResponse?.data ?? [], [foodsResponse?.data]);
|
||||
const { items } = useCart();
|
||||
const { data: cartData } = useGetCartItems(isSuccess);
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
|
||||
const cartFoods = React.useMemo(() => {
|
||||
@@ -37,11 +39,20 @@ const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps
|
||||
}, [foods, items]);
|
||||
|
||||
const totalPrice = React.useMemo(() => {
|
||||
// اگر داده از API آمده و total وجود دارد، از آن استفاده میکنیم
|
||||
if (isSuccess && cartData?.data?.total !== undefined) {
|
||||
return cartData.data.total;
|
||||
}
|
||||
|
||||
// در غیر این صورت، محاسبه محلی با در نظر گرفتن تخفیف
|
||||
return cartFoods.reduce((sum, food) => {
|
||||
const qty = items[String(food.id)]?.quantity ?? 0;
|
||||
return sum + (food.price ?? 0) * qty;
|
||||
const basePrice = food.price ?? 0;
|
||||
const discount = food.discount ?? 0;
|
||||
const priceAfterDiscount = basePrice * (1 - discount / 100);
|
||||
return sum + priceAfterDiscount * qty;
|
||||
}, 0);
|
||||
}, [cartFoods, items]);
|
||||
}, [cartFoods, items, isSuccess, cartData?.data?.total]);
|
||||
|
||||
const isCartEmpty = cartFoods.length === 0;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export interface Category {
|
||||
deletedAt: string | null;
|
||||
title: string;
|
||||
isActive: boolean;
|
||||
restId: string;
|
||||
restaurant: string;
|
||||
avatarUrl: string | null;
|
||||
}
|
||||
|
||||
@@ -22,23 +22,33 @@ export type FoodImage = string | { url: string; alt?: string | null };
|
||||
|
||||
export interface Food {
|
||||
id: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
deletedAt?: string | null;
|
||||
restaurant?: string;
|
||||
category?: Category;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
deletedAt: string | null;
|
||||
restaurant: string;
|
||||
category: Category;
|
||||
inventory: string;
|
||||
title: string;
|
||||
desc: string;
|
||||
content: string[];
|
||||
price: number;
|
||||
order: number | null;
|
||||
prepareTime: number | null;
|
||||
weekDays: number[];
|
||||
mealTypes: unknown[];
|
||||
isActive: boolean;
|
||||
images: string[];
|
||||
inPlaceServe: boolean;
|
||||
pickupServe: boolean;
|
||||
score: number;
|
||||
discount: number;
|
||||
isSpecialOffer: boolean;
|
||||
// فیلدهای قدیمی برای سازگاری با سایر بخشهای کد
|
||||
name?: string;
|
||||
title?: string;
|
||||
foodName?: string;
|
||||
description?: string;
|
||||
desc?: string | null;
|
||||
content?: string[] | string | null;
|
||||
price: number;
|
||||
image?: string | null;
|
||||
images?: FoodImage[] | null;
|
||||
points?: number | null;
|
||||
order?: number | null;
|
||||
prepareTime?: number | null;
|
||||
sat?: boolean;
|
||||
sun?: boolean;
|
||||
mon?: boolean;
|
||||
@@ -47,12 +57,7 @@ export interface Food {
|
||||
dinner?: boolean;
|
||||
stock?: number;
|
||||
stockDefault?: number;
|
||||
isActive?: boolean;
|
||||
inPlaceServe?: boolean;
|
||||
pickupServe?: boolean;
|
||||
rate?: number;
|
||||
discount?: number;
|
||||
isSpecialOffer?: boolean;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,11 +64,30 @@ const MenuItem = ({ food }: MenuItemProps) => {
|
||||
return desc.replace(/,/g, '،');
|
||||
}, [food.description, food.desc]);
|
||||
|
||||
const finalPrice = useMemo(() => {
|
||||
const basePrice = food.price || 0;
|
||||
const discount = food.discount || 0;
|
||||
if (discount > 0) {
|
||||
return Math.max(0, basePrice - discount);
|
||||
}
|
||||
return basePrice;
|
||||
}, [food.price, food.discount]);
|
||||
|
||||
const formattedPrice = useMemo(
|
||||
() => (finalPrice ? finalPrice.toLocaleString('fa-IR') : '0'),
|
||||
[finalPrice]
|
||||
);
|
||||
|
||||
const formattedOriginalPrice = useMemo(
|
||||
() => (food.price ? food.price.toLocaleString('fa-IR') : '0'),
|
||||
[food.price]
|
||||
);
|
||||
|
||||
const hasDiscount = useMemo(
|
||||
() => (food.discount || 0) > 0,
|
||||
[food.discount]
|
||||
);
|
||||
|
||||
const handleAddToCart = () => {
|
||||
addToCart(food.id);
|
||||
};
|
||||
@@ -104,9 +123,22 @@ const MenuItem = ({ food }: MenuItemProps) => {
|
||||
</div>
|
||||
</Link>
|
||||
<div className="inline-flex mt-2 gap-2 justify-between w-full items-center">
|
||||
<span className="w-full text-sm mt-1" dir="ltr">
|
||||
{formattedPrice} T
|
||||
</span>
|
||||
<div className="w-full flex flex-col gap-1" dir="ltr">
|
||||
{hasDiscount ? (
|
||||
<>
|
||||
<span className="text-xs text-disabled-text line-through">
|
||||
{formattedOriginalPrice} T
|
||||
</span>
|
||||
<span className="text-sm font-medium text-primary dark:text-foreground">
|
||||
{formattedPrice} T
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<span className="text-sm mt-1">
|
||||
{formattedPrice} T
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<motion.div
|
||||
whileTap={{ scale: 1.05 }}
|
||||
className="bg-background active:drop-shadow-xs max-w-[115px] rounded-md w-full h-8 inline-flex p-1 justify-between items-center gap-2 relative overflow-hidden"
|
||||
|
||||
Reference in New Issue
Block a user