From bee8127450033366d78edd7b44d984035dff7ba1 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 22 Dec 2025 17:08:22 +0330 Subject: [PATCH] favorite list --- .../favorite/hooks/useFavoriteData.ts | 9 ++ src/app/[name]/(Profile)/favorite/page.tsx | 97 +++++++++++++++++++ .../(Profile)/favorite/service/Service.ts | 7 ++ .../[name]/(Profile)/favorite/types/Types.ts | 39 ++++++++ src/components/navigation/BottomNavBar.tsx | 17 +++- 5 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 src/app/[name]/(Profile)/favorite/hooks/useFavoriteData.ts create mode 100644 src/app/[name]/(Profile)/favorite/page.tsx create mode 100644 src/app/[name]/(Profile)/favorite/service/Service.ts create mode 100644 src/app/[name]/(Profile)/favorite/types/Types.ts diff --git a/src/app/[name]/(Profile)/favorite/hooks/useFavoriteData.ts b/src/app/[name]/(Profile)/favorite/hooks/useFavoriteData.ts new file mode 100644 index 0000000..46d09b1 --- /dev/null +++ b/src/app/[name]/(Profile)/favorite/hooks/useFavoriteData.ts @@ -0,0 +1,9 @@ +import { useQuery } from "@tanstack/react-query"; +import { getFavorites } from "../service/Service"; + +export const useGetFavorites = () => { + return useQuery({ + queryKey: ["favorites"], + queryFn: getFavorites, + }); +}; diff --git a/src/app/[name]/(Profile)/favorite/page.tsx b/src/app/[name]/(Profile)/favorite/page.tsx new file mode 100644 index 0000000..18b54f8 --- /dev/null +++ b/src/app/[name]/(Profile)/favorite/page.tsx @@ -0,0 +1,97 @@ +'use client' +import React, { useMemo } from 'react' +import { useRouter } from 'next/navigation' +import { ArrowLeft } from 'iconsax-react' +import { useGetFavorites } from './hooks/useFavoriteData' +import MenuItem from '@/components/listview/MenuItem' +import MenuItemRenderer from '@/components/listview/MenuItemRenderer' +import VerticalScrollView from '@/components/listview/VerticalScrollView' +import type { Favorite } from './types/Types' +import type { Food } from '@/app/[name]/(Main)/types/Types' + +function FavoritePage() { + const router = useRouter() + const { data: favoritesData, isLoading } = useGetFavorites() + + const favorites = useMemo(() => { + return favoritesData?.data || [] + }, [favoritesData?.data]) + + const foodItems = useMemo(() => { + return favorites.map((favorite: Favorite) => { + const favoriteFood = favorite.food + // تبدیل FavoriteFood به Food برای استفاده در MenuItem + const food: Food = { + id: favoriteFood.id, + createdAt: favoriteFood.createdAt, + updatedAt: favoriteFood.updatedAt, + deletedAt: favoriteFood.deletedAt, + restaurant: favoriteFood.restaurant as unknown as Food['restaurant'], + category: favoriteFood.category as unknown as Food['category'], + inventory: {} as Food['inventory'], + title: favoriteFood.title, + desc: favoriteFood.desc, + content: favoriteFood.content, + price: favoriteFood.price, + order: favoriteFood.order, + prepareTime: favoriteFood.prepareTime, + weekDays: favoriteFood.weekDays, + mealTypes: favoriteFood.mealTypes, + isActive: favoriteFood.isActive, + images: favoriteFood.images, + inPlaceServe: favoriteFood.inPlaceServe, + pickupServe: favoriteFood.pickupServe, + score: favoriteFood.score, + discount: favoriteFood.discount, + isSpecialOffer: favoriteFood.isSpecialOffer, + reviews: [], + favorites: [], + isFavorite: true, + name: favoriteFood.title, + description: favoriteFood.desc, + } + return food + }) + }, [favorites]) + + return ( +
+
+ +

علاقه‌مندی‌ها

+ { router.back() }} + /> +
+ +
+ {isLoading ? ( +
+ +

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

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

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

+

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

+
+ ) : ( + + {foodItems.map((food) => ( + + + + ))} + + )} +
+
+ ) +} + +export default FavoritePage \ No newline at end of file diff --git a/src/app/[name]/(Profile)/favorite/service/Service.ts b/src/app/[name]/(Profile)/favorite/service/Service.ts new file mode 100644 index 0000000..e7fd512 --- /dev/null +++ b/src/app/[name]/(Profile)/favorite/service/Service.ts @@ -0,0 +1,7 @@ +import { api } from "@/config/axios"; +import { FavoritesResponse } from "../types/Types"; + +export const getFavorites = async (): Promise => { + const { data } = await api.get("/public/foods/favorite"); + return data; +}; diff --git a/src/app/[name]/(Profile)/favorite/types/Types.ts b/src/app/[name]/(Profile)/favorite/types/Types.ts new file mode 100644 index 0000000..215c5d5 --- /dev/null +++ b/src/app/[name]/(Profile)/favorite/types/Types.ts @@ -0,0 +1,39 @@ +import { BaseResponse } from "@/app/[name]/(Main)/types/Types"; + +export type MealType = "breakfast" | "lunch" | "dinner" | "snack"; + +export interface FavoriteFood { + id: string; + createdAt: string; + updatedAt: string; + deletedAt: string | null; + restaurant: string; + category: string; + title: string; + desc: string; + content: string[]; + price: number; + order: number | null; + prepareTime: number | null; + weekDays: number[]; + mealTypes: MealType[]; + isActive: boolean; + images: string[]; + inPlaceServe: boolean; + pickupServe: boolean; + score: number; + discount: number; + isSpecialOffer: boolean; +} + +export interface Favorite { + id: string; + createdAt: string; + updatedAt: string; + deletedAt: string | null; + user: string; + food: FavoriteFood; +} + +export type FavoritesResponse = BaseResponse; + diff --git a/src/components/navigation/BottomNavBar.tsx b/src/components/navigation/BottomNavBar.tsx index ba5cb88..e07a5e1 100644 --- a/src/components/navigation/BottomNavBar.tsx +++ b/src/components/navigation/BottomNavBar.tsx @@ -7,18 +7,20 @@ import BottomNavHighlightLink from './BottomNavLinkBig' import PagerIcon from '../icons/PagerIcon' import BagIcon from '../icons/BagIcon' import HeartIcon from '../icons/HeartIcon' -import { useParams, usePathname } from 'next/navigation' +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 { Building } from 'iconsax-react'; import clsx from 'clsx'; +import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData'; type BottomNavBarProps = { onPagerClick?: () => void; }; function BottomNavBar({ onPagerClick }: BottomNavBarProps) { + const params = useParams(); const { name } = params; const pathname = usePathname(); @@ -27,7 +29,8 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) { const buildingVariant = React.useMemo(() => { return (isAboutRoute ? 'Bold' : 'Outline') as 'Bold' | 'Outline'; }, [isAboutRoute]); - + const { isSuccess } = useGetProfile() + const router = useRouter() const { t } = useTranslation('common', { keyPrefix: 'BottomNavbar' }); @@ -39,6 +42,14 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) { }, 0); }, [items]); + const handleFavoritesClick = () => { + if (isSuccess) { + router.push('/favorites'); + } else { + router.push(`/${name}/auth`); + } + } + return (
@@ -111,7 +122,7 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) { {t('about')} - } value={t('Favorites')} /> + } value={t('Favorites')} />