cart checker for remove cart when slug changed

This commit is contained in:
hamid zarghami
2025-12-29 09:04:58 +03:30
parent d6c2f2630d
commit 98b834b982
5 changed files with 65 additions and 7 deletions
+23 -4
View File
@@ -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 { useGetProfile } from "@/app/[name]/(Profile)/profile/hooks/userProfileData";
import { useReceiptStore } from "@/zustand/receiptStore"; import { useReceiptStore } from "@/zustand/receiptStore";
import { import {
@@ -10,7 +11,9 @@ import {
export const useCart = () => { export const useCart = () => {
const { isSuccess } = useGetProfile(); 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: mutateIncrementCart } = useIncrementCart();
const { mutate: mutateDecrementCart } = useDecrementCart(); const { mutate: mutateDecrementCart } = useDecrementCart();
const { mutate: mutateClearCart } = useClearCart(); const { mutate: mutateClearCart } = useClearCart();
@@ -20,6 +23,10 @@ export const useCart = () => {
if (isSuccess) { if (isSuccess) {
mutateIncrementCart(id); mutateIncrementCart(id);
} else { } else {
// تنظیم slug هنگام افزودن آیتم به سبد (فقط برای کاربران لاگین نشده)
if (currentSlug && slug !== currentSlug) {
setSlug(currentSlug);
}
increment(id); increment(id);
} }
}; };
@@ -32,13 +39,13 @@ export const useCart = () => {
} }
}; };
const clearCart = () => { const clearCart = useCallback(() => {
if (isSuccess) { if (isSuccess) {
mutateClearCart(); mutateClearCart();
} else { } else {
clear(); clear();
} }
}; }, [isSuccess, mutateClearCart, clear]);
const cartItemsMap = useMemo(() => { const cartItemsMap = useMemo(() => {
if (isSuccess) { if (isSuccess) {
@@ -58,8 +65,20 @@ export const useCart = () => {
return false; 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 { return {
items: cartItemsMap, items: cartItemsMap,
slug: cartSlug,
increment, increment,
decrement, decrement,
clear, clear,
+5 -1
View File
@@ -3,6 +3,7 @@ import React from 'react'
import type { Metadata, Viewport } from 'next' import type { Metadata, Viewport } from 'next'
import { getRestaurant } from './lib/getRestaurant' import { getRestaurant } from './lib/getRestaurant'
import { notFound } from 'next/navigation' import { notFound } from 'next/navigation'
import CartChecker from '@/components/CartChecker'
export const dynamic = 'force-dynamic' export const dynamic = 'force-dynamic'
export const revalidate = 0 export const revalidate = 0
@@ -85,7 +86,10 @@ export default async function Layout({
try { try {
const { name } = await params const { name } = await params
await getRestaurant(name) await getRestaurant(name)
return <PreferenceWrapper>{children}</PreferenceWrapper> return <>
<PreferenceWrapper>{children}</PreferenceWrapper>
<CartChecker />
</>
} catch (error) { } catch (error) {
if (error instanceof Error && error.message === 'RESTAURANT_NOT_FOUND') { if (error instanceof Error && error.message === 'RESTAURANT_NOT_FOUND') {
notFound() notFound()
+30
View File
@@ -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
+2 -1
View File
@@ -43,7 +43,7 @@ function applyPrimaryColor(colorHex: string) {
function PreferenceWrapper({ children }: Props) { function PreferenceWrapper({ children }: Props) {
const { state: nightMode } = usePreference('night-mode', false); const { state: nightMode } = usePreference('night-mode', false);
const { data: aboutData, isSuccess } = useGetAbout(); const { data: aboutData } = useGetAbout();
// بررسی اینکه آیا باید اسپلش نمایش داده بشه // بررسی اینکه آیا باید اسپلش نمایش داده بشه
const [showSplash, setShowSplash] = useState(() => { const [showSplash, setShowSplash] = useState(() => {
@@ -90,6 +90,7 @@ function PreferenceWrapper({ children }: Props) {
applyPrimaryColor(aboutData.data.menuColor); applyPrimaryColor(aboutData.data.menuColor);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [aboutData?.data?.menuColor]); }, [aboutData?.data?.menuColor]);
// اعمال تم تاریک/روشن // اعمال تم تاریک/روشن
+5 -1
View File
@@ -10,6 +10,8 @@ type ReceiptItemMap = {
type ReceiptStore = { type ReceiptStore = {
items: ReceiptItemMap; items: ReceiptItemMap;
slug: string | null;
setSlug: (slug: string) => void;
increment: (id: string | number) => void; increment: (id: string | number) => void;
decrement: (id: string | number) => void; decrement: (id: string | number) => void;
clear: () => void; clear: () => void;
@@ -19,7 +21,9 @@ export const useReceiptStore = create<ReceiptStore>()(
persist( persist(
(set) => ({ (set) => ({
items: {}, items: {},
clear: () => set({ items: {} }), slug: null,
setSlug: (slug) => set({ slug }),
clear: () => set({ items: {}, slug: null }),
increment: (id) => increment: (id) =>
set((state) => { set((state) => {
const current = state.items[id]?.quantity || 0; const current = state.items[id]?.quantity || 0;