242 lines
7.4 KiB
JavaScript
242 lines
7.4 KiB
JavaScript
import React, { useState } from 'react';
|
||
import {
|
||
Box,
|
||
Typography,
|
||
Card,
|
||
CardContent,
|
||
useTheme,
|
||
IconButton,
|
||
useMediaQuery,
|
||
Menu,
|
||
MenuItem,
|
||
Button,
|
||
ButtonGroup,
|
||
TextField
|
||
} from '@mui/material';
|
||
import {
|
||
TrendingUp as TrendingUpIcon,
|
||
TrendingDown as TrendingDownIcon,
|
||
} 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 { ResponsiveContainer } from 'recharts';
|
||
import dayjs from 'dayjs';
|
||
|
||
const OrderStatusCard = ({
|
||
title = 'Order Status',
|
||
period = 'This Quarter',
|
||
progress = 70.5,
|
||
description = 'You succeeded in earning $240 today, it’s higher than yesterday',
|
||
timeFrame,
|
||
setTimeFrame,
|
||
customDate,
|
||
setCustomDate
|
||
}) => {
|
||
const theme = useTheme();
|
||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||
const isTablet = useMediaQuery(theme.breakpoints.between('sm', 'md'));
|
||
const [anchorEl, setAnchorEl] = useState(null);
|
||
|
||
const open = Boolean(anchorEl);
|
||
const handleMenuOpen = (event) => {
|
||
setAnchorEl(event.currentTarget);
|
||
};
|
||
const handleMenuClose = () => {
|
||
setAnchorEl(null);
|
||
};
|
||
|
||
return (
|
||
<Card
|
||
sx={{
|
||
width: { xs: '96%', sm: '94%', md: 360 },
|
||
height: '400',
|
||
borderRadius: 2,
|
||
boxShadow: '0px 4px 5px rgba(0, 0, 0, 0.1)',
|
||
p: 1,
|
||
position: 'relative'
|
||
}}
|
||
>
|
||
<ResponsiveContainer width="100%" height={isMobile ? '75vh' : isTablet ? '59vh' : 385}>
|
||
|
||
{/* زر القائمة العلوية */}
|
||
<IconButton
|
||
aria-label="more-actions"
|
||
onClick={handleMenuOpen}
|
||
sx={{
|
||
position: 'absolute',
|
||
top: 8,
|
||
right: 8,
|
||
color: '#667085'
|
||
}}
|
||
>
|
||
<MoreVertIcon />
|
||
</IconButton>
|
||
|
||
{/* القائمة المنسدلة */}
|
||
<Menu
|
||
anchorEl={anchorEl}
|
||
open={open}
|
||
onClose={handleMenuClose}
|
||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||
>
|
||
<Box sx={{ p: 2, minWidth: 250 }}>
|
||
{/* Header Buttons (Timeframe) */}
|
||
<ButtonGroup
|
||
size="small"
|
||
variant="outlined"
|
||
sx={{
|
||
backgroundColor: '#ffffff',
|
||
borderRadius: '8px',
|
||
boxShadow: 'inset 0 0 0 1px #e0e0e0',
|
||
mb: 2,
|
||
width: '100%',
|
||
'& .MuiButton-root': {
|
||
textTransform: 'none',
|
||
fontSize: '13px',
|
||
padding: '6px 12px',
|
||
border: 'none',
|
||
borderRadius: '8px',
|
||
color: '#555',
|
||
'&:hover': { backgroundColor: '#f5f5f5' }
|
||
},
|
||
'& .MuiButton-contained': {
|
||
backgroundColor: 'rgba(255, 117, 34, 0.08)',
|
||
color: '#ff5722',
|
||
fontWeight: 'bold'
|
||
}
|
||
}}
|
||
>
|
||
{[{ label: '12 Months', value: '12m' }, { label: '30 Days', value: '30d' }, { label: '24 Hours', value: '24h' }].map(({ label, value }) => (
|
||
<Button
|
||
key={value}
|
||
variant={timeFrame === value ? 'contained' : 'text'}
|
||
onClick={() => { setTimeFrame(value); handleMenuClose(); }}
|
||
>
|
||
{label}
|
||
</Button>
|
||
))}
|
||
</ButtonGroup>
|
||
|
||
{/* Date Picker + Today Button */}
|
||
<Box
|
||
display="flex"
|
||
gap={1}
|
||
alignItems="center"
|
||
sx={{
|
||
backgroundColor: theme.palette.background.paper,
|
||
borderRadius: 2,
|
||
p: '4px 8px',
|
||
boxShadow: 'inset 0 0 0 1px #e0e0e0'
|
||
}}
|
||
>
|
||
<TextField
|
||
type="date"
|
||
value={customDate}
|
||
onChange={(e) => setCustomDate(e.target.value)}
|
||
size="small"
|
||
sx={{
|
||
width: isMobile ? '100%' : 150,
|
||
'& .MuiInputBase-input': { fontSize: isMobile ? 12 : 13, padding: '6px 8px' },
|
||
'& .MuiOutlinedInput-notchedOutline': { border: 'none' }
|
||
}}
|
||
/>
|
||
<Button
|
||
variant="contained"
|
||
size="small"
|
||
onClick={() => setCustomDate(dayjs().format('YYYY-MM-DD'))}
|
||
sx={{
|
||
backgroundColor: 'rgba(255, 117, 34, 0.08)',
|
||
color: '#ff5722',
|
||
textTransform: 'none',
|
||
boxShadow: 'none',
|
||
fontSize: isMobile ? 12 : 13,
|
||
'&:hover': { backgroundColor: 'rgba(255, 117, 34, 0.15)' }
|
||
}}
|
||
>
|
||
Today
|
||
</Button>
|
||
</Box>
|
||
</Box>
|
||
</Menu>
|
||
|
||
{/* المحتوى الأساسي للكارت */}
|
||
<CardContent>
|
||
<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', mb: 3 }}>
|
||
{period}
|
||
</Typography>
|
||
</Box>
|
||
|
||
{/* دائرة التقدم */}
|
||
<Box sx={{ height: 120, mb: 2, position: 'relative' }}>
|
||
<Box sx={{ position: 'relative', width: '100%', maxWidth: 350, 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,
|
||
})}
|
||
/>
|
||
</Box>
|
||
|
||
{/* النص داخل الدائرة */}
|
||
<Box
|
||
sx={{
|
||
position: 'absolute',
|
||
top: '36%',
|
||
left: '50%',
|
||
transform: 'translate(-50%, -50%)',
|
||
fontSize: { xs: '20px', sm: '26px' },
|
||
fontWeight: 500,
|
||
color: theme.palette.text.primary,
|
||
}}
|
||
>
|
||
{`${progress}%`}
|
||
</Box>
|
||
</Box>
|
||
</Box>
|
||
|
||
{/* الوصف */}
|
||
<Typography
|
||
variant="body2"
|
||
sx={{
|
||
mb: 1,
|
||
mt: 10,
|
||
color: '#667085',
|
||
fontSize: { xs: '14px', sm: '16px' },
|
||
}}
|
||
>
|
||
{description}
|
||
</Typography>
|
||
</CardContent>
|
||
</ResponsiveContainer>
|
||
</Card>
|
||
);
|
||
};
|
||
|
||
export default OrderStatusCard;
|