From 6a6f92aefca27cb7d342099446ef5900aedf4a41 Mon Sep 17 00:00:00 2001 From: Mohammed Al-yaseen Date: Mon, 20 Oct 2025 21:42:48 +0300 Subject: [PATCH] update restaurant details source & add loyalty icon --- src/assets/locals/ar.json | 2 +- src/assets/locals/en.json | 2 +- src/components/LoyaltyCard/LoyaltyCard.tsx | 33 ++- src/pages/checkout/hooks/useOrder.ts | 7 +- .../menu/components/LocalStorageHandler.tsx | 2 +- .../menu/components/MenuFooter/MenuFooter.tsx | 6 +- .../components/MenuList/MenuList.module.css | 14 +- .../menu/components/MenuList/MenuList.tsx | 17 +- .../menu/components/SearchMenu/SearchMenu.tsx | 269 +++++++++--------- src/pages/menu/page.tsx | 23 +- src/pages/restaurant/RestaurantServices.tsx | 6 +- src/pages/restaurant/page.tsx | 34 +-- src/redux/api/others.ts | 33 ++- src/utils/constants.ts | 2 +- src/utils/types/appTypes.ts | 60 +++- 15 files changed, 305 insertions(+), 205 deletions(-) diff --git a/src/assets/locals/ar.json b/src/assets/locals/ar.json index 578dd85..0899655 100644 --- a/src/assets/locals/ar.json +++ b/src/assets/locals/ar.json @@ -119,7 +119,7 @@ "viewCart": "عرض السلة", "rating": "التقييم ", "loyaltyPoints": "نقاط الولاء", - "loyaltyDescription": "اشترى 5 وجبات واحصل على وجبة مجانية", + "loyaltyDescription": "اشترى {{value}} وجبات واحصل على وجبة مجانية", "youMightAlsoLike": "قد تعجبك أيضاً..", "choose1": "اختر 1", "specialRequest": "طلب خاص", diff --git a/src/assets/locals/en.json b/src/assets/locals/en.json index 00d9007..f7dd129 100644 --- a/src/assets/locals/en.json +++ b/src/assets/locals/en.json @@ -135,7 +135,7 @@ "viewCart": "View Cart", "rating": "Rating ", "loyaltyPoints": "Loyalty Points", - "loyaltyDescription": "Buy 5 meals and get 1 FREE", + "loyaltyDescription": "Buy {{value}} meals and get 1 FREE", "choose1": "Choose 1", "youMightAlsoLike": "You might also like..", "specialRequest": "Special Request", diff --git a/src/components/LoyaltyCard/LoyaltyCard.tsx b/src/components/LoyaltyCard/LoyaltyCard.tsx index 86d4174..321b6b0 100644 --- a/src/components/LoyaltyCard/LoyaltyCard.tsx +++ b/src/components/LoyaltyCard/LoyaltyCard.tsx @@ -1,13 +1,16 @@ -import { Button, Card, Col, Row } from "antd"; +import { Button, Card, Col, Image, Row } from "antd"; import LoyaltyIcon from "components/Icons/cart/LoyaltyIcons"; import PresentIcon from "components/Icons/cart/PresentIcon"; import { useTranslation } from "react-i18next"; +import { useGetRestaurantDetailsQuery } from "redux/api/others"; import { colors } from "../../ThemeConstants"; import ProText from "../ProText"; import styles from "./LoyaltyCard.module.css"; const LoyaltyCard = () => { const { t } = useTranslation(); + const { data: restaurant } = useGetRestaurantDetailsQuery("595"); + return (
@@ -37,7 +40,9 @@ const LoyaltyCard = () => { top: -2, }} > - {t("menu.loyaltyDescription")} + {t("menu.loyaltyDescription", { + value: restaurant?.loyalty_stamps, + })} @@ -48,11 +53,25 @@ const LoyaltyCard = () => {
- {["#006347", "#e23000", "#006d34", "#006db7", "#e40000"].map( - (color) => ( -
- ) - )} + + + x{restaurant?.loyalty_stamps} +
diff --git a/src/pages/checkout/hooks/useOrder.ts b/src/pages/checkout/hooks/useOrder.ts index effacca..14260d7 100644 --- a/src/pages/checkout/hooks/useOrder.ts +++ b/src/pages/checkout/hooks/useOrder.ts @@ -38,12 +38,12 @@ export default function useOrder() { couponID: coupon, discountAmount: 0, comment: specialRequest, + delivery_method: "3", timeslot: "", - table_id: tables, + table_id: tables[0], deliveryType: orderType, - dineType: orderType, type: "table-pickup", - user_id: id, + // user_id: id, restorant_id: restaurantID, items: items.map((i) => ({ ...i, @@ -74,6 +74,7 @@ export default function useOrder() { senderEmail: giftDetails?.senderEmail, senderPhone: giftDetails?.senderPhone, senderName: giftDetails?.senderName, + dineType: orderType } : {}), }) diff --git a/src/pages/menu/components/LocalStorageHandler.tsx b/src/pages/menu/components/LocalStorageHandler.tsx index a718a67..1bf9b64 100644 --- a/src/pages/menu/components/LocalStorageHandler.tsx +++ b/src/pages/menu/components/LocalStorageHandler.tsx @@ -31,7 +31,7 @@ export default function LocalStorageHandler({ restaurantName, }: { restaurantID: string; - restaurantName: string; + restaurantName?: string; }) { useEffect(() => { // Check if restaurant has changed diff --git a/src/pages/menu/components/MenuFooter/MenuFooter.tsx b/src/pages/menu/components/MenuFooter/MenuFooter.tsx index e60837f..f0fa027 100644 --- a/src/pages/menu/components/MenuFooter/MenuFooter.tsx +++ b/src/pages/menu/components/MenuFooter/MenuFooter.tsx @@ -4,16 +4,16 @@ import ProText from "components/ProText"; import { selectCartItems } from "features/order/orderSlice"; import useBreakPoint from "hooks/useBreakPoint"; import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; +import { Link, useParams } from "react-router-dom"; import { useAppSelector } from "redux/hooks"; import { colors, ProBlack2 } from "ThemeConstants"; export function MenuFooter() { const items = useAppSelector(selectCartItems); - const restaurantName = localStorage.getItem("restaurantName"); const { themeName } = useAppSelector((state) => state.theme); const { isMobile, isTablet } = useBreakPoint(); const { t } = useTranslation(); + const { id } = useParams(); const totalItems = items.reduce((sum, item) => sum + item.quantity, 0); @@ -37,7 +37,7 @@ export function MenuFooter() { }} > state.order); - const restaurantName = localStorage.getItem("restaurantName"); + const { id } = useParams(); const navigate = useNavigate(); const { t } = useTranslation(); const { themeName } = useAppSelector((state) => state.theme); @@ -45,7 +46,7 @@ export function MenuList({ data, categoryRefs }: MenuListProps) { if (isDesktop) { setIsDialogOpen(true); } else { - navigate(`/${restaurantName}/product/${item.id}`); + navigate(`/${id}/product/${item.id}`); } }; @@ -238,6 +239,14 @@ export function MenuList({ data, categoryRefs }: MenuListProps) {
+ {item.isHasLoyalty && ( +
-
- + + + {items.find((i) => i.id === item.id) && ( + i.id === item.id)?.quantity} + className={ + styles.cartBadge + + " " + + (isRTL ? styles.cartBadgeRTL : styles.cartBadgeLTR) + } + style={{ + backgroundColor: colors.primary, + }} + title={`${ + items.find((i) => i.id === item.id)?.quantity + } in cart`} + /> + )}
-
- - - - - {items.find((i) => i.id === item.id) && ( - i.id === item.id)?.quantity} - className={ - styles.cartBadge + - " " + - (isRTL ? styles.cartBadgeRTL : styles.cartBadgeLTR) - } - style={{ - backgroundColor: colors.primary, - }} - title={`${ - items.find((i) => i.id === item.id)?.quantity - } in cart`} - /> - )} -
- - - - ))} - + + + ))} + ); diff --git a/src/pages/menu/page.tsx b/src/pages/menu/page.tsx index f9e9426..0b42c9d 100644 --- a/src/pages/menu/page.tsx +++ b/src/pages/menu/page.tsx @@ -30,15 +30,14 @@ function MenuPage() { const { id } = useParams(); const { isRTL } = useAppSelector((state) => state.locale); const { t } = useTranslation(); - const { data: restaurantDetails, isLoading: isLoadingRestaurant } = - useGetRestaurantDetailsQuery(id, { + const { data: restaurant, isLoading: isLoadingRestaurant } = + useGetRestaurantDetailsQuery("595", { skip: !id, }); - const { restaurant } = restaurantDetails || {}; const { data: menuData, isLoading: isLoadingMenu } = useGetMenuQuery( - restaurantDetails?.restaurant.id, + restaurant?.restautantId, { - skip: !restaurantDetails?.restaurant.id, + skip: !restaurant?.restautantId, }, ); const { categoryRefs } = useScrollHandler(); @@ -47,10 +46,7 @@ function MenuPage() { return ( <> - + {isLoading ? ( @@ -58,7 +54,7 @@ function MenuPage() {
{t("menu.restaurantLogo")}
- {isRTL ? restaurant?.nameAR : restaurant?.name} + {isRTL ? restaurant?.nameAR : restaurant?.restautantName}
@@ -120,7 +116,8 @@ function MenuPage() {
- + {restaurant?.loyalty_stamps && + restaurant?.is_loyalty_enabled && }
diff --git a/src/pages/restaurant/RestaurantServices.tsx b/src/pages/restaurant/RestaurantServices.tsx index 4d2906d..d18fbfc 100644 --- a/src/pages/restaurant/RestaurantServices.tsx +++ b/src/pages/restaurant/RestaurantServices.tsx @@ -11,7 +11,7 @@ import ToRoomIcon from "components/Icons/ToRoomIcon"; import ProTitle from "components/ProTitle"; import { updateOrderType } from "features/order/orderSlice"; import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; +import { Link, useParams } from "react-router-dom"; import { useAppDispatch, useAppSelector } from "redux/hooks"; import styles from "./restaurant.module.css"; @@ -37,9 +37,9 @@ export default function RestaurantServices({ }: RestaurantServicesProps) { const { t } = useTranslation(); const { isRTL } = useAppSelector((state) => state.locale); - const id = localStorage.getItem("restaurantName"); + const { id } = useParams(); const dispatch = useAppDispatch(); - + const services = [ ...((dineIn && [ { diff --git a/src/pages/restaurant/page.tsx b/src/pages/restaurant/page.tsx index 79418be..f2bc80a 100644 --- a/src/pages/restaurant/page.tsx +++ b/src/pages/restaurant/page.tsx @@ -19,11 +19,12 @@ import LocalStorageHandler from "../menu/components/LocalStorageHandler"; export default function RestaurantPage() { const param = useParams(); const { isRTL } = useAppSelector((state) => state.locale); - const { data, isLoading } = useGetRestaurantDetailsQuery(param.id, { - skip: !param.id, - }); - const { restaurant, dineIn, pickup, delivery, gift, toOffice, toRoom } = - data || {}; + const { data: restaurant, isLoading } = useGetRestaurantDetailsQuery( + "595", + { + skip: !param.id, + }, + ); if (isLoading) { return ; @@ -34,8 +35,7 @@ export default function RestaurantPage() { } if (restaurant) { - localStorage.setItem("restaurantID", restaurant.id); - localStorage.setItem("restaurantName", restaurant.subdomain); + localStorage.setItem("restaurantID", restaurant.restautantId); } return ( @@ -48,7 +48,7 @@ export default function RestaurantPage() {
logo
- {isRTL ? restaurant?.nameAR : restaurant?.name} + {isRTL ? restaurant?.nameAR : restaurant?.restautantName} {isRTL ? restaurant?.descriptionAR : restaurant?.description} @@ -64,12 +64,12 @@ export default function RestaurantPage() {
@@ -85,8 +85,8 @@ export default function RestaurantPage() {
); diff --git a/src/redux/api/others.ts b/src/redux/api/others.ts index ff0823e..68069c9 100644 --- a/src/redux/api/others.ts +++ b/src/redux/api/others.ts @@ -5,7 +5,7 @@ import { ORDERS_URL, PRODUCTS_AND_CATEGORIES_URL, RESTAURANT_DETAILS_URL, - TABLES_URL + TABLES_URL, } from "utils/constants"; import { OrderDetails } from "pages/checkout/hooks/types"; @@ -16,10 +16,15 @@ import { baseApi } from "./apiSlice"; export const branchApi = baseApi.injectEndpoints({ endpoints: (builder) => ({ getRestaurantDetails: builder.query({ - query: (restaurantId: string) => - `${RESTAURANT_DETAILS_URL}${restaurantId}`, + query: (restaurantId: string) => ({ + url: RESTAURANT_DETAILS_URL, + method: "POST", + body: { + restaurant_id: restaurantId, + }, + }), transformResponse: (response: any) => { - return response.result; + return response?.result?.restaurants?.[0]; }, }), getMenu: builder.query({ @@ -55,10 +60,7 @@ export const branchApi = baseApi.injectEndpoints({ }), invalidatesTags: ["Orders"], }), - getTables: builder.query< - any, - { restaurantID: string; tableType: string } - >({ + getTables: builder.query({ query: ({ restaurantID, tableType, @@ -77,8 +79,17 @@ export const branchApi = baseApi.injectEndpoints({ return response.result.data; }, }), - getOrderDetails: builder.query({ - query: ({ orderID, restaurantID }: { orderID: string; restaurantID: string }) => ({ + getOrderDetails: builder.query< + OrderDetails, + { orderID: string; restaurantID: string } + >({ + query: ({ + orderID, + restaurantID, + }: { + orderID: string; + restaurantID: string; + }) => ({ url: `${ORDER_DETAILS_URL}/${orderID}`, method: "POST", body: { @@ -98,5 +109,5 @@ export const { useGetOrdersQuery, useGetTablesQuery, useGetOrderDetailsQuery, - useCancelOrderMutation + useCancelOrderMutation, } = branchApi; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index cefa1d6..7cf4f36 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -91,7 +91,7 @@ export const PATHS = { privacy: path(ROOTS_DEFAULT, "/privacy"), }; -export const RESTAURANT_DETAILS_URL = `${BASE_URL}restaurant/selectLanguage/`; +export const RESTAURANT_DETAILS_URL = `${BASE_URL}restaurants/one`; export const PRODUCTS_AND_CATEGORIES_URL = `${BASE_URL}getRestaurantItems/`; export const PRODUCT_DETAILS_URL = `${BASE_URL}getOptionsForItem/`; export const ORDERS_URL = `${BASE_URL}customer_orders`; diff --git a/src/utils/types/appTypes.ts b/src/utils/types/appTypes.ts index b6bc477..f2ff901 100644 --- a/src/utils/types/appTypes.ts +++ b/src/utils/types/appTypes.ts @@ -319,11 +319,8 @@ export interface Translation { locale: string; } - - // ################################################# - export interface CartItem { id: number | string; name: string; @@ -343,7 +340,6 @@ export interface User { role: "admin" | "user"; } - export type Locale = "en" | "ar"; export type Theme = "light" | "dark"; @@ -445,6 +441,22 @@ export interface Hours { } export interface RestaurantDetails { + restautantId: string; + restautantName: string; + nameAR: string; + address: string; + addressAR: string; + restautantImage: string; + restaurant_logo: string; + restaurant_cover: string; + distance: number; + description: string; + descriptionAR: string; + price_rate: number; + vat: number; + lat: string; + lng: string; + hasDinein: boolean; dineIn: boolean; viewMenuOnly: boolean; pickup: boolean; @@ -452,7 +464,45 @@ export interface RestaurantDetails { gift: boolean; toOffice: boolean; toRoom: boolean; - restaurant: Restaurant; + online_payment: number; + online_payment_for: number; + is_wallet_payment_enabled: number; + is_booking_enabled: number; + loyalty_stamp_image: string; + loyalty_stamps: number; + customer_loyalty_points: number; + is_loyalty_enabled: number; + package_id: number; + deliver_to_office: number; + delivery_fees: string; + delivery_to_office_fees: string; + isCashPaymentEnabled: boolean; + banner: Banner[]; + contact_number: string; + menu_url: string; + taxes: Tax[]; + openingTime: string; + closingTime: string; + isOpened: boolean; + isFav: boolean; +} + +export interface Banner { + restaurant_banner1: string; + restaurant_banner2: string; + restaurant_banner3: string; +} + +export interface Tax { + id: number; + restorant_id: number; + name: string; + name_local: string; + percentage: string; + is_active: number; + created_at: string; + updated_at: string; + deleted_at: any; } export interface Category {