From 98b834b982ddfad36552bb43898639ebab9b7cc7 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 29 Dec 2025 09:04:58 +0330 Subject: [PATCH] cart checker for remove cart when slug changed --- src/app/[name]/(Dialogs)/cart/hook/useCart.ts | 27 ++++++++++++++--- src/app/[name]/layout.tsx | 6 +++- src/components/CartChecker.tsx | 30 +++++++++++++++++++ src/components/wrapper/PreferenceWrapper.tsx | 3 +- src/zustand/receiptStore.ts | 6 +++- 5 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 src/components/CartChecker.tsx diff --git a/src/app/[name]/(Dialogs)/cart/hook/useCart.ts b/src/app/[name]/(Dialogs)/cart/hook/useCart.ts index 5a66c78..537cb86 100644 --- a/src/app/[name]/(Dialogs)/cart/hook/useCart.ts +++ b/src/app/[name]/(Dialogs)/cart/hook/useCart.ts @@ -1,4 +1,5 @@ -import { useMemo } from "react"; +import { useCallback, useMemo } from "react"; +import { useParams } from "next/navigation"; import { useGetProfile } from "@/app/[name]/(Profile)/profile/hooks/userProfileData"; import { useReceiptStore } from "@/zustand/receiptStore"; import { @@ -10,7 +11,9 @@ import { export const useCart = () => { const { isSuccess } = useGetProfile(); - const { clear, increment, decrement, items } = useReceiptStore(); + const params = useParams(); + const currentSlug = (params.name as string) || null; + const { clear, increment, decrement, items, slug, setSlug } = useReceiptStore(); const { mutate: mutateIncrementCart } = useIncrementCart(); const { mutate: mutateDecrementCart } = useDecrementCart(); const { mutate: mutateClearCart } = useClearCart(); @@ -20,6 +23,10 @@ export const useCart = () => { if (isSuccess) { mutateIncrementCart(id); } else { + // تنظیم slug هنگام افزودن آیتم به سبد (فقط برای کاربران لاگین نشده) + if (currentSlug && slug !== currentSlug) { + setSlug(currentSlug); + } increment(id); } }; @@ -32,13 +39,13 @@ export const useCart = () => { } }; - const clearCart = () => { + const clearCart = useCallback(() => { if (isSuccess) { mutateClearCart(); } else { clear(); } - }; + }, [isSuccess, mutateClearCart, clear]); const cartItemsMap = useMemo(() => { if (isSuccess) { @@ -58,8 +65,20 @@ export const useCart = () => { return false; }; + // برای کاربران لاگین شده، slug از API می‌آید (در cartItems.data.restaurantId) + // برای کاربران لاگین نشده، slug از receiptStore می‌آید + const cartSlug = useMemo(() => { + if (isSuccess && cartItems?.data?.restaurantId) { + // اگر از API آمده، می‌توانیم restaurantId را برگردانیم + // اما بهتر است slug را از URL بگیریم چون API ممکن است restaurantId را برگرداند نه slug + return currentSlug; + } + return slug; + }, [isSuccess, cartItems?.data?.restaurantId, currentSlug, slug]); + return { items: cartItemsMap, + slug: cartSlug, increment, decrement, clear, diff --git a/src/app/[name]/layout.tsx b/src/app/[name]/layout.tsx index 9af68f6..313b2f4 100644 --- a/src/app/[name]/layout.tsx +++ b/src/app/[name]/layout.tsx @@ -3,6 +3,7 @@ import React from 'react' import type { Metadata, Viewport } from 'next' import { getRestaurant } from './lib/getRestaurant' import { notFound } from 'next/navigation' +import CartChecker from '@/components/CartChecker' export const dynamic = 'force-dynamic' export const revalidate = 0 @@ -85,7 +86,10 @@ export default async function Layout({ try { const { name } = await params await getRestaurant(name) - return {children} + return <> + {children} + + } catch (error) { if (error instanceof Error && error.message === 'RESTAURANT_NOT_FOUND') { notFound() diff --git a/src/components/CartChecker.tsx b/src/components/CartChecker.tsx new file mode 100644 index 0000000..514229a --- /dev/null +++ b/src/components/CartChecker.tsx @@ -0,0 +1,30 @@ +"use client" + +import { useCart } from '@/app/[name]/(Dialogs)/cart/hook/useCart' +import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData' +import { useParams } from 'next/navigation' +import { useEffect, useRef, type FC } from 'react' + +const CartChecker: FC = () => { + + const { isSuccess } = useGetProfile() + const params = useParams() + const currentSlug = params.name as string + const { slug: cartSlug, clearCart } = useCart() + const hasClearedRef = useRef(false) + + useEffect(() => { + if (!isSuccess && currentSlug && cartSlug && currentSlug !== cartSlug) { + if (!hasClearedRef.current) { + hasClearedRef.current = true + clearCart() + } + } else if (currentSlug === cartSlug) { + hasClearedRef.current = false + } + }, [isSuccess, currentSlug, cartSlug, clearCart]) + + return null +} + +export default CartChecker \ No newline at end of file diff --git a/src/components/wrapper/PreferenceWrapper.tsx b/src/components/wrapper/PreferenceWrapper.tsx index cd0a544..f87a27e 100644 --- a/src/components/wrapper/PreferenceWrapper.tsx +++ b/src/components/wrapper/PreferenceWrapper.tsx @@ -43,7 +43,7 @@ function applyPrimaryColor(colorHex: string) { function PreferenceWrapper({ children }: Props) { const { state: nightMode } = usePreference('night-mode', false); - const { data: aboutData, isSuccess } = useGetAbout(); + const { data: aboutData } = useGetAbout(); // بررسی اینکه آیا باید اسپلش نمایش داده بشه const [showSplash, setShowSplash] = useState(() => { @@ -90,6 +90,7 @@ function PreferenceWrapper({ children }: Props) { applyPrimaryColor(aboutData.data.menuColor); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [aboutData?.data?.menuColor]); // اعمال تم تاریک/روشن diff --git a/src/zustand/receiptStore.ts b/src/zustand/receiptStore.ts index 590b042..0df7fd6 100644 --- a/src/zustand/receiptStore.ts +++ b/src/zustand/receiptStore.ts @@ -10,6 +10,8 @@ type ReceiptItemMap = { type ReceiptStore = { items: ReceiptItemMap; + slug: string | null; + setSlug: (slug: string) => void; increment: (id: string | number) => void; decrement: (id: string | number) => void; clear: () => void; @@ -19,7 +21,9 @@ export const useReceiptStore = create()( persist( (set) => ({ items: {}, - clear: () => set({ items: {} }), + slug: null, + setSlug: (slug) => set({ slug }), + clear: () => set({ items: {}, slug: null }), increment: (id) => set((state) => { const current = state.items[id]?.quantity || 0;