diff --git a/src/index.css b/src/index.css index 4dcdee9..1f15489 100644 --- a/src/index.css +++ b/src/index.css @@ -325,3 +325,8 @@ label { .cart-button .ant-badge-count { left: 0px !important; } + +.product-link-search .ant-card-body { + padding: 16px 16px 8px 16px !important; + box-shadow: none !important; +} diff --git a/src/pages/menu/components/MenuList/MenuList.module.css b/src/pages/menu/components/MenuList/MenuList.module.css index 5c3d421..ea3c16a 100644 --- a/src/pages/menu/components/MenuList/MenuList.module.css +++ b/src/pages/menu/components/MenuList/MenuList.module.css @@ -678,19 +678,22 @@ display: flex; height: 100%; width: 100%; + } - + .productLink .ant-card { height: 100%; display: flex; flex-direction: column; + justify-content: space-between; } - + .productLink .ant-card .ant-card-body { flex: 1; display: flex; flex-direction: column; justify-content: space-between; + } } diff --git a/src/pages/menu/components/MenuList/MenuList.tsx b/src/pages/menu/components/MenuList/MenuList.tsx index 64064df..96922ca 100644 --- a/src/pages/menu/components/MenuList/MenuList.tsx +++ b/src/pages/menu/components/MenuList/MenuList.tsx @@ -115,20 +115,19 @@ export function MenuList({ data, categoryRefs }: MenuListProps) { borderRadius: 8, overflow: "hide", width: "100%", + boxShadow: "none", }} styles={{ body: { display: "flex", flexDirection: "column", justifyContent: "space-between", - borderRadius: 8, padding: item.description ? "16px 16px 8px 16px" : "16px 16px 24px 16px", overflow: "hide", - boxShadow: - "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.05)", - }, + boxShadow: "none", + }, }} >
state.locale); - const { sm, md } = useBreakpoint(); - const isMobile = !sm; - const isTablet = sm && !md; - const { themeName } = useAppSelector((state) => state.theme); - const dispatch = useAppDispatch(); - const cartItems = useAppSelector(selectCartItems); - const getItemQuantity = (id: number | string) => { - const item = cartItems.find((i) => i.id === id); - return item ? item.quantity : 0; - }; - const { t } = useTranslation(); - - // Memoized handlers for better performance - const handleQuickAdd = useCallback( - (item: Product) => { - dispatch( - addItem({ - item: { - id: item.id, - name: item.name, - price: item.price, - image: item.image, - description: item.description, - variant: "None", - extras: [], - extrasgroup: [], - }, - quantity: 1, - }) - ); - }, - [dispatch] - ); - - const getMenuItemCardStyle = useCallback( - (itemDescription: string) => { - if (isMobile) { - return { - height: itemDescription?.length > 0 ? 160 : 130, - padding: "12px 12px 12px 16px", - }; - } else if (isTablet) { - return { - height: 160, - padding: "16px", - }; - } else { - return { - height: 180, - padding: "20px", - }; - } - }, - [isMobile, isTablet] - ); - - const getMenuItemImageStyle = useCallback(() => { - if (isMobile) { - return { - width: 90, - height: 95, - }; - } else if (isTablet) { - return { - width: 120, - height: 120, - }; - } else { - return { - width: 140, - height: 140, - }; - } - }, [isMobile, isTablet]); - - return ( - <> - {products?.map((item) => ( - - -
-
- - {locale == "ar" ? item.nameOther : item.name} - - - {item.description} - -
-
- - -
-
- - - {/* Cart quantity badge - shows current quantity in cart */} - {getItemQuantity(item.id) > 0 && ( - - )} -
-
-
- - ))} - - ); -} diff --git a/src/pages/menu/components/SearchMenu/SearchMenu.tsx b/src/pages/menu/components/SearchMenu/SearchMenu.tsx new file mode 100644 index 0000000..d69aeb1 --- /dev/null +++ b/src/pages/menu/components/SearchMenu/SearchMenu.tsx @@ -0,0 +1,207 @@ +import { Badge, Card } from "antd"; +import ArabicPrice from "components/ArabicPrice"; +import ImageWithFallback from "components/ImageWithFallback"; +import { ItemDescriptionIcons } from "components/ItemDescriptionIcons/ItemDescriptionIcons"; +import ProText from "components/ProText"; +import useBreakPoint from "hooks/useBreakPoint"; +import { AddToCartButton } from "pages/menu/components/AddToCartButton/AddToCartButton.tsx"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import { useAppSelector } from "redux/hooks"; +import { colors } from "ThemeConstants"; +import { Product } from "utils/types/appTypes"; +import styles from "../MenuList/MenuList.module.css"; + +interface MenuListProps { + products: Product[]; +} + +export function SearchMenu({ products }: MenuListProps) { + const { isRTL } = useAppSelector((state) => state.locale); + const { isMobile, isTablet } = useBreakPoint(); + const { items } = useAppSelector((state) => state.order); + const restaurantName = localStorage.getItem("restaurantName"); + const navigate = useNavigate(); + const { t } = useTranslation(); + const { themeName } = useAppSelector((state) => state.theme); + + // Show error state if data exists but has no products + if (products && (!products || products.length === 0)) { + return ( +
+ {t("menu.noMenuItemsAvailable")} +
+ ); + } + + return ( + <> +
+
+ {products.map((item: Product) => ( +
{ + localStorage.setItem("product", JSON.stringify(item)); + navigate(`/${restaurantName}/product/${item.id}`); + }} + > + +
+
+ + {isRTL ? item.name : item.nameOther} + + {item.description && ( + + {item.description} + + )} + +
+ {item.original_price !== item.price && ( + + )} + +
+ +
+ +
+
+
+ + + + + {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/search/page.tsx b/src/pages/search/page.tsx index 5152092..4c1f179 100644 --- a/src/pages/search/page.tsx +++ b/src/pages/search/page.tsx @@ -4,13 +4,15 @@ import SearchIcon from "components/Icons/SearchIcon"; import LoadingSpinner from "components/LoadingSpinner"; import ProHeader from "components/ProHeader/ProHeader"; import ProText from "components/ProText"; +import useBreakPoint from "hooks/useBreakPoint"; +import { CartButton } from "pages/menu/components/CartButton/CartButton"; +import { SearchMenu } from "pages/menu/components/SearchMenu/SearchMenu"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link, useParams, useSearchParams } from "react-router-dom"; import { useGetMenuQuery } from "redux/api/others"; import { useAppSelector } from "redux/hooks"; import { Product } from "utils/types/appTypes"; -import { ProductCard } from "../menu/components/ProductCard/ProductCard"; import styles from "./search.module.css"; export default function SearchPage() { @@ -22,6 +24,7 @@ export default function SearchPage() { const [searchResults, setSearchResults] = useState([]); const [isSearching, setIsSearching] = useState(false); const restaurantID = localStorage.getItem("restaurantID"); + const { isDesktop } = useBreakPoint(); const { data: menuData } = useGetMenuQuery(restaurantID as string, { skip: !restaurantID, @@ -52,7 +55,7 @@ export default function SearchPage() { setIsSearching(false); }, 300); }, - [menuData] + [menuData], ); // Handle input change and update search params @@ -67,7 +70,7 @@ export default function SearchPage() { setSearchParams({}); } }, - [setSearchParams] + [setSearchParams], ); // Debounced search effect @@ -93,7 +96,6 @@ export default function SearchPage() {
) : searchQuery && searchResults?.length > 0 ? ( - + ) : searchQuery && searchResults?.length === 0 && !isSearching ? (
@@ -169,29 +171,33 @@ export default function SearchPage() { ) : null}
- - - - - + {!isDesktop ? ( + + + + + + ) : ( + + )} ); }