diff --git a/src/pages/menu/components/MenuList/MenuList.module.css b/src/pages/menu/components/MenuList/MenuList.module.css index d93a39a..79e2007 100644 --- a/src/pages/menu/components/MenuList/MenuList.module.css +++ b/src/pages/menu/components/MenuList/MenuList.module.css @@ -25,11 +25,11 @@ } .menuSection:first-child h3 { - margin-top: 0px !important; + margin-top: 0 !important; } .menuSection h3 { - margin: 30px 0px 15px 0px; + margin: 30px 0 15px 0; transition: color 0.3s ease; } @@ -42,7 +42,7 @@ /* Enhanced responsive menu section headers */ @media (min-width: 769px) and (max-width: 1024px) { .menuSection h3 { - margin: 40px 0px 20px 0px; + margin: 40px 0 20px 0; font-size: 24px; } @@ -59,7 +59,7 @@ } .menuSection h3 { - margin: 50px 0px 25px 0px; + margin: 50px 0 25px 0; font-size: 28px; } @@ -97,32 +97,6 @@ display: none; } -.popularMenuItemImage { - width: 90px; - height: 90px; - object-fit: cover; - border-radius: 8px; - transition: transform 0.3s ease; - overflow: hidden; -} - -.popularMenuItemImageMobile { - height: 90px; - overflow: hidden; -} - -.popularMenuItemImageTablet { - height: 95px; - width: 120px; - overflow: hidden; -} - -.popularMenuItemImageDesktop { - height: 120px; - width: 140px; - overflow: hidden; -} - .menuItemImage { object-fit: cover; border-radius: 8px; @@ -154,24 +128,6 @@ gap: 8px; } -.itemDescription { - /* font-size: 12px !important; */ - transition: color 0.3s ease; -} - -/* Enhanced responsive item descriptions */ -@media (min-width: 769px) and (max-width: 1024px) { - .itemDescription { - font-size: 14px !important; - } -} - -@media (min-width: 1025px) { - .itemDescription { - font-size: 16px !important; - } -} - /* Responsive adjustments */ @media (max-width: 768px) { .container { @@ -214,10 +170,6 @@ margin-left: 200px; } -/* .itemDescriptionIcons path { - fill: 000044 !important; -} */ - @media (max-width: 768px) { .sidebarCollapsed .pageContainer, .sidebarExpanded .pageContainer { @@ -308,28 +260,6 @@ } } -@keyframes imageEntrance { - 0% { - transform: scale(0.9) rotate(-2deg); - opacity: 0.7; - } - 100% { - transform: scale(1) rotate(0deg); - opacity: 1; - } -} - -@keyframes imageReturn { - 0% { - transform: scale(0.95) rotate(-1deg); - opacity: 0.85; - } - 100% { - transform: scale(1) rotate(0deg); - opacity: 1; - } -} - @keyframes cardEntrance { 0% { transform: translateY(20px) scale(0.95); @@ -352,167 +282,6 @@ } } -@keyframes glowPulse { - 0%, - 100% { - opacity: 0.3; - transform: scaleX(0.8); - } - 50% { - opacity: 0.6; - transform: scaleX(1); - } -} - -@keyframes glowFadeOut { - 0% { - opacity: 0.1; - transform: scaleX(1); - } - 100% { - opacity: 0; - transform: scaleX(0.8); - } -} - -@keyframes slideDown { - 0% { - transform: translateY(-100%) scale(0.95); - opacity: 0; - filter: blur(10px); - } - 50% { - transform: translateY(-20%) scale(0.98); - opacity: 0.7; - filter: blur(5px); - } - 100% { - transform: translateY(0) scale(1); - opacity: 1; - filter: blur(0); - } -} - -@keyframes slideUp { - 0% { - transform: translateY(-10px) scale(0.98); - opacity: 0.9; - filter: blur(2px); - } - 50% { - transform: translateY(-5px) scale(0.99); - opacity: 0.95; - filter: blur(1px); - } - 100% { - transform: translateY(0) scale(1); - opacity: 1; - filter: blur(0); - } -} - -@keyframes darkGlowPulse { - 0%, - 100% { - opacity: 0.4; - transform: scaleX(0.8); - } - 50% { - opacity: 0.7; - transform: scaleX(1); - } -} - -@keyframes darkGlowFadeOut { - 0% { - opacity: 0.2; - transform: scaleX(1); - } - 100% { - opacity: 0; - transform: scaleX(0.8); - } -} - -/* Enhanced dark theme for menu item images */ -:global(.darkApp) .menuItemImage, -:global(.darkApp) .popularMenuItemImage { - border-color: rgba(255, 255, 255, 0.1); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); -} - -/* Enhanced dark theme for add to cart buttons */ -:global(.darkApp) .addToCartButton { - background-color: var(--primary) !important; - border-color: var(--primary) !important; - color: #000000 !important; - font-weight: 600; - transition: all 0.3s ease; -} - -:global(.darkApp) .addToCartButton:hover { - background-color: #ffd633 !important; - border-color: #ffd633 !important; - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(255, 198, 0, 0.3); -} - -/* Enhanced dark theme for quantity controls */ -:global(.darkApp) .quantityControl { - background-color: rgba(42, 42, 42, 0.8); - border-color: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(8px); -} - -:global(.darkApp) .quantityButton { - background-color: rgba(54, 54, 54, 0.8) !important; - border-color: rgba(255, 255, 255, 0.1) !important; - color: #ffffff !important; - transition: all 0.3s ease; -} - -:global(.darkApp) .quantityButton:hover { - background-color: rgba(66, 66, 66, 0.9) !important; - border-color: var(--primary) !important; -} - -:global(.darkApp) .quantityInput { - background-color: rgba(42, 42, 42, 0.8) !important; - border-color: rgba(255, 255, 255, 0.1) !important; - color: #ffffff !important; - text-align: center; -} - -/* Enhanced dark theme for container backgrounds */ -:global(.darkApp) .container { - background-color: #0a0a0a !important; - border-bottom-color: #363636 !important; -} - -:global(.darkApp) .itemDescriptionIcons path { - fill: #ffffff; -} - -/* Animation for newly added items */ -@keyframes badgePulse { - 0% { - transform: scale(1); - } - 50% { - transform: scale(1.2); - } - 100% { - transform: scale(1); - } -} - - -/* Enhanced dark theme animations */ -:global(.darkApp) .menuItem, -:global(.darkApp) .popularMenuItem { - animation: fadeInUp 0.3s ease-out; -} - @keyframes fadeInUp { from { opacity: 0; @@ -524,6 +293,12 @@ } } +/* Enhanced dark theme animations */ +:global(.darkApp) .menuItem, +:global(.darkApp) .popularMenuItem { + animation: fadeInUp 0.3s ease-out; +} + /* Smooth transitions for all elements */ .container *, .menuItem *, @@ -601,47 +376,10 @@ height: 60; } -.loyaltyButton { - position: absolute; - top: 1px; - left: 1px; - z-index: 99; - background-color: var(--primary) !important; - color: white !important; - border: none !important; -} - -:global(.ant-app-rtl) .loyaltyButton { - right: 1px !important; -} - -.productLink { - border-radius: 8px; -} - -/* Desktop unified height styles */ -@media (min-width: 1025px) { - .productLink { - 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; - - } +/* Enhanced dark theme for container backgrounds */ +:global(.darkApp) .container { + background-color: #0a0a0a !important; + border-bottom-color: #363636 !important; } .categoryMenuItemImage { @@ -649,6 +387,5 @@ object-fit: cover; border-radius: 8px; text-align: center; - width: 100%; overflow: hidden; } diff --git a/src/pages/menu/components/MenuList/MenuList.tsx b/src/pages/menu/components/MenuList/MenuList.tsx index 31c7710..b050172 100644 --- a/src/pages/menu/components/MenuList/MenuList.tsx +++ b/src/pages/menu/components/MenuList/MenuList.tsx @@ -1,20 +1,11 @@ -import { StarOutlined } from "@ant-design/icons"; -import { Badge, Button, 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 ProTitle from "components/ProTitle"; -import useBreakPoint from "hooks/useBreakPoint"; -import { AddToCartButton } from "pages/menu/components/AddToCartButton/AddToCartButton.tsx"; -import { ProductPreviewDialog } from "pages/menu/components/ProductPreviewDialog"; -import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { useNavigate, useParams } from "react-router-dom"; + import { useAppSelector } from "redux/hooks"; -import { colors } from "ThemeConstants"; import { Product } from "utils/types/appTypes"; import styles from "./MenuList.module.css"; +import ProductCard from "pages/menu/components/MenuList/ProductCard.tsx"; interface MenuListProps { data: @@ -29,31 +20,10 @@ interface MenuListProps { export function MenuList({ data, categoryRefs }: MenuListProps) { const { isRTL } = useAppSelector((state) => state.locale); const products = data?.products; - const { isMobile, isTablet, isDesktop } = useBreakPoint(); - const { items } = useAppSelector((state) => state.order); - const { subdomain } = useParams(); - const navigate = useNavigate(); + const { t } = useTranslation(); const { themeName } = useAppSelector((state) => state.theme); - // Dialog state - const [isDialogOpen, setIsDialogOpen] = useState(false); - - // Handle product click - open dialog on desktop, navigate on mobile/tablet - const handleProductClick = (item: Product) => { - localStorage.setItem("product", JSON.stringify(item)); - if (isDesktop) { - setIsDialogOpen(true); - } else { - navigate(`/${subdomain}/product/${item.id}`); - } - }; - - // Handle dialog close - const handleDialogClose = () => { - setIsDialogOpen(false); - }; - // Show error state if data exists but has no products if (data && (!data.products || data.products.length === 0)) { return ( @@ -107,176 +77,13 @@ export function MenuList({ data, categoryRefs }: MenuListProps) {
{categoryProducts.map((item: Product) => ( -
handleProductClick(item)} - > - -
-
- - {isRTL ? item.name : item.nameOther} - - {item.description && ( - - {item.description} - - )} - -
- {item.original_price !== item.price && ( - - )} - -
- -
- -
-
-
- {item.isHasLoyalty && ( -
-
-
-
+ ))}
); })} - - {/* Product Preview Dialog for Desktop */} - ); } diff --git a/src/pages/menu/components/MenuList/ProductCard.module.css b/src/pages/menu/components/MenuList/ProductCard.module.css new file mode 100644 index 0000000..bb04827 --- /dev/null +++ b/src/pages/menu/components/MenuList/ProductCard.module.css @@ -0,0 +1,87 @@ +.productLink { + border-radius: 8px; +} + +/* Desktop unified height styles */ +@media (min-width: 1025px) { + .productLink { + 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; + } +} + +.itemDescription { + transition: color 0.3s ease; +} + +/* Enhanced responsive item descriptions */ +@media (min-width: 769px) and (max-width: 1024px) { + .itemDescription { + font-size: 14px !important; + } +} + +@media (min-width: 1025px) { + .itemDescription { + font-size: 16px !important; + } +} + +.popularMenuItemImage { + width: 90px; + height: 90px; + object-fit: cover; + border-radius: 8px; + transition: transform 0.3s ease; + overflow: hidden; +} + +.popularMenuItemImageMobile { + height: 90px; + overflow: hidden; +} + +.popularMenuItemImageTablet { + height: 95px; + width: 120px; + overflow: hidden; +} + +.popularMenuItemImageDesktop { + height: 120px; + width: 140px; + overflow: hidden; +} + +.loyaltyButton { + position: absolute; + top: 1px; + left: 1px; + z-index: 99; + background-color: var(--primary) !important; + color: white !important; + border: none !important; +} + +:global(.ant-app-rtl) .loyaltyButton { + right: 1px !important; +} + +.itemDescriptionIcons svg { + fill: inherit; +} \ No newline at end of file diff --git a/src/pages/menu/components/MenuList/ProductCard.tsx b/src/pages/menu/components/MenuList/ProductCard.tsx new file mode 100644 index 0000000..46134d0 --- /dev/null +++ b/src/pages/menu/components/MenuList/ProductCard.tsx @@ -0,0 +1,209 @@ +import styles from "pages/menu/components/MenuList/ProductCard.module.css"; +import { Card, Button, Badge } from "antd"; +import ProText from "components/ProText.tsx"; +import ArabicPrice from "components/ArabicPrice"; +import { colors } from "ThemeConstants.ts"; +import { ItemDescriptionIcons } from "components/ItemDescriptionIcons/ItemDescriptionIcons.tsx"; +import { StarOutlined } from "@ant-design/icons"; +import ImageWithFallback from "components/ImageWithFallback"; +import { AddToCartButton } from "pages/menu/components/AddToCartButton/AddToCartButton.tsx"; +import { Product } from "utils/types/appTypes.ts"; +import useBreakPoint from "hooks/useBreakPoint.ts"; +import { useAppSelector } from "redux/hooks.ts"; +import { useParams, useNavigate } from "react-router-dom"; +import { ProductPreviewDialog } from "pages/menu/components/ProductPreviewDialog"; +import { useState } from "react"; + +type Props = { + item: Product; +}; +export default function ProductCard({ item }: Props) { + const { isRTL } = useAppSelector((state) => state.locale); + const { themeName } = useAppSelector((state) => state.theme); + const { isMobile, isTablet, isDesktop } = useBreakPoint(); + const { items } = useAppSelector((state) => state.order); + const { subdomain } = useParams(); + const navigate = useNavigate(); + // Dialog state + const [isDialogOpen, setIsDialogOpen] = useState(false); + + // Handle dialog close + const handleDialogClose = () => { + setIsDialogOpen(false); + }; + + // Handle product click - open dialog on desktop, navigate on mobile/tablet + const handleProductClick = (item: Product) => { + localStorage.setItem("product", JSON.stringify(item)); + if (isDesktop) { + setIsDialogOpen(true); + } else { + navigate(`/${subdomain}/product/${item.id}`); + } + }; + return ( + <> +
handleProductClick(item)} + > + +
+
+ + {isRTL ? item.name : item.nameOther} + + {item.description && ( + + {item.description} + + )} + +
+ {item.original_price !== item.price && ( + + )} + +
+ +
+ +
+
+
+ {item.isHasLoyalty && ( +
+
+
+
+ + {/* Product Preview Dialog for Desktop */} + {isDialogOpen && ( + + )} + + ); +}