Initial commit - restaurant dashboard
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Box,
|
||||
@@ -6,7 +6,11 @@ import {
|
||||
Paper,
|
||||
Typography,
|
||||
useTheme,
|
||||
useMediaQuery
|
||||
useMediaQuery,
|
||||
Menu,
|
||||
MenuItem,
|
||||
TextField,
|
||||
Button
|
||||
} from '@mui/material';
|
||||
import {
|
||||
AreaChart,
|
||||
@@ -18,37 +22,64 @@ import {
|
||||
ResponsiveContainer,
|
||||
CartesianGrid
|
||||
} from 'recharts';
|
||||
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
||||
|
||||
const formatCurrency = (value) => {
|
||||
if (value >= 1000000) return `$${(value / 1000000).toFixed(1)}M`;
|
||||
if (value >= 1000) return `$${(value / 1000).toFixed(1)}K`;
|
||||
return `$${value}`;
|
||||
};
|
||||
// import MoreVertIcon from '@mui/icons-material/MoreVert';
|
||||
|
||||
const StatisticsCard = ({
|
||||
title = "Statistics",
|
||||
subtitle = "Delivery Times",
|
||||
data = [],
|
||||
dataKeys = [
|
||||
{ key: 'revenue', name: 'Revenue', color: '#E46A11' }, // << هنا تغيير اللون
|
||||
{ key: 'sales', name: 'Sales', color: '#0182FC' } // << وهنا أيضاً
|
||||
{ key: 'revenue', name: 'Revenue', color: '#E46A11' },
|
||||
{ key: 'sales', name: 'Sales', color: '#0182FC' }
|
||||
],
|
||||
xDataKey = 'month',
|
||||
valueFormatter = formatCurrency,
|
||||
valueFormatter = (value) => value,
|
||||
timeFrame = 'month',
|
||||
onTimeFrameChange
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.between('sm', 'md'));
|
||||
const [selectedDate, setSelectedDate] = useState('');
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
|
||||
const handleTimeFrameChange = (newTimeFrame) => {
|
||||
if (onTimeFrameChange) onTimeFrameChange(newTimeFrame);
|
||||
const handleMenuOpen = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
const handleMenuClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleDateChange = (event) => {
|
||||
setSelectedDate(event.target.value);
|
||||
if (onTimeFrameChange) onTimeFrameChange(timeFrame, event.target.value);
|
||||
handleMenuClose();
|
||||
};
|
||||
|
||||
const handleTodayClick = () => {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
setSelectedDate(today);
|
||||
if (onTimeFrameChange) onTimeFrameChange(timeFrame, today);
|
||||
handleMenuClose();
|
||||
};
|
||||
|
||||
// حساب العلامات الديناميكية للمحور الشاقولي
|
||||
const ticksArray = (() => {
|
||||
if (!data || data.length === 0) return [];
|
||||
const maxValue = Math.max(
|
||||
...data.flatMap(d => dataKeys.map(k => d[k.key] || 0))
|
||||
);
|
||||
const desiredTicks = 8; // عدد العلامات المطلوب
|
||||
const step = Math.ceil(maxValue / desiredTicks) || 1;
|
||||
const arr = [];
|
||||
for (let i = 0; i <= maxValue; i += step) {
|
||||
arr.push(i);
|
||||
}
|
||||
return arr;
|
||||
})();
|
||||
|
||||
return (
|
||||
<Box sx={{ borderRadius: 2, width: { sm: '100%', md: '167vh' }}}>
|
||||
<Box sx={{ borderRadius: 2, width: { sm: '100%', md: '167vh' } }}>
|
||||
<Paper sx={{
|
||||
p: { xs: 1.5, sm: 2 },
|
||||
mb: { xs: 2, sm: 2 },
|
||||
@@ -64,10 +95,34 @@ const StatisticsCard = ({
|
||||
right: { xs: 4, sm: 8 },
|
||||
color: '#667085'
|
||||
}}
|
||||
onClick={handleMenuOpen}
|
||||
>
|
||||
<MoreVertIcon fontSize={isMobile ? 'small' : 'medium'} />
|
||||
{/* <MoreVertIcon fontSize={isMobile ? 'small' : 'medium'} /> */}
|
||||
</IconButton>
|
||||
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleMenuClose}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||
>
|
||||
<MenuItem>
|
||||
<TextField
|
||||
type="date"
|
||||
value={selectedDate}
|
||||
onChange={handleDateChange}
|
||||
size="small"
|
||||
sx={{ width: 150 }}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<Button variant="outlined" size="small" onClick={handleTodayClick}>
|
||||
Today
|
||||
</Button>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
{/* Header */}
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
@@ -88,7 +143,7 @@ const StatisticsCard = ({
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<ResponsiveContainer width="100%" height={isMobile ? 250 : isTablet ? 290 : 295}>
|
||||
<ResponsiveContainer width="100%" height={isMobile ? 350 : isTablet ? 390 : 395}>
|
||||
<AreaChart data={data} margin={{
|
||||
top: isMobile ? -30 : -45,
|
||||
right: isMobile ? 15 : 30,
|
||||
@@ -112,18 +167,20 @@ const StatisticsCard = ({
|
||||
tickMargin={isMobile ? 8 : 15}
|
||||
tick={{
|
||||
fontSize: isMobile ? 11 : 12,
|
||||
angle: -25, // تدوير النص لتفادي التزاحم
|
||||
angle: -25,
|
||||
textAnchor: 'end'
|
||||
}}
|
||||
interval={0} // عرض كل القيم على محور X
|
||||
interval={0}
|
||||
/>
|
||||
<YAxis
|
||||
ticks={ticksArray}
|
||||
tickFormatter={valueFormatter}
|
||||
axisLine={false}
|
||||
tickLine={false}
|
||||
tickMargin={isMobile ? 8 : 15}
|
||||
tick={{ fontSize: isMobile ? 11 : 12 }}
|
||||
/>
|
||||
|
||||
<Tooltip formatter={valueFormatter} />
|
||||
<Legend
|
||||
verticalAlign="top"
|
||||
@@ -138,9 +195,9 @@ const StatisticsCard = ({
|
||||
name={name}
|
||||
type="monotone"
|
||||
dataKey={key}
|
||||
stroke={color} // لون الخط
|
||||
stroke={color}
|
||||
strokeWidth={isMobile ? 2 : 3}
|
||||
fill={`url(#color-${key})`} // لون التعبئة بتدرج
|
||||
fill={`url(#color-${key})`}
|
||||
/>
|
||||
))}
|
||||
</AreaChart>
|
||||
|
||||
Reference in New Issue
Block a user