Files
RestaurantDash/src/components/Home/Meal/contect/MealsByCateg.js
T

203 lines
6.5 KiB
JavaScript

import React, { useState, useEffect, useCallback } from "react";
import { Box, Typography, Skeleton, useTheme, Button } from "@mui/material";
import MealCard from "./MealCard";
import authService from "../../../../services/authService";
import AddMeal from "./AddMeal";
import SimplePagination from "../../SimplePagination";
const MealsByCateg = ({
restaurantId,
categoryId,
onProductClick,
onAddMeal,
categoryName,
onBack,
}) => {
const theme = useTheme();
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [openModal, setOpenModal] = useState(false);
const [page, setPage] = useState(1);
const [pagination, setPagination] = useState(null);
const itemsPerPage = 6;
// استخدام useCallback لمنع إنشاء الدالة عند كل إعادة render
const fetchMeals = useCallback(async () => {
if (!restaurantId || !categoryId) return;
setLoading(true);
setError(null);
try {
const result = await authService.getMealsByCategory(
restaurantId,
categoryId,
page
);
if (result.success) {
const mealsWithImages = result.data.map((meal) => ({
id: meal.id,
name: meal.name,
price: meal.price,
description: meal.description || [],
additions: meal.additions || [],
unit: meal.unit || "/pcs",
photo: meal.photo || "/images/default-product.png",
category_id: meal.category_id || categoryId,
}));
setProducts(mealsWithImages);
setPagination(result.pagination);
} else {
setProducts([]);
setPagination(null);
}
} catch (err) {
console.error(err);
setError("Failed to fetch meals.");
setProducts([]);
setPagination(null);
} finally {
setLoading(false);
}
}, [restaurantId, categoryId, page]);
// جلب البيانات عند تغيير restaurantId أو categoryId أو page
useEffect(() => {
fetchMeals();
}, [fetchMeals]);
// إضافة وجبة جديدة وتحديث القائمة فورًا
// في MealsByCateg
const handleAddProduct = async (meal) => {
setOpenModal(false); // اغلاق مودال الإضافة
setPage(1); // العودة للصفحة الأولى
const result = await fetchMeals(); // جلب الوجبات بعد الإضافة
if (onAddMeal) onAddMeal(meal); // تمرير الوجبة للمكون الأب
};
return (
<Box
sx={{
mb: 2,
pl: { xs: 2, sm: 3 },
pr: { xs: 2, sm: 3 },
pb: { xs: 2, sm: 3 },
pt: { xs: 2, sm: 1.5 },
maxWidth: { xs: "90%", md: "100%" },
backgroundColor: "#FFFFFF",
borderRadius: "10px",
padding: "20px",
display: "flex",
flexDirection: "column",
gap: "20px",
overflowY: "auto",
}}
>
{/* العنوان + أزرار */}
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<Typography variant="h6" fontWeight={600}>
{categoryName || "Meals"}
</Typography>
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
<Button
onClick={() => setOpenModal(true)}
sx={{
textTransform: "none",
color: "#fff",
backgroundColor: theme.palette.primary.main,
borderRadius: "8px",
height: "40px",
width: { xs: "100%", sm: "130px", md: "150px" },
fontWeight: 700,
}}
>
Add Product
</Button>
<Button variant="text" color="primary" sx={{ ml: 1 }} onClick={onBack}>
Back
</Button>
</Box>
</Box>
{/* حالة التحميل أو الخطأ */}
{loading ? (
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 2 }}>
{Array.from({ length: itemsPerPage }).map((_, index) => (
<Box key={index} sx={{ flex: "1 1 calc(33.33% - 16px)" }}>
<Skeleton variant="rectangular" width="100%" height={180} sx={{ borderRadius: 2 }} />
<Skeleton variant="text" width="80%" sx={{ mt: 1 }} />
<Skeleton variant="text" width="40%" />
</Box>
))}
</Box>
) : error ? (
<Box sx={{ display: "flex", justifyContent: "center", mt: 4 }}>
<Typography variant="body1" color="error">{error}</Typography>
</Box>
) : products.length === 0 ? (
<Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", minHeight: "150px" }}>
<Typography variant="body1" color="text.secondary">
There is no meal available
</Typography>
</Box>
) : (
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 2 }}>
{products.map((product) => (
<Box
key={product.id}
onClick={() =>
onProductClick({
...product,
category: categoryName,
category_id: categoryId,
})
}
>
<MealCard
meal={product}
onClick={() =>
onProductClick({
...product,
category: categoryName,
category_id: categoryId,
})
}
onAdd={onAddMeal}
/>
</Box>
))}
</Box>
)}
{/* Pagination Footer */}
{pagination && !loading && pagination.last_page > 1 && (
<Box display="flex" justifyContent="space-between" alignItems="center" mt={2} sx={{ borderTop: "1px solid #f0f0f0", pt: 2 }}>
<Typography variant="body2" color="text.secondary">
Showing {(page - 1) * itemsPerPage + 1} to{" "}
{Math.min(page * itemsPerPage, pagination.total)} of {pagination.total} meals
</Typography>
<SimplePagination
currentPage={page}
pageCount={pagination.last_page}
onChange={(newPage) => setPage(newPage)}
/>
</Box>
)}
{/* Add Meal Modal */}
<AddMeal
open={openModal}
onClose={() => setOpenModal(false)}
onAdd={handleAddProduct}
selectedCategory={categoryId}
restaurantId={restaurantId}
/>
</Box>
);
};
export default MealsByCateg;