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 { 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,
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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) {
|
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]);
|
||||||
|
|
||||||
// اعمال تم تاریک/روشن
|
// اعمال تم تاریک/روشن
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user