cart page online and offline
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
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 { Add, Minus } from 'iconsax-react';
|
||||
|
||||
interface CartSummaryProps {
|
||||
description?: string;
|
||||
onDescriptionChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
const CartSummary = ({ description = '', onDescriptionChange }: CartSummaryProps) => {
|
||||
const { data: foodsResponse } = useGetFoods();
|
||||
const foods = React.useMemo(() => foodsResponse?.data ?? [], [foodsResponse?.data]);
|
||||
const { items } = useCart();
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'Cart' });
|
||||
|
||||
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) => Boolean(food));
|
||||
}, [foods, items]);
|
||||
|
||||
const totalPrice = React.useMemo(() => {
|
||||
return cartFoods.reduce((sum, food) => {
|
||||
const qty = items[String(food.id)]?.quantity ?? 0;
|
||||
return sum + (food.price ?? 0) * qty;
|
||||
}, 0);
|
||||
}, [cartFoods, items]);
|
||||
|
||||
const isCartEmpty = cartFoods.length === 0;
|
||||
|
||||
const formatPrice = React.useCallback(
|
||||
(value: number) => value.toLocaleString('fa-IR'),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<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) => onDescriptionChange?.(e.target.value)}
|
||||
></textarea>
|
||||
<span className='absolute top-4 right-2 px-2 bg-background text-foreground text-xs'></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='grid grid-cols-2 items-end gap-4'>
|
||||
<div>
|
||||
<div className='text-sm font-semibold'>
|
||||
{`جمع خرید: ${formatPrice(totalPrice)} تومان`}
|
||||
</div>
|
||||
</div>
|
||||
<Link
|
||||
href={'order/checkout/0'}
|
||||
onClick={(event) => {
|
||||
if (isCartEmpty) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}}
|
||||
className={isCartEmpty ? 'pointer-events-none opacity-60' : ''}
|
||||
>
|
||||
<Button disabled={isCartEmpty}>{t('ButtonCheckout')}</Button>
|
||||
</Link>
|
||||
</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;
|
||||
|
||||
Reference in New Issue
Block a user