diff --git a/src/app/[name]/(Dialogs)/cart/hooks/useCartData.ts b/src/app/[name]/(Dialogs)/cart/hooks/useCartData.ts index b60cd2b..20c4d7c 100644 --- a/src/app/[name]/(Dialogs)/cart/hooks/useCartData.ts +++ b/src/app/[name]/(Dialogs)/cart/hooks/useCartData.ts @@ -1,13 +1,14 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import * as api from "../service/CartService"; import type { CartResponse, CartItem } from "../types/Types"; +import type { FoodsResponse } from "@/app/[name]/(Main)/types/Types"; export const useBulkCart = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: api.bulkCart, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["cart-items"] }); + queryClient.refetchQueries({ queryKey: ["cart-items"] }); }, }); }; @@ -18,56 +19,74 @@ export const useIncrementCart = () => { mutationFn: api.increment, onMutate: async (id: string | number) => { await queryClient.cancelQueries({ queryKey: ["cart-items"] }); + await queryClient.cancelQueries({ queryKey: ["menu"] }); const previousCart = queryClient.getQueryData([ "cart-items", ]); + const foodsData = queryClient.getQueryData(["menu"]); - if (previousCart?.data) { + if (previousCart?.data && foodsData?.data) { const existingItem = previousCart.data.items.find( (item) => item.foodId === String(id) ); + let updatedItems: CartItem[]; + let newTotalItems: number; + if (existingItem) { - // به‌روزرسانی خوش‌بینانه برای آیتم موجود - const updatedItems = previousCart.data.items.map((item) => { + updatedItems = previousCart.data.items.map((item) => { if (item.foodId === String(id)) { return { ...item, quantity: item.quantity + 1, + totalPrice: item.price * (item.quantity + 1) * (1 - item.discount / 100), }; } return item; }); - - queryClient.setQueryData(["cart-items"], { - ...previousCart, - data: { - ...previousCart.data, - items: updatedItems, - totalItems: previousCart.data.totalItems + 1, - }, - }); + newTotalItems = previousCart.data.totalItems + 1; } else { - // افزودن خوش‌بینانه برای آیتم جدید - const newItem: CartItem = { - foodId: String(id), - foodTitle: "", // این بعداً از سرور پر می‌شود - quantity: 1, - price: 0, - discount: 0, - totalPrice: 0, - }; - - queryClient.setQueryData(["cart-items"], { - ...previousCart, - data: { - ...previousCart.data, - items: [...previousCart.data.items, newItem], - totalItems: previousCart.data.totalItems + 1, - }, - }); + const food = foodsData.data.find((f) => String(f.id) === String(id)); + if (food) { + const newItem: CartItem = { + foodId: String(id), + foodTitle: food.title || food.name || "", + quantity: 1, + price: food.price, + discount: food.discount || 0, + totalPrice: food.price * (1 - (food.discount || 0) / 100), + }; + updatedItems = [...previousCart.data.items, newItem]; + newTotalItems = previousCart.data.totalItems + 1; + } else { + return { previousCart }; + } } + + // محاسبه subTotal جدید + const newSubTotal = updatedItems.reduce( + (sum, item) => sum + item.totalPrice, + 0 + ); + + // محاسبه total جدید (با حفظ deliveryFee، tax و discount) + const newTotal = + newSubTotal + + (previousCart.data.deliveryFee || 0) - + (previousCart.data.totalDiscount || 0) + + (previousCart.data.tax || 0); + + queryClient.setQueryData(["cart-items"], { + ...previousCart, + data: { + ...previousCart.data, + items: updatedItems, + totalItems: newTotalItems, + subTotal: newSubTotal, + total: newTotal, + }, + }); } return { previousCart }; @@ -77,6 +96,9 @@ export const useIncrementCart = () => { queryClient.setQueryData(["cart-items"], context.previousCart); } }, + onSuccess: () => { + queryClient.refetchQueries({ queryKey: ["cart-items"] }); + }, }); }; @@ -102,18 +124,34 @@ export const useDecrementCart = () => { return { ...item, quantity: newQuantity, + totalPrice: item.price * newQuantity * (1 - item.discount / 100), }; } return item; }) .filter((item: CartItem | null): item is CartItem => item !== null); + // محاسبه subTotal جدید + const newSubTotal = updatedItems.reduce( + (sum, item) => sum + item.totalPrice, + 0 + ); + + // محاسبه total جدید + const newTotal = + newSubTotal + + (previousCart.data.deliveryFee || 0) - + (previousCart.data.totalDiscount || 0) + + (previousCart.data.tax || 0); + queryClient.setQueryData(["cart-items"], { ...previousCart, data: { ...previousCart.data, items: updatedItems, totalItems: Math.max(0, previousCart.data.totalItems - 1), + subTotal: newSubTotal, + total: newTotal, }, }); } @@ -125,6 +163,9 @@ export const useDecrementCart = () => { queryClient.setQueryData(["cart-items"], context.previousCart); } }, + onSuccess: () => { + queryClient.refetchQueries({ queryKey: ["cart-items"] }); + }, }); }; @@ -132,32 +173,8 @@ export const useClearCart = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: api.clear, - onMutate: async () => { - await queryClient.cancelQueries({ queryKey: ["cart-items"] }); - - const previousCart = queryClient.getQueryData([ - "cart-items", - ]); - - if (previousCart?.data) { - queryClient.setQueryData(["cart-items"], { - ...previousCart, - data: { - ...previousCart.data, - items: [], - totalItems: 0, - subTotal: 0, - total: 0, - }, - }); - } - - return { previousCart }; - }, - onError: (_err, _variables, context) => { - if (context?.previousCart) { - queryClient.setQueryData(["cart-items"], context.previousCart); - } + onSuccess: () => { + queryClient.refetchQueries({ queryKey: ["cart-items"] }); }, }); }; diff --git a/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx b/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx index 2574e1d..697d0c8 100644 --- a/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx +++ b/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx @@ -29,28 +29,28 @@ const getDeliveryMethodTitle = (method: string) => { } }; -const getStatusPercentage = (status: string) => { - switch (status) { - case 'new': - case 'pendingPayment': - return 0; - case 'paid': - case 'confirmed': - return 20; - case 'preparing': - return 40; - case 'ready': - return 60; - case 'shipped': - case 'delivering': - return 80; - case 'completed': - case 'delivered': - return 100; - default: - return 0; - } -}; +// const getStatusPercentage = (status: string) => { +// switch (status) { +// case 'new': +// case 'pendingPayment': +// return 0; +// case 'paid': +// case 'confirmed': +// return 20; +// case 'preparing': +// return 40; +// case 'ready': +// return 60; +// case 'shipped': +// case 'delivering': +// return 80; +// case 'completed': +// case 'delivered': +// return 100; +// default: +// return 0; +// } +// }; const getStatusText = (status: string): string => { const statusKey = status as keyof typeof ordersTranslations.status; diff --git a/src/app/[name]/(Profile)/profile/address/new/page.tsx b/src/app/[name]/(Profile)/profile/address/new/page.tsx index 6adf28a..2d57de5 100644 --- a/src/app/[name]/(Profile)/profile/address/new/page.tsx +++ b/src/app/[name]/(Profile)/profile/address/new/page.tsx @@ -1,8 +1,9 @@ 'use client'; -import { useSearchParams } from 'next/navigation'; +import { useSearchParams, useRouter } from 'next/navigation'; import React, { useState, useEffect } from 'react'; import dynamic from 'next/dynamic'; +import { ArrowLeft } from 'iconsax-react'; import useToggle from '@/hooks/helpers/useToggle'; import { useAuthStore } from '@/zustand/authStore'; import { MarkerData, NominatimReverseGeocodingResponse } from '../types/Types'; @@ -20,6 +21,7 @@ const CustomMap = dynamic( function OrderTrackingPage() { + const router = useRouter(); const params = useSearchParams(); const id = params.get('id'); const editMode = !!id; @@ -186,8 +188,17 @@ function OrderTrackingPage() { /> +
+ +
+ {hasServiceArea && ( -
+

محدوده سرویس‌دهی روی نقشه با رنگ آبی مشخص شده است