initial commit

This commit is contained in:
RaghadAlkhous
2026-05-06 15:08:57 +03:00
commit 1ccca905f3
215 changed files with 61375 additions and 0 deletions
+326
View File
@@ -0,0 +1,326 @@
import React, { useState, useEffect } from 'react';
import {
useMediaQuery,
Box,
Typography,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
IconButton,
Skeleton,
CircularProgress,
Button
} from '@mui/material';
import { useTheme } from '@mui/material/styles';
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import authService from '../../../../services/authService';
import CartDetails from './OrderDetails';
import CartView from './CartView';
const SimplePagination = ({ currentPage, pageCount, onChange }) => {
const theme = useTheme();
const handlePrev = () => { if (currentPage > 1) onChange(currentPage - 1); };
const handleNext = () => { if (currentPage < pageCount) onChange(currentPage + 1); };
return (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<IconButton
size="small"
onClick={handlePrev}
disabled={currentPage <= 1}
sx={{
borderRadius: '8px',
backgroundColor: '#FFECE0',
'&:hover': { backgroundColor: '#FFD6B5' },
color: theme.palette.primary.main,
'&.Mui-disabled': { color: '#ccc', backgroundColor: '#FFF5E6' },
}}
>
<ArrowBackIosNewIcon fontSize="small" />
</IconButton>
<Box
sx={{
width: 32,
height: 32,
borderRadius: '8px',
backgroundColor: theme.palette.primary.main,
color: '#fff',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 600,
fontSize: 14,
userSelect: 'none',
boxShadow: `0 0 0 1px ${theme.palette.primary.main}`,
}}
>
{currentPage}
</Box>
<IconButton
size="small"
onClick={handleNext}
disabled={currentPage >= pageCount}
sx={{
borderRadius: '8px',
backgroundColor: '#FFECE0',
'&:hover': { backgroundColor: '#FFD6B5' },
color: theme.palette.primary.main,
'&.Mui-disabled': { color: '#ccc', backgroundColor: '#FFF5E6' },
}}
>
<ArrowForwardIosIcon fontSize="small" />
</IconButton>
</Box>
);
};
const Orders = ({ adminId }) => {
useEffect(() => {
console.log('Admin ID from props:', adminId);
}, [adminId]);
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const [ordersData, setOrdersData] = useState([]);
const [loading, setLoading] = useState(true);
const [selectedCart, setSelectedCart] = useState(null);
const [cartLoading, setCartLoading] = useState(false);
const [showCartView, setShowCartView] = useState(false); // ← التحكم بعرض CartView هنا
const [currentPage, setCurrentPage] = useState(1);
const itemsPerPage = 6;
const [orders, setOrders] = useState([]);
const handleAddOrder = (newOrder) => {
setOrders((prevOrders) => [...prevOrders, newOrder]);
};
useEffect(() => {
const fetchOrders = async () => {
setLoading(true);
try {
const result = await authService.getCart();
if (result.success) {
setOrdersData(Array.isArray(result.data) ? result.data : []);
} else {
console.error(result.message);
setOrdersData([]);
}
} catch (error) {
console.error('Failed to fetch orders:', error);
setOrdersData([]);
}
setLoading(false);
};
fetchOrders();
}, []);
const handleRowClick = async (cartId) => {
setCartLoading(true);
try {
const result = await authService.getCartById(cartId);
if (result.success) setSelectedCart(result.data);
else console.error(result.message);
} catch (error) {
console.error('Failed to fetch cart details:', error);
}
setCartLoading(false);
};
const handleCartUpdated = (updatedCart) => {
setOrdersData(prev =>
prev.map(cart => cart.id === updatedCart.id ? updatedCart : cart)
);
setSelectedCart(null);
};
const handleCloseCartDetails = () => { setSelectedCart(null); };
const pageCount = Math.ceil(ordersData.length / itemsPerPage);
const paginatedOrders = ordersData.slice(
(currentPage - 1) * itemsPerPage,
currentPage * itemsPerPage
);
if (cartLoading) {
return (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 4 }}>
<CircularProgress />
</Box>
);
}
if (selectedCart) {
return (
<CartDetails
cart={selectedCart}
onClose={handleCloseCartDetails}
onUpdated={handleCartUpdated}
/>
);
}
// عرض CartView بدل الطلبات إذا تم الضغط على الزر
// داخل Orders.js
if (showCartView) {
return (
<CartView
onClose={() => setShowCartView(false)}
onSend={handleAddOrder}
onCartCreated={(newCart) => {
setOrdersData(prev => [newCart, ...prev]); // ضف الكارت الجديد مباشرة
setShowCartView(false);
}}
adminId={adminId} // ← أرسل الـ adminId هنا
/>
);
}
return (
<Box
sx={{
width: { xs: '100%', sm: '93.5%' },
p: { xs: 2, sm: 3 },
backgroundColor: 'white',
borderRadius: 2,
}}
>
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
justifyContent: 'space-between',
alignItems: { xs: 'stretch', sm: 'center' },
mb: 2,
gap: { xs: 1, sm: 0 },
}}
>
<Typography
variant="h5"
sx={{
fontWeight: 600,
fontSize: { xs: '18px', sm: '20px' },
mb: { xs: 1, sm: 0 },
textAlign: { xs: 'center', sm: 'left' },
}}
>
Order
</Typography>
</Box>
{/* جدول الطلبات */}
<TableContainer
component={Paper}
sx={{
boxShadow: 'none',
border: '1px solid #e0e0e0',
borderRadius: 2,
minWidth: 320,
height: '380px',
}}
>
<Table
sx={{ minWidth: { sm: 550, md: 650 }, tableLayout: 'auto' }}
aria-label="orders table"
size={isMobile ? 'small' : 'medium'}
>
<TableHead sx={{ backgroundColor: '#f5f5f5', color: '#61677F' }}>
<TableRow sx={{ '& th': { borderBottom: 'none' } }}>
<TableCell sx={{ fontWeight: 500, fontSize: '16px', color: '#61677F' }}>Cart ID</TableCell>
<TableCell sx={{ fontWeight: 500, fontSize: '16px', color: '#61677F' }}>Total Price</TableCell>
<TableCell sx={{ fontWeight: 500, fontSize: '16px', color: '#61677F' }}>Created At</TableCell>
<TableCell sx={{ fontWeight: 500, fontSize: '16px', color: '#61677F' }}>Items Count</TableCell>
</TableRow>
</TableHead>
<TableBody>
{loading
? Array.from({ length: itemsPerPage }).map((_, idx) => (
<TableRow key={`skeleton-${idx}`}>
<TableCell><Skeleton variant="text" /></TableCell>
<TableCell><Skeleton variant="text" /></TableCell>
<TableCell><Skeleton variant="text" /></TableCell>
<TableCell><Skeleton variant="text" /></TableCell>
</TableRow>
))
: (
<>
{paginatedOrders.map(order => {
const attributes = order?.attributes || {};
const relationships = order?.relationships || {};
const cartItems = relationships?.cartItems || relationships?.cart_items || [];
return (
<TableRow
key={order?.id}
hover
sx={{
cursor: 'pointer',
transition: 'background-color 0.3s',
'&:hover': {
backgroundColor: '#ffe4d0ff !important',
'& td': { color: '#000000ff' },
},
}}
onClick={() => handleRowClick(order.id)}
>
<TableCell>{order?.id || '--'}</TableCell>
<TableCell>{attributes?.totalPrice ?? attributes?.total_price ?? '0.00'}</TableCell>
<TableCell>{attributes?.createdAt ? new Date(attributes.createdAt).toLocaleString() : '--'}</TableCell>
<TableCell>{cartItems.length}</TableCell>
</TableRow>
);
})}
{paginatedOrders.length < itemsPerPage &&
Array.from({ length: itemsPerPage - paginatedOrders.length }).map((_, idx) => (
<TableRow key={`empty-${idx}`} sx={{ height: 53 }}>
<TableCell colSpan={4} sx={{ borderBottom: 'none' }} />
</TableRow>
))
}
</>
)
}
</TableBody>
</Table>
</TableContainer>
<Box
display="flex"
justifyContent="space-between"
alignItems="center"
pt={{ xs: 1, sm: 2 }}
sx={{
position: 'sticky',
bottom: 0,
backgroundColor: theme.palette.background.paper,
borderTop: '1px solid #f0f0f0',
}}
>
<Typography
variant="body2"
color="text.secondary"
sx={{ fontSize: { xs: '11px', sm: '14px' }, whiteSpace: 'nowrap' }}
>
Showing {(currentPage - 1) * itemsPerPage + 1} - {Math.min(currentPage * itemsPerPage, ordersData.length)} of {ordersData.length}
</Typography>
<SimplePagination currentPage={currentPage} pageCount={pageCount} onChange={setCurrentPage} />
</Box>
</Box>
);
};
export default Orders;