Files
web-menu-react-version-/src/pages/menu/components/MenuList/MenuList.tsx
2026-01-14 18:53:09 +03:00

108 lines
3.3 KiB
TypeScript

import ProText from "components/ProText";
import ProTitle from "components/ProTitle";
import { useTranslation } from "react-i18next";
import { useAppSelector } from "redux/hooks";
import { Product } from "utils/types/appTypes";
import styles from "./MenuList.module.css";
import ProductCard from "pages/menu/components/MenuList/ProductCard.tsx";
import { ProductBottomSheet } from "pages/product/components/ProductBottomSheet";
import { useState } from "react";
import { Category } from "utils/types/appTypes";
interface MenuListProps {
data:
| {
products: Product[];
categories: { id: number; name: string; image?: string }[];
}
| undefined;
categoryRefs: React.RefObject<{ [key: number]: HTMLDivElement | null }>;
}
export function MenuList({ data, categoryRefs }: MenuListProps) {
const { isRTL } = useAppSelector((state) => state.locale);
const products = data?.products;
const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false);
const { t } = useTranslation();
const { themeName } = useAppSelector((state) => state.theme);
// Show error state if data exists but has no products
if (data && (!data.products || data.products.length === 0)) {
return (
<div
className={styles.menuSections}
style={{ padding: "40px", textAlign: "center" }}
>
<ProText type="secondary">{t("menu.noMenuItemsAvailable")}</ProText>
</div>
);
}
// Group products by category
const productsByCategory = products?.reduce(
(acc, product) => {
if (product.categoryId && !acc[product?.categoryId]) {
acc[product?.categoryId] = [];
}
acc[product?.categoryId || 0].push(product);
return acc;
},
{} as Record<number, Product[]>,
);
return (
<>
<div className={styles.menuSections}>
{data?.categories?.map((category: Category, index) => {
const categoryProducts = productsByCategory?.[category.id] || [];
if (categoryProducts.length === 0) return null;
return (
<div
key={category.id}
ref={(el) => {
if (categoryRefs.current) {
categoryRefs.current[category.id] = el;
}
}}
style={{ marginBottom: "2rem" }}
>
{index !== 0 && (
<ProTitle
style={{
fontWeight: 600,
fontStyle: "SemiBold",
fontSize: "16px",
lineHeight: "140%",
letterSpacing: "0%",
color: themeName === "dark" ? "#fff" : "#070707",
marginBottom: 16,
}}
level={5}
>
{isRTL ? category.nameAR : category.nameEN}
</ProTitle>
)}
<div className={styles.menuItemsGrid}>
{categoryProducts.map((item: Product) => (
<ProductCard
item={item}
key={item.id}
setIsBottomSheetOpen={setIsBottomSheetOpen}
/>
))}
</div>
</div>
);
})}
<ProductBottomSheet
isOpen={isBottomSheetOpen}
onClose={() => setIsBottomSheetOpen(false)}
/>
</div>
</>
);
}