cart checker for remove cart when slug changed
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 <PreferenceWrapper>{children}</PreferenceWrapper>
|
||||
return <>
|
||||
<PreferenceWrapper>{children}</PreferenceWrapper>
|
||||
<CartChecker />
|
||||
</>
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message === 'RESTAURANT_NOT_FOUND') {
|
||||
notFound()
|
||||
|
||||
@@ -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
|
||||
@@ -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]);
|
||||
|
||||
// اعمال تم تاریک/روشن
|
||||
|
||||
@@ -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<ReceiptStore>()(
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user