diff --git a/public/assets/images/cart.png b/public/assets/images/cart.png new file mode 100644 index 0000000..8fe1d6f Binary files /dev/null and b/public/assets/images/cart.png differ diff --git a/public/assets/images/favorite.png b/public/assets/images/favorite.png new file mode 100644 index 0000000..10d0421 Binary files /dev/null and b/public/assets/images/favorite.png differ diff --git a/public/assets/images/notification.png b/public/assets/images/notification.png new file mode 100644 index 0000000..c5366cb Binary files /dev/null and b/public/assets/images/notification.png differ diff --git a/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx b/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx index 4c029ad..27b99a4 100644 --- a/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx +++ b/src/app/[name]/(Dialogs)/cart/components/CartSummary.tsx @@ -60,51 +60,47 @@ const CartSummary = () => { return ( <> -
-
-

{t('InputDescription.Label')}

- - -
-
- -
-
- -
-
{t('PayableAmountLabel')}
-
{formatPrice(totalPrice)} تومان
+ {!isCartEmpty && ( + <> +
+
+

{t('InputDescription.Label')}

+ + +
- { - if (isCartEmpty) { - event.preventDefault(); - return; - } - if (!isSuccess) { - event.preventDefault(); - const redirectUrl = encodeURIComponent(pathname); - router.push(`/${name}/auth?redirect=${redirectUrl}`); - return; - } - }} - > - - +
+
+
+
{t('PayableAmountLabel')}
+
{formatPrice(totalPrice)} تومان
+
-
-
+ { + if (!isSuccess) { + event.preventDefault(); + const redirectUrl = encodeURIComponent(pathname); + router.push(`/${name}/auth?redirect=${redirectUrl}`); + return; + } + }} + > + + +
+
+ + )} {/* {!isCartEmpty && (
diff --git a/src/app/[name]/(Dialogs)/cart/page.tsx b/src/app/[name]/(Dialogs)/cart/page.tsx index 209ec58..459fefc 100644 --- a/src/app/[name]/(Dialogs)/cart/page.tsx +++ b/src/app/[name]/(Dialogs)/cart/page.tsx @@ -4,22 +4,37 @@ 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 CartItemsList from './components/CartItemsList'; import CartSummary from './components/CartSummary'; import Prompt from '@/components/utils/Prompt'; import { useGetFoods } from '@/app/[name]/(Main)/hooks/useMenuData'; -import { CartSummarySkeleton } from './components/CartSkeleton'; +import VerticalScrollView from '@/components/listview/VerticalScrollView'; +import MenuItem from '@/components/listview/MenuItem'; +import MenuItemRenderer from '@/components/listview/MenuItemRenderer'; +import type { Food } from '@/app/[name]/(Main)/types/Types'; const CartIndex = () => { const { t } = useTranslation('parallels', { keyPrefix: 'Cart' }); const router = useRouter(); - const { clearCart } = useCart(); + const { clearCart, items } = useCart(); const [showClearConfirm, setShowClearConfirm] = React.useState(false); const { data: foodsResponse, isFetching } = useGetFoods(); 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(); @@ -34,14 +49,18 @@ const CartIndex = () => { }; return ( -
-
- setShowClearConfirm(true)} - /> +
+
+ {isCartEmpty ? ( + + ) : ( + setShowClearConfirm(true)} + /> + )}

{t('Heading')}

{ />
-
- - {isLoading ? : } +
+ {isLoading ? ( +
+ +

در حال دریافت سبد خرید...

+
+ ) : isCartEmpty ? ( +
+ cart +
+

{t('EmptyStateTitle', { defaultValue: 'سبد خرید شما خالی است' })}

+

+ {t('EmptyStateDescription', { + defaultValue: 'برای افزودن غذا، به منوی رستوران برگردید.', + })} +

+
+
+ ) : ( + + {cartFoods.map((food) => ( + + + + ))} + + + )}
diff --git a/src/app/[name]/(Dialogs)/notifications/page.tsx b/src/app/[name]/(Dialogs)/notifications/page.tsx index 98598ce..11e2edf 100644 --- a/src/app/[name]/(Dialogs)/notifications/page.tsx +++ b/src/app/[name]/(Dialogs)/notifications/page.tsx @@ -4,6 +4,7 @@ import { ef } from '@/lib/helpers/utfNumbers'; import { ArrowLeft, Trash } from 'iconsax-react'; import { useRouter } from 'next/navigation'; import React from 'react' +import Image from 'next/image'; import { useTranslation } from 'react-i18next'; import { useGetNotifications, useDeleteNotification } from './hooks/useNotificationData'; import type { Notification } from './types/Types'; @@ -30,7 +31,7 @@ const formatTime = (dateString: string): string => { export default function NotificationsIndex({ }: Props) { const { t } = useTranslation('notifications') const router = useRouter(); - const { data, isLoading, isError } = useGetNotifications(); + const { data, isLoading } = useGetNotifications(); const { mutate: deleteNotification } = useDeleteNotification(); const notifications = React.useMemo(() => { @@ -41,50 +42,9 @@ export default function NotificationsIndex({ }: Props) { deleteNotification(id); }; - if (isLoading) { - return ( -
-
- -

{t("Heading")}

- { router.back() }} - /> -
-
- -

در حال دریافت اعلان‌ها...

-
-
- ); - } - - if (isError || !notifications.length) { - return ( -
-
- -

{t("Heading")}

- { router.back() }} - /> -
-
-

اعلانی وجود ندارد

-
-
- ); - } - return ( -
-
+
+

{t("Heading")}

-
    - {notifications.map((notification: Notification) => { - const isNew = !notification.sentAt; - const formattedDate = formatDate(notification.createdAt); - const formattedTime = formatTime(notification.createdAt); +
    + {isLoading ? ( +
    + +

    در حال دریافت اعلان‌ها...

    +
    + ) : notifications.length === 0 ? ( +
    + notification +
    +

    اعلانی وجود ندارد

    +
    +
    + ) : ( +
      + {notifications.map((notification: Notification) => { + const isNew = !notification.sentAt; + const formattedDate = formatDate(notification.createdAt); + const formattedTime = formatTime(notification.createdAt); - return ( -
    • -
      {notification.title}
      -

      {notification.content}

      + return ( +
    • +
      {notification.title}
      +

      {notification.content}

      -
      -
      - {isNew && ( - - {t('Tags.New')} - - )} - - {ef(formattedDate)} - - - - {ef(formattedTime)} - -
      - handleDelete(notification.id)} - /> -
      -
    • - ); - })} -
    +
    +
    + {isNew && ( + + {t('Tags.New')} + + )} + + {ef(formattedDate)} + + + + {ef(formattedTime)} + +
    + handleDelete(notification.id)} + /> +
    + + ); + })} +
+ )} +
) } \ No newline at end of file diff --git a/src/app/[name]/(Profile)/favorite/page.tsx b/src/app/[name]/(Profile)/favorite/page.tsx index 18b54f8..55d0890 100644 --- a/src/app/[name]/(Profile)/favorite/page.tsx +++ b/src/app/[name]/(Profile)/favorite/page.tsx @@ -2,6 +2,7 @@ import React, { useMemo } from 'react' import { useRouter } from 'next/navigation' import { ArrowLeft } from 'iconsax-react' +import Image from 'next/image' import { useGetFavorites } from './hooks/useFavoriteData' import MenuItem from '@/components/listview/MenuItem' import MenuItemRenderer from '@/components/listview/MenuItemRenderer' @@ -74,11 +75,20 @@ function FavoritePage() {

در حال دریافت علاقه‌مندی‌ها...

) : foodItems.length === 0 ? ( -
-

شما هیچ مورد علاقه‌مندی ثبت نکرده‌اید

-

- برای افزودن غذا به علاقه‌مندی‌ها، به صفحه جزئیات غذا بروید -

+
+ favorite +
+

شما هیچ مورد علاقه‌مندی ثبت نکرده‌اید

+

+ برای افزودن غذا به علاقه‌مندی‌ها، به صفحه جزئیات غذا بروید +

+
) : (