نسخ من RaghadAlkhous/RestaurantDash
update the dashbord and router
هذا الالتزام موجود في:
260
src/components/Home/Dashboard/OrderStatusCard.js
Normal file
260
src/components/Home/Dashboard/OrderStatusCard.js
Normal file
@@ -0,0 +1,260 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Box,
|
||||
Typography,
|
||||
Card,
|
||||
CardContent,
|
||||
Divider,
|
||||
Chip,
|
||||
useTheme,
|
||||
IconButton,
|
||||
useMediaQuery
|
||||
} from '@mui/material';
|
||||
import {
|
||||
TrendingUp as TrendingUpIcon,
|
||||
TrendingDown as TrendingDownIcon,
|
||||
CheckCircle as CheckCircleIcon,
|
||||
Cancel as CancelIcon,
|
||||
Pending as PendingIcon
|
||||
} from '@mui/icons-material';
|
||||
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
||||
import {
|
||||
CircularProgressbar,
|
||||
buildStyles
|
||||
} from 'react-circular-progressbar';
|
||||
import 'react-circular-progressbar/dist/styles.css';
|
||||
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
||||
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
||||
// import { Box, IconButton, Paper, Typography, useTheme, useMediaQuery } from '@mui/material';
|
||||
import {
|
||||
|
||||
ResponsiveContainer,
|
||||
|
||||
} from 'recharts';
|
||||
|
||||
|
||||
const OrderStatusCard = ({
|
||||
title = 'Order Status',
|
||||
period = 'This Quarter',
|
||||
progress = 70.5,
|
||||
progressChange = '+10%',
|
||||
progressDirection = 'up', // or 'down'
|
||||
description = 'You succeeded in earning $240 today, it’s higher than yesterday',
|
||||
completed = '$20k',
|
||||
canceled = '$16k',
|
||||
pending = '$1.5k'
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const progressColor = progressDirection === 'up' ? theme.palette.success.main : theme.palette.error.main;
|
||||
const progressIcon = progressDirection === 'up' ? <TrendingUpIcon fontSize="small" /> : <TrendingDownIcon fontSize="small" />;
|
||||
const highlightedDescription = description.replace(
|
||||
/(\$\d+(?:\.\d+)?[kKmM]?)/g,
|
||||
'<span style="color:#000;font-weight:500;">$1</span>'
|
||||
);
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.between('sm', 'md'));
|
||||
|
||||
|
||||
return (
|
||||
<Card
|
||||
sx={{
|
||||
width: { xs: '96%', sm: '94%', md: 360 },
|
||||
height: 'auto',
|
||||
borderRadius: 2,
|
||||
boxShadow: '0px 4px 5px rgba(0, 0, 0, 0.1)',
|
||||
pl: { xs: 1, sm: 1 },
|
||||
pr: { xs: 1, sm: 1 },
|
||||
pb: { xs: 1, sm: 1 },
|
||||
pt: { xs: 0, sm: 0 },
|
||||
|
||||
position: 'relative' // إضافة هذه الخاصية
|
||||
}}
|
||||
>
|
||||
<ResponsiveContainer width="100%" height={isMobile ? '75vh' : isTablet ? '59vh' : 385}>
|
||||
{/* زر الإجراءات في الزاوية العلوية اليمنى */}
|
||||
<IconButton
|
||||
aria-label="more-actions"
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: 8,
|
||||
right: 8,
|
||||
color: '#667085'
|
||||
}}
|
||||
>
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
|
||||
<CardContent>
|
||||
{/* Header */}
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
ml: 0 // هامش يسار لإفساح المجال للأيقونة
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{
|
||||
fontSize: { xs: '16px', sm: '18px' },
|
||||
fontWeight: 500
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: { xs: '12px', sm: '14px' },
|
||||
fontWeight: 500,
|
||||
color: '#667085'
|
||||
}}
|
||||
>
|
||||
{period}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{/* Progress Circle */}
|
||||
<Box sx={{ height: 120, mb: 2, position: 'relative' }}>
|
||||
{/* تغيير النسبة تحت الدائرة */}
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: '80%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<Chip
|
||||
label={progressChange}
|
||||
size="small"
|
||||
icon={progressIcon}
|
||||
sx={{
|
||||
height: 22,
|
||||
fontSize: '0.75rem',
|
||||
color: progressDirection === 'up' ? '#087443' : '#B42318',
|
||||
backgroundColor: progressDirection === 'up' ? '#ECFDF3' : '#FEF3F2',
|
||||
'.MuiChip-icon': {
|
||||
color: progressDirection === 'up' ? '#087443' : '#B42318',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* دائرة التقدم */}
|
||||
<Box sx={{ position: 'relative', width: '100%', maxWidth: 250, mx: 'auto' }}>
|
||||
<CircularProgressbar
|
||||
value={100}
|
||||
circleRatio={0.5}
|
||||
strokeWidth={5}
|
||||
styles={buildStyles({
|
||||
rotation: 0.75,
|
||||
strokeLinecap: 'round',
|
||||
trailColor: '#eee',
|
||||
pathColor: '#eee',
|
||||
})}
|
||||
/>
|
||||
<Box sx={{ position: 'absolute', top: -1.5, left: 0, width: '100%', height: '100%' }}>
|
||||
<CircularProgressbar
|
||||
value={progress}
|
||||
circleRatio={0.5}
|
||||
strokeWidth={6}
|
||||
styles={buildStyles({
|
||||
rotation: 0.75,
|
||||
strokeLinecap: 'round',
|
||||
trailColor: 'transparent',
|
||||
pathColor: theme.palette.primary.main,
|
||||
textColor: 'transparent',
|
||||
})}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* النص داخل الدائرة */}
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: '22%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
fontSize: { xs: '18px', sm: '24px' },
|
||||
fontWeight: 500,
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
>
|
||||
{`${progress}%`}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* الوصف */}
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{
|
||||
mb: 1,
|
||||
mt: 5,
|
||||
color: '#667085',
|
||||
fontSize: { xs: '14px', sm: '16px' },
|
||||
}}
|
||||
dangerouslySetInnerHTML={{ __html: highlightedDescription }}
|
||||
/>
|
||||
|
||||
<Divider sx={{ my: 2 }} />
|
||||
|
||||
{/* الحقول الثلاثة (Completed / Canceled / Pending) */}
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
gap: { xs: 1, sm: 2 },
|
||||
flexDirection: { xs: 'column', sm: 'row' },
|
||||
ml: -1
|
||||
}}
|
||||
>
|
||||
{/* لكل قسم: */}
|
||||
{[{
|
||||
label: 'Completed',
|
||||
icon: <ArrowUpwardIcon color="success" fontSize="small" sx={{ mt: 0.2, ml: -1 }} />,
|
||||
value: completed
|
||||
}, {
|
||||
label: 'Canceled',
|
||||
icon: <ArrowDownwardIcon color="error" fontSize="small" sx={{ mt: 0.6, ml: -1 }} />,
|
||||
value: canceled
|
||||
}, {
|
||||
label: 'Pending',
|
||||
icon: <ArrowDownwardIcon color="warning" fontSize="small" sx={{ mt: 0.6, ml: -1 }} />,
|
||||
value: pending
|
||||
}].map(({ label, icon, value }, i) => (
|
||||
<Box
|
||||
key={i}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
mb: { xs: 1, sm: 0 }
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{ color: '#667085', fontSize: '12px', fontWeight: 500, mb: 1 }}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
|
||||
{icon}
|
||||
<Typography sx={{ color: '#333843', fontSize: { xs: '14px', sm: '16px',md:'24px'}, fontWeight: 500 }}>
|
||||
{value}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</CardContent>
|
||||
</ResponsiveContainer>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrderStatusCard;
|
||||
المرجع في مشكلة جديدة
حظر مستخدم