This commit is contained in:
@@ -1,134 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useParams, useRouter, usePathname } from 'next/navigation';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import { useGetFoods } from '@/app/[name]/(Main)/hooks/useMenuData';
|
||||
import type { Food } from '@/app/[name]/(Main)/types/Types';
|
||||
import { useCart } from '../hook/useCart';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useGetCartItems } from '../hooks/useCartData';
|
||||
import { useCartStore } from '../store/Store';
|
||||
|
||||
interface CartSummaryProps {
|
||||
isPremium: boolean;
|
||||
}
|
||||
|
||||
const CartSummary = ({ isPremium }: CartSummaryProps) => {
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const name = params.name as string;
|
||||
const { isSuccess } = useGetProfile();
|
||||
const { data: foodsResponse } = useGetFoods();
|
||||
const foods = React.useMemo(() => foodsResponse?.data ?? [], [foodsResponse?.data]);
|
||||
const { items } = useCart();
|
||||
const { data: cartData } = useGetCartItems(isSuccess);
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
const { description, setDescription } = useCartStore();
|
||||
|
||||
const cartFoods = React.useMemo(() => {
|
||||
if (!foods.length) return [];
|
||||
return Object.entries(items)
|
||||
.filter(([, detail]) => detail?.quantity && detail.quantity > 0)
|
||||
.map(([id]) =>
|
||||
foods.find((foodItem) => String(foodItem.id) === String(id))
|
||||
)
|
||||
.filter((food): food is Food => Boolean(food));
|
||||
}, [foods, items]);
|
||||
|
||||
const totalPrice = React.useMemo(() => {
|
||||
// اگر داده از API آمده و total وجود دارد، از آن استفاده میکنیم
|
||||
if (isSuccess && cartData?.data?.total !== undefined) {
|
||||
return cartData.data.total;
|
||||
}
|
||||
|
||||
// در غیر این صورت، محاسبه محلی با در نظر گرفتن تخفیف
|
||||
return cartFoods.reduce((sum, food) => {
|
||||
const qty = items[String(food.id)]?.quantity ?? 0;
|
||||
const basePrice = food.price ?? 0;
|
||||
const discount = food.discount ?? 0;
|
||||
const priceAfterDiscount = basePrice * (1 - discount / 100);
|
||||
return sum + priceAfterDiscount * qty;
|
||||
}, 0);
|
||||
}, [cartFoods, items, isSuccess, cartData?.data?.total]);
|
||||
|
||||
const isCartEmpty = cartFoods.length === 0;
|
||||
|
||||
const formatPrice = React.useCallback(
|
||||
(value: number) => value.toLocaleString('fa-IR'),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isCartEmpty && (
|
||||
<>
|
||||
{isPremium && (
|
||||
<div className='mt-2 mb-4'>
|
||||
<div className='relative'>
|
||||
<h3 className='text-sm'>{t('InputDescription.Label')}</h3>
|
||||
<textarea
|
||||
className='w-full px-4 py-2.5 mt-4 text-sm2 leading-6 outline-0 border border-border rounded-normal resize-none focus:ring-0'
|
||||
placeholder={t('InputDescription.Placeholder')}
|
||||
id='description'
|
||||
name='description'
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
></textarea>
|
||||
<span className='absolute top-4 right-2 px-2 bg-background text-foreground text-xs'></span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='fixed bottom-0 left-0 right-0 z-50 bg-white dark:bg-container border-t border-border p-4 w-full'>
|
||||
<div className='flex justify-between items-center gap-4'>
|
||||
<div className='flex flex-col'>
|
||||
<div className='text-xs text-gray-400 dark:text-disabled-text'>{t('PayableAmountLabel')}</div>
|
||||
{
|
||||
isPremium &&
|
||||
<div className='text-sm mt-2 font-semibold dark:text-foreground'>{formatPrice(totalPrice)} تومان</div>
|
||||
|
||||
}
|
||||
</div>
|
||||
|
||||
{isPremium && (
|
||||
<Link
|
||||
href={'order/checkout/0'}
|
||||
onClick={(event) => {
|
||||
if (!isSuccess) {
|
||||
event.preventDefault();
|
||||
const redirectUrl = encodeURIComponent(pathname);
|
||||
router.replace(`/${name}/auth?redirect=${redirectUrl}`);
|
||||
return;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button className='w-fit! px-10 dark:bg-white dark:text-black! dark:hover:bg-gray-100'>{t('ButtonCheckout')}</Button>
|
||||
</Link>
|
||||
)}
|
||||
{!isPremium && (
|
||||
<div className='text-sm mt-2 font-semibold dark:text-foreground'>{formatPrice(totalPrice)} تومان</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* {!isCartEmpty && (
|
||||
<div className='flex items-center justify-between rounded-xl border border-border px-4 py-3 text-xs text-muted-foreground'>
|
||||
<span>{t('CartControlsHint', { defaultValue: 'برای ویرایش تعداد، از دکمههای هر آیتم استفاده کنید.' })}</span>
|
||||
<div className='flex items-center gap-1 text-foreground'>
|
||||
<Add size={16} />
|
||||
<Minus size={16} />
|
||||
</div>
|
||||
</div>
|
||||
)} */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CartSummary;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const CartPage = dynamic(() => import('./CartPage'), {
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<div className='flex flex-col items-center justify-center gap-2 py-12 text-sm2 text-muted-foreground'>
|
||||
<span className='h-4 w-4 animate-spin rounded-full border border-dashed border-foreground border-t-transparent'></span>
|
||||
<p>در حال دریافت سبد خرید...</p>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
|
||||
export default function Page() {
|
||||
return <CartPage />;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import Button from '@/components/button/PrimaryButton';
|
||||
import { extractErrorMessage } from '@/lib/func';
|
||||
import { toast } from '@/components/Toast';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useGetCartItems } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData';
|
||||
import { useGetCartItems } from '@/app/[name]/(Main)/cart/hooks/useCartData';
|
||||
|
||||
type CouponSectionProps = {
|
||||
couponType: string;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
|
||||
import { useGetPaymentMethod } from '../../hooks/useOrderData';
|
||||
import { useCheckoutStore } from '../../store/Store';
|
||||
import { useGetUserWallet } from '@/app/[name]/(Main)/transactions/hooks/useTransactionData';
|
||||
import { useGetCartItems } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData';
|
||||
import { useGetCartItems } from '@/app/[name]/(Main)/cart/hooks/useCartData';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
|
||||
type PaymentSectionProps = {
|
||||
|
||||
@@ -9,12 +9,12 @@ import { toast } from '@/components/Toast';
|
||||
import { useCreateOrder } from '../../hooks/useOrderData';
|
||||
import { extractErrorMessage } from '@/lib/func';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useGetCartItems, useSaveAllMethod } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData';
|
||||
import { useGetCartItems, useSaveAllMethod } from '@/app/[name]/(Main)/cart/hooks/useCartData';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useGetShipmentMethod } from '../../hooks/useOrderData';
|
||||
import CartItemsList from '@/app/[name]/(Dialogs)/cart/components/CartItemsList';
|
||||
import { useCartStore } from '@/app/[name]/(Dialogs)/cart/store/Store';
|
||||
import CartItemsList from '@/app/[name]/(Main)/cart/components/CartItemsList';
|
||||
import { useCartStore } from '@/app/[name]/(Main)/cart/store/Store';
|
||||
|
||||
type SummarySectionProps = {
|
||||
cartModal: boolean;
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ShippingSection } from './components/ShippingSection';
|
||||
import { SummarySection } from './components/SummarySection';
|
||||
import { TableSection } from './components/TableSection';
|
||||
import { useGetShipmentMethod } from '../hooks/useOrderData';
|
||||
import { useGetCartItems } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData';
|
||||
import { useGetCartItems } from '@/app/[name]/(Main)/cart/hooks/useCartData';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useCheckoutStore } from '../store/Store';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useCart } from "@/app/[name]/(Dialogs)/cart/hook/useCart";
|
||||
import { useCart } from "@/app/[name]/(Main)/cart/hook/useCart";
|
||||
import MinusIcon from "@/components/icons/MinusIcon";
|
||||
import PlusIcon from "@/components/icons/PlusIcon";
|
||||
import { toast } from "@/components/Toast";
|
||||
|
||||
@@ -9,6 +9,8 @@ export const useGetAbout = () => {
|
||||
queryFn: () => api.getAbout(name),
|
||||
enabled: !!name,
|
||||
retry: false,
|
||||
staleTime: 5 * 60_000,
|
||||
refetchOnMount: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
+38
-22
@@ -11,35 +11,54 @@ import Prompt from '@/components/utils/Prompt';
|
||||
import { useGetFoods } from '@/app/[name]/(Main)/hooks/useMenuData';
|
||||
import MenuItem from '@/components/listview/MenuItem';
|
||||
import MenuItemRenderer from '@/components/listview/MenuItemRenderer';
|
||||
import type { Food } from '@/app/[name]/(Main)/types/Types';
|
||||
import { useGetAbout } from '../../(Main)/about/hooks/useAboutData';
|
||||
import { useGetAbout } from '../about/hooks/useAboutData';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useGetCartItems } from './hooks/useCartData';
|
||||
import PagerModal from '@/components/pager/PagerModal';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import NotificationBellIcon from '@/components/icons/NotificationBellIcon';
|
||||
import CartSkeleton from './components/CartSkeleton';
|
||||
import {
|
||||
cartItemToFood,
|
||||
guestCartItemsToFoods,
|
||||
hasCartEntries,
|
||||
} from './lib/cartUtils';
|
||||
|
||||
const CartPage = () => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
const router = useRouter();
|
||||
const { isSuccess } = useGetProfile();
|
||||
const { clearCart, items } = useCart();
|
||||
const { data: cartData, isPending: cartPending } = useGetCartItems(isSuccess);
|
||||
const { data: foodsResponse } = useGetFoods();
|
||||
const { data: aboutData } = useGetAbout();
|
||||
const [showClearConfirm, setShowClearConfirm] = React.useState(false);
|
||||
const [showPagerModal, setShowPagerModal] = React.useState(false);
|
||||
const { data: foodsResponse, isFetching } = useGetFoods();
|
||||
const { data: aboutData } = useGetAbout();
|
||||
|
||||
const isPremium = aboutData?.data?.plan === 'premium';
|
||||
const foods = React.useMemo(() => foodsResponse?.data ?? [], [foodsResponse?.data]);
|
||||
const isLoading = isFetching && !foods.length;
|
||||
|
||||
const cartFoods = React.useMemo(() => {
|
||||
if (!foods.length) return [];
|
||||
return Object.entries(items)
|
||||
.filter(([, detail]) => detail?.quantity && detail.quantity > 0)
|
||||
.map(([id]) =>
|
||||
foods.find((foodItem) => String(foodItem.id) === String(id))
|
||||
)
|
||||
.filter((food): food is Food => Boolean(food));
|
||||
}, [foods, items]);
|
||||
if (isSuccess) {
|
||||
const apiItems =
|
||||
cartData?.data?.items?.filter((item) => item.quantity > 0) ?? [];
|
||||
return apiItems.map(cartItemToFood);
|
||||
}
|
||||
return guestCartItemsToFoods(items, foodsResponse?.data ?? []);
|
||||
}, [isSuccess, cartData?.data?.items, items, foodsResponse?.data]);
|
||||
|
||||
const isCartEmpty = cartFoods.length === 0;
|
||||
const hasItems = React.useMemo(() => {
|
||||
if (isSuccess) {
|
||||
return (cartData?.data?.totalItems ?? 0) > 0 || hasCartEntries(items);
|
||||
}
|
||||
return hasCartEntries(items);
|
||||
}, [isSuccess, cartData?.data?.totalItems, items]);
|
||||
|
||||
const guestAwaitingMenu =
|
||||
!isSuccess && hasItems && cartFoods.length === 0 && !foodsResponse?.data;
|
||||
|
||||
const showInitialCartLoad = isSuccess && cartPending && !cartData && hasItems;
|
||||
|
||||
const isCartEmpty = !hasItems;
|
||||
|
||||
const handleClearCart = (e: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
@@ -55,7 +74,7 @@ const CartPage = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='overflow-y-auto h-full noscrollbar flex flex-col bg-background -mx-6 -mt-4 -mb-6 px-6 pt-4 pb-6'>
|
||||
<div className='overflow-y-auto h-full noscrollbar flex flex-col bg-background'>
|
||||
<div className='grid grid-cols-3 items-center'>
|
||||
{isCartEmpty ? (
|
||||
<span></span>
|
||||
@@ -77,11 +96,8 @@ const CartPage = () => {
|
||||
</div>
|
||||
|
||||
<div className="mt-8 flex-1 h-full">
|
||||
{isLoading ? (
|
||||
<div className='flex flex-col items-center justify-center gap-2 py-12 text-sm2 text-muted-foreground'>
|
||||
<span className='h-4 w-4 animate-spin rounded-full border border-dashed border-foreground border-t-transparent'></span>
|
||||
<p>در حال دریافت سبد خرید...</p>
|
||||
</div>
|
||||
{showInitialCartLoad || guestAwaitingMenu ? (
|
||||
<CartSkeleton />
|
||||
) : isCartEmpty ? (
|
||||
<div className='flex flex-col items-center justify-center gap-4 h-full'>
|
||||
<Image
|
||||
@@ -131,7 +147,7 @@ const CartPage = () => {
|
||||
<MenuItem food={food} />
|
||||
</MenuItemRenderer>
|
||||
))}
|
||||
<CartSummary isPremium={isPremium} />
|
||||
<CartSummary isPremium={isPremium} hasItems={hasItems} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -0,0 +1,115 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useParams, useRouter, usePathname } from 'next/navigation';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import { useGetFoods } from '@/app/[name]/(Main)/hooks/useMenuData';
|
||||
import { useCart } from '../hook/useCart';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
import { useGetCartItems } from '../hooks/useCartData';
|
||||
import { useCartStore } from '../store/Store';
|
||||
import { guestCartItemsToFoods } from '../lib/cartUtils';
|
||||
|
||||
interface CartSummaryProps {
|
||||
isPremium: boolean;
|
||||
hasItems: boolean;
|
||||
}
|
||||
|
||||
const CartSummary = ({ isPremium, hasItems }: CartSummaryProps) => {
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const name = params.name as string;
|
||||
const { isSuccess } = useGetProfile();
|
||||
const { data: foodsResponse } = useGetFoods();
|
||||
const { items } = useCart();
|
||||
const { data: cartData } = useGetCartItems(isSuccess);
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
const { description, setDescription } = useCartStore();
|
||||
|
||||
const totalPrice = React.useMemo(() => {
|
||||
if (isSuccess && cartData?.data?.total !== undefined) {
|
||||
return cartData.data.total;
|
||||
}
|
||||
|
||||
const foods = foodsResponse?.data ?? [];
|
||||
const cartFoods = guestCartItemsToFoods(items, foods);
|
||||
return cartFoods.reduce((sum, food) => {
|
||||
const qty = items[String(food.id)]?.quantity ?? 0;
|
||||
const basePrice = food.price ?? 0;
|
||||
const discount = food.discount ?? 0;
|
||||
const priceAfterDiscount = basePrice * (1 - discount / 100);
|
||||
return sum + priceAfterDiscount * qty;
|
||||
}, 0);
|
||||
}, [isSuccess, cartData?.data?.total, foodsResponse?.data, items]);
|
||||
|
||||
const formatPrice = React.useCallback(
|
||||
(value: number) => value.toLocaleString('fa-IR'),
|
||||
[]
|
||||
);
|
||||
|
||||
if (!hasItems) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPremium && (
|
||||
<div className='mt-2 mb-4'>
|
||||
<div className='relative'>
|
||||
<h3 className='text-sm'>{t('InputDescription.Label')}</h3>
|
||||
<textarea
|
||||
className='w-full px-4 py-2.5 mt-4 text-sm2 leading-6 outline-0 border border-border rounded-normal resize-none focus:ring-0'
|
||||
placeholder={t('InputDescription.Placeholder')}
|
||||
id='description'
|
||||
name='description'
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
></textarea>
|
||||
<span className='absolute top-4 right-2 px-2 bg-background text-foreground text-xs'></span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='fixed bottom-0 left-0 right-0 z-50 bg-white dark:bg-container border-t border-border p-4 w-full'>
|
||||
<div className='flex justify-between items-center gap-4'>
|
||||
<div className='flex flex-col'>
|
||||
<div className='text-xs text-gray-400 dark:text-disabled-text'>{t('PayableAmountLabel')}</div>
|
||||
{isPremium && (
|
||||
<div className='text-sm mt-2 font-semibold dark:text-foreground'>
|
||||
{formatPrice(totalPrice)} تومان
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isPremium && (
|
||||
<Link
|
||||
href={'order/checkout/0'}
|
||||
onClick={(event) => {
|
||||
if (!isSuccess) {
|
||||
event.preventDefault();
|
||||
const redirectUrl = encodeURIComponent(pathname);
|
||||
router.replace(`/${name}/auth?redirect=${redirectUrl}`);
|
||||
return;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button className='w-fit! px-10 dark:bg-white dark:text-black! dark:hover:bg-gray-100'>
|
||||
{t('ButtonCheckout')}
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
{!isPremium && (
|
||||
<div className='text-sm mt-2 font-semibold dark:text-foreground'>
|
||||
{formatPrice(totalPrice)} تومان
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CartSummary;
|
||||
+1
@@ -184,6 +184,7 @@ export const useGetCartItems = (enabled = true) => {
|
||||
queryKey: ["cart-items"],
|
||||
queryFn: api.getCartItems,
|
||||
enabled,
|
||||
staleTime: 60_000,
|
||||
refetchOnMount: false,
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { CartItem } from '../types/Types';
|
||||
import type { Food } from '@/app/[name]/(Main)/types/Types';
|
||||
|
||||
export function cartItemToFood(item: CartItem): Food {
|
||||
return {
|
||||
id: item.foodId,
|
||||
category: '',
|
||||
title: item.foodTitle,
|
||||
desc: '',
|
||||
content: [],
|
||||
price: item.price,
|
||||
prepareTime: 0,
|
||||
isActive: true,
|
||||
images: [],
|
||||
inPlaceServe: true,
|
||||
pickupServe: true,
|
||||
discount: item.discount,
|
||||
isSpecialOffer: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function guestCartItemsToFoods(
|
||||
items: Record<string | number, { quantity: number }>,
|
||||
foods: Food[]
|
||||
): Food[] {
|
||||
return Object.entries(items)
|
||||
.filter(([, detail]) => detail?.quantity && detail.quantity > 0)
|
||||
.map(([id]) => foods.find((food) => String(food.id) === String(id)))
|
||||
.filter((food): food is Food => Boolean(food));
|
||||
}
|
||||
|
||||
export function hasCartEntries(
|
||||
items: Record<string | number, { quantity: number }>
|
||||
): boolean {
|
||||
return Object.values(items).some((detail) => detail?.quantity && detail.quantity > 0);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import CartPage from './CartPage';
|
||||
|
||||
export default CartPage;
|
||||
@@ -8,6 +8,8 @@ export const useGetFoods = () => {
|
||||
queryKey: ["menu"],
|
||||
queryFn: () => api.getFoods(name),
|
||||
enabled: !!name,
|
||||
staleTime: 5 * 60_000,
|
||||
refetchOnMount: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
import { cache } from "react";
|
||||
import { API_BASE_URL } from "@/config/const";
|
||||
import { AboutResponse, Restaurant } from "../(Main)/about/types/Types";
|
||||
import axios from "axios";
|
||||
|
||||
export async function getRestaurant(slug: string): Promise<Restaurant> {
|
||||
async function fetchRestaurant(slug: string): Promise<Restaurant> {
|
||||
try {
|
||||
const response = await axios(`${API_BASE_URL}/public/restaurants/${slug}`, {
|
||||
// cache: "no-store",
|
||||
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-SLUG": slug,
|
||||
},
|
||||
});
|
||||
|
||||
console.log("response", response);
|
||||
|
||||
if (!response.data) {
|
||||
if (response.status === 404) {
|
||||
throw new Error("RESTAURANT_NOT_FOUND");
|
||||
@@ -30,11 +27,11 @@ export async function getRestaurant(slug: string): Promise<Restaurant> {
|
||||
|
||||
return data.data;
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
|
||||
if (error instanceof Error && error.message === "RESTAURANT_NOT_FOUND") {
|
||||
throw error;
|
||||
}
|
||||
throw new Error(`Failed to fetch restaurant data: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
export const getRestaurant = cache(fetchRestaurant);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { useCart } from '@/app/[name]/(Dialogs)/cart/hook/useCart'
|
||||
import { useCart } from '@/app/[name]/(Main)/cart/hook/useCart'
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData'
|
||||
import { useParams } from 'next/navigation'
|
||||
import { useEffect, useRef, type FC } from 'react'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
"use client";
|
||||
|
||||
import { useCart } from "@/app/[name]/(Dialogs)/cart/hook/useCart";
|
||||
import { useCart } from "@/app/[name]/(Main)/cart/hook/useCart";
|
||||
import type { Food, FoodImage } from "@/app/[name]/(Main)/types/Types";
|
||||
import MinusIcon from "@/components/icons/MinusIcon";
|
||||
import PlusIcon from "@/components/icons/PlusIcon";
|
||||
|
||||
@@ -10,7 +10,7 @@ import HeartIcon from '../icons/HeartIcon'
|
||||
import { useParams, usePathname, useRouter } from 'next/navigation'
|
||||
import HomeIcon from '../icons/HomeIcon'
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCart } from '@/app/[name]/(Dialogs)/cart/hook/useCart';
|
||||
import { useCart } from '@/app/[name]/(Main)/cart/hook/useCart';
|
||||
import { Building } from 'iconsax-react';
|
||||
import clsx from 'clsx';
|
||||
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
|
||||
|
||||
@@ -11,12 +11,13 @@ type Props = {
|
||||
value: string
|
||||
} & LinkProps & React.AnchorHTMLAttributes<HTMLAnchorElement>
|
||||
|
||||
function BottomNavLink({ icon, value, href, ...restProps }: Props) {
|
||||
function BottomNavLink({ icon, value, href, prefetch, ...restProps }: Props) {
|
||||
const pathname = usePathname();
|
||||
const isActive = pathname === href;
|
||||
const shouldPrefetch = prefetch ?? true;
|
||||
|
||||
return (
|
||||
<Link {...restProps} href={href} className={clsx(
|
||||
<Link {...restProps} href={href} prefetch={shouldPrefetch} className={clsx(
|
||||
'flex flex-col justify-arround items-center gap-[5px] text-primary pointer-events-auto **:stroke-primary min-w-0 dark:text-white dark:**:stroke-white',
|
||||
isActive && 'text-primary-foreground **:stroke-primary-foreground',
|
||||
restProps.className ?? '',
|
||||
|
||||
@@ -32,7 +32,7 @@ function ClientSideWrapper({ children, className = 'h-full' }: Props) {
|
||||
initial={isInitial || !pathnameChanged ? false : { y: -10 }}
|
||||
animate={{ y: 0 }}
|
||||
exit={{ y: 0, transition: { duration: 0 } }}
|
||||
transition={{ duration: 0.3 }}
|
||||
transition={{ duration: 0.12 }}
|
||||
style={{ opacity: 1 }}
|
||||
className={clsx(className)}
|
||||
>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { toast } from '@/components/Toast'
|
||||
import Button from '@/components/button/PrimaryButton'
|
||||
import { extractErrorMessage } from '@/lib/func'
|
||||
import { useReceiptStore } from '@/zustand/receiptStore'
|
||||
import { useBulkCart } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData'
|
||||
import { useBulkCart } from '@/app/[name]/(Main)/cart/hooks/useCartData'
|
||||
import { setRefreshToken, setToken } from '@/lib/api/func'
|
||||
import { useSearchParams } from 'next/navigation'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user