new backend and disable ssr cart
Build and Deploy Docker Images / build_and_deploy (push) Has been cancelled
Build and Deploy Docker Images / build_and_deploy (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ArrowLeft, Trash } from 'iconsax-react';
|
||||
import Image from 'next/image';
|
||||
import { useCart } from './hook/useCart';
|
||||
import CartSummary from './components/CartSummary';
|
||||
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 PagerModal from '@/components/pager/PagerModal';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import NotificationBellIcon from '@/components/icons/NotificationBellIcon';
|
||||
|
||||
const CartPage = () => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
const router = useRouter();
|
||||
const { clearCart, items } = useCart();
|
||||
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]);
|
||||
|
||||
const isCartEmpty = cartFoods.length === 0;
|
||||
|
||||
const handleClearCart = (e: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
clearCart();
|
||||
setShowClearConfirm(false);
|
||||
};
|
||||
|
||||
const toggleClearConfirm = (e: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
setShowClearConfirm(false);
|
||||
};
|
||||
|
||||
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='grid grid-cols-3 items-center'>
|
||||
{isCartEmpty ? (
|
||||
<span></span>
|
||||
) : (
|
||||
<Trash
|
||||
className='cursor-pointer place-self-start'
|
||||
size='24'
|
||||
color='currentColor'
|
||||
onClick={() => setShowClearConfirm(true)}
|
||||
/>
|
||||
)}
|
||||
<h1 className='text-sm2 place-self-center font-medium'>{t('Heading')}</h1>
|
||||
<ArrowLeft
|
||||
className='cursor-pointer place-self-end'
|
||||
size='24'
|
||||
color='currentColor'
|
||||
onClick={() => router.back()}
|
||||
/>
|
||||
</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>
|
||||
) : isCartEmpty ? (
|
||||
<div className='flex flex-col items-center justify-center gap-4 h-full'>
|
||||
<Image
|
||||
src='/assets/images/cart.png'
|
||||
alt='cart'
|
||||
width={120}
|
||||
height={120}
|
||||
className='object-contain'
|
||||
/>
|
||||
<div className='flex flex-col items-center gap-2 text-sm2 text-muted-foreground'>
|
||||
<p>{t('EmptyStateTitle', { defaultValue: 'سبد خرید شما خالی است' })}</p>
|
||||
<p className='text-xs'>
|
||||
{t('EmptyStateDescription', {
|
||||
defaultValue: 'برای افزودن غذا، به منوی رستوران برگردید.',
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col gap-4 pb-24">
|
||||
{!isPremium && (
|
||||
<div className='bg-container rounded-container p-4 border border-border shadow-sm'>
|
||||
<div className='flex items-start gap-3 mb-4'>
|
||||
<div className='shrink-0 mt-0.5'>
|
||||
<NotificationBellIcon width={24} height={24} className="currentColor" />
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<p className='text-sm font-medium text-foreground mb-1'>
|
||||
ثبت سفارش
|
||||
</p>
|
||||
<p className='text-xs text-muted-foreground leading-5'>
|
||||
برای ثبت سفارش، لطفاً گارسون را صدا کنید
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => setShowPagerModal(true)}
|
||||
className='w-full dark:bg-white! dark:text-black! flex items-center justify-center gap-2'
|
||||
>
|
||||
<NotificationBellIcon width={18} height={18} className="text-white dark:text-black!" />
|
||||
<span>صدا کردن گارسون</span>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{cartFoods.map((food) => (
|
||||
<MenuItemRenderer key={food.id}>
|
||||
<MenuItem food={food} />
|
||||
</MenuItemRenderer>
|
||||
))}
|
||||
<CartSummary isPremium={isPremium} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={showClearConfirm ? 'fixed inset-0 z-1001' : 'pointer-events-none fixed inset-0 z-1001'}>
|
||||
<Prompt
|
||||
title='پاک کردن سبد خرید'
|
||||
description='آیا از پاک کردن تمامی آیتمهای سبد خرید اطمینان دارید؟'
|
||||
textConfirm='بله'
|
||||
textCancel='خیر'
|
||||
onConfirm={handleClearCart}
|
||||
onCancel={toggleClearConfirm}
|
||||
visible={showClearConfirm}
|
||||
onClick={toggleClearConfirm}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PagerModal visible={showPagerModal} onClose={() => setShowPagerModal(false)} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CartPage;
|
||||
@@ -1,157 +1,17 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ArrowLeft, Trash } from 'iconsax-react';
|
||||
import Image from 'next/image';
|
||||
import { useCart } from './hook/useCart';
|
||||
import CartSummary from './components/CartSummary';
|
||||
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 PagerModal from '@/components/pager/PagerModal';
|
||||
import Button from '@/components/button/PrimaryButton';
|
||||
import NotificationBellIcon from '@/components/icons/NotificationBellIcon';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const CartIndex = () => {
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
const router = useRouter();
|
||||
const { clearCart, items } = useCart();
|
||||
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]);
|
||||
|
||||
const isCartEmpty = cartFoods.length === 0;
|
||||
|
||||
const handleClearCart = (e: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
clearCart();
|
||||
setShowClearConfirm(false);
|
||||
};
|
||||
|
||||
const toggleClearConfirm = (e: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
setShowClearConfirm(false);
|
||||
};
|
||||
|
||||
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='grid grid-cols-3 items-center'>
|
||||
{isCartEmpty ? (
|
||||
<span></span>
|
||||
) : (
|
||||
<Trash
|
||||
className='cursor-pointer place-self-start'
|
||||
size='24'
|
||||
color='currentColor'
|
||||
onClick={() => setShowClearConfirm(true)}
|
||||
/>
|
||||
)}
|
||||
<h1 className='text-sm2 place-self-center font-medium'>{t('Heading')}</h1>
|
||||
<ArrowLeft
|
||||
className='cursor-pointer place-self-end'
|
||||
size='24'
|
||||
color='currentColor'
|
||||
onClick={() => router.back()}
|
||||
/>
|
||||
</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>
|
||||
) : isCartEmpty ? (
|
||||
<div className='flex flex-col items-center justify-center gap-4 h-full'>
|
||||
<Image
|
||||
src='/assets/images/cart.png'
|
||||
alt='cart'
|
||||
width={120}
|
||||
height={120}
|
||||
className='object-contain'
|
||||
/>
|
||||
<div className='flex flex-col items-center gap-2 text-sm2 text-muted-foreground'>
|
||||
<p>{t('EmptyStateTitle', { defaultValue: 'سبد خرید شما خالی است' })}</p>
|
||||
<p className='text-xs'>
|
||||
{t('EmptyStateDescription', {
|
||||
defaultValue: 'برای افزودن غذا، به منوی رستوران برگردید.',
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col gap-4 pb-24">
|
||||
{!isPremium && (
|
||||
<div className='bg-container rounded-container p-4 border border-border shadow-sm'>
|
||||
<div className='flex items-start gap-3 mb-4'>
|
||||
<div className='shrink-0 mt-0.5'>
|
||||
<NotificationBellIcon width={24} height={24} className="currentColor" />
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<p className='text-sm font-medium text-foreground mb-1'>
|
||||
ثبت سفارش
|
||||
</p>
|
||||
<p className='text-xs text-muted-foreground leading-5'>
|
||||
برای ثبت سفارش، لطفاً گارسون را صدا کنید
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => setShowPagerModal(true)}
|
||||
className='w-full dark:bg-white! dark:text-black! flex items-center justify-center gap-2'
|
||||
>
|
||||
<NotificationBellIcon width={18} height={18} className="text-white dark:text-black!" />
|
||||
<span>صدا کردن گارسون</span>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{cartFoods.map((food) => (
|
||||
<MenuItemRenderer key={food.id}>
|
||||
<MenuItem food={food} />
|
||||
</MenuItemRenderer>
|
||||
))}
|
||||
<CartSummary isPremium={isPremium} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={showClearConfirm ? 'fixed inset-0 z-1001' : 'pointer-events-none fixed inset-0 z-1001'}>
|
||||
<Prompt
|
||||
title='پاک کردن سبد خرید'
|
||||
description='آیا از پاک کردن تمامی آیتمهای سبد خرید اطمینان دارید؟'
|
||||
textConfirm='بله'
|
||||
textCancel='خیر'
|
||||
onConfirm={handleClearCart}
|
||||
onCancel={toggleClearConfirm}
|
||||
visible={showClearConfirm}
|
||||
onClick={toggleClearConfirm}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PagerModal visible={showPagerModal} onClose={() => setShowPagerModal(false)} />
|
||||
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 CartIndex;
|
||||
export default function Page() {
|
||||
return <CartPage />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user