feat(charts): add new ChartFlow page and analytics components for enhanced dashboard insights

This commit is contained in:
OlgunR 2025-11-24 17:18:06 +01:00
parent df144ae357
commit cfbdda6e02
15 changed files with 1048 additions and 2 deletions

View File

@ -39,10 +39,15 @@ export const navData = [
icon: icon('ic-cart'),
},
{
title: 'User Manager',
title: 'SignFlow',
path: '/user',
icon: icon('ic-user'),
},
{
title: 'ChartFlow',
path: '/chart-flow',
icon: icon('ic-user'),
},
{
title: 'Sign in',
path: '/sign-in',

View File

@ -0,0 +1,20 @@
import { CONFIG } from 'src/config-global';
import { ChartsView } from 'src/sections/charts/view';
// ----------------------------------------------------------------------
export default function Page() {
return (
<>
<title>{`Dashboard - ${CONFIG.appName}`}</title>
<meta
name="description"
content="The starting point for your next project with Minimal UI Kit, built on the newest version of Material-UI ©, ready to be customized to your style"
/>
<meta name="keywords" content="react,material,kit,application,dashboard,admin,template" />
< ChartsView/>
</>
);
}

View File

@ -1,6 +1,6 @@
import { CONFIG } from 'src/config-global';
import { OverviewAnalyticsView as DashboardView, OverviewAnalyticsView } from 'src/sections/overview/view';
import { OverviewAnalyticsView } from 'src/sections/overview/view';
// ----------------------------------------------------------------------

View File

@ -19,6 +19,7 @@ export const SignInPage = lazy(() => import('src/pages/sign-in'));
export const ProductsPage = lazy(() => import('src/pages/products'));
export const Page404 = lazy(() => import('src/pages/page-not-found'));
export const DocumentSearch = lazy(() => import('src/pages/doc-search'));
export const ChartFlowPage = lazy(() => import('src/pages/charts'));
const renderFallback = () => (
<Box
@ -55,6 +56,7 @@ export const routesSection: RouteObject[] = [
{ path: 'products', element: <ProductsPage /> },
{ path: 'user', element: <UserPage /> },
{ path: 'blog', element: <BlogPage /> },
{ path: 'chart-flow', element: <ChartFlowPage /> },
],
},
{

View File

@ -0,0 +1,82 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import { useTheme, alpha as hexAlpha } from '@mui/material/styles';
import { fNumber } from 'src/utils/format-number';
import { Chart, useChart } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
categories?: string[];
series: {
name: string;
data: number[];
}[];
options?: ChartOptions;
};
};
export function AnalyticsConversionRates({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartColors = chart.colors ?? [
theme.palette.primary.dark,
hexAlpha(theme.palette.primary.dark, 0.24),
];
const chartOptions = useChart({
colors: chartColors,
stroke: { width: 2, colors: ['transparent'] },
tooltip: {
shared: true,
intersect: false,
y: {
formatter: (value: number) => fNumber(value),
title: { formatter: (seriesName: string) => `${seriesName}: ` },
},
},
xaxis: { categories: chart.categories },
dataLabels: {
enabled: true,
offsetX: -6,
style: { fontSize: '10px', colors: ['#FFFFFF', theme.palette.text.primary] },
},
plotOptions: {
bar: {
horizontal: true,
borderRadius: 2,
barHeight: '48%',
dataLabels: { position: 'top' },
},
},
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="bar"
series={chart.series}
options={chartOptions}
slotProps={{ loading: { p: 2.5 } }}
sx={{
pl: 1,
py: 2.5,
pr: 2.5,
height: 360,
}}
/>
</Card>
);
}

View File

@ -0,0 +1,73 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import Divider from '@mui/material/Divider';
import { useTheme } from '@mui/material/styles';
import CardHeader from '@mui/material/CardHeader';
import { Chart, useChart, ChartLegends } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
categories: string[];
series: {
name: string;
data: number[];
}[];
options?: ChartOptions;
};
};
export function AnalyticsCurrentSubject({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartColors = chart.colors ?? [
theme.palette.primary.main,
theme.palette.warning.main,
theme.palette.info.main,
];
const chartOptions = useChart({
colors: chartColors,
stroke: { width: 2 },
fill: { opacity: 0.48 },
xaxis: {
categories: chart.categories,
labels: { style: { colors: Array.from({ length: 6 }, () => theme.palette.text.secondary) } },
},
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="radar"
series={chart.series}
options={chartOptions}
slotProps={{ loading: { py: 2.5 } }}
sx={{
my: 1,
mx: 'auto',
width: 300,
height: 300,
}}
/>
<Divider sx={{ borderStyle: 'dashed' }} />
<ChartLegends
labels={chart.series.map((item) => item.name)}
colors={chartOptions?.colors}
sx={{ p: 3, justifyContent: 'center' }}
/>
</Card>
);
}

View File

@ -0,0 +1,81 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import Divider from '@mui/material/Divider';
import { useTheme } from '@mui/material/styles';
import CardHeader from '@mui/material/CardHeader';
import { fNumber } from 'src/utils/format-number';
import { Chart, useChart, ChartLegends } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
series: {
label: string;
value: number;
}[];
options?: ChartOptions;
};
};
export function AnalyticsCurrentVisits({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartSeries = chart.series.map((item) => item.value);
const chartColors = chart.colors ?? [
theme.palette.primary.main,
theme.palette.warning.light,
theme.palette.info.dark,
theme.palette.error.main,
];
const chartOptions = useChart({
chart: { sparkline: { enabled: true } },
colors: chartColors,
labels: chart.series.map((item) => item.label),
stroke: { width: 0 },
dataLabels: { enabled: true, dropShadow: { enabled: false } },
tooltip: {
y: {
formatter: (value: number) => fNumber(value),
title: { formatter: (seriesName: string) => `${seriesName}` },
},
},
plotOptions: { pie: { donut: { labels: { show: false } } } },
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="pie"
series={chartSeries}
options={chartOptions}
sx={{
my: 6,
mx: 'auto',
width: { xs: 240, xl: 260 },
height: { xs: 240, xl: 260 },
}}
/>
<Divider sx={{ borderStyle: 'dashed' }} />
<ChartLegends
labels={chartOptions?.labels}
colors={chartOptions?.colors}
sx={{ p: 3, justifyContent: 'center' }}
/>
</Card>
);
}

View File

@ -0,0 +1,103 @@
import type { BoxProps } from '@mui/material/Box';
import type { CardProps } from '@mui/material/Card';
import Box from '@mui/material/Box';
import Link from '@mui/material/Link';
import Card from '@mui/material/Card';
import Button from '@mui/material/Button';
import Avatar from '@mui/material/Avatar';
import CardHeader from '@mui/material/CardHeader';
import ListItemText from '@mui/material/ListItemText';
import { fToNow } from 'src/utils/format-time';
import { Iconify } from 'src/components/iconify';
import { Scrollbar } from 'src/components/scrollbar';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: {
id: string;
title: string;
coverUrl: string;
description: string;
postedAt: string | number | null;
}[];
};
export function AnalyticsNews({ title, subheader, list, sx, ...other }: Props) {
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} sx={{ mb: 1 }} />
<Scrollbar sx={{ minHeight: 405 }}>
<Box sx={{ minWidth: 640 }}>
{list.map((item) => (
<Item key={item.id} item={item} />
))}
</Box>
</Scrollbar>
<Box sx={{ p: 2, textAlign: 'right' }}>
<Button
size="small"
color="inherit"
endIcon={<Iconify icon="eva:arrow-ios-forward-fill" width={18} sx={{ ml: -0.5 }} />}
>
View all
</Button>
</Box>
</Card>
);
}
// ----------------------------------------------------------------------
type ItemProps = BoxProps & {
item: Props['list'][number];
};
function Item({ item, sx, ...other }: ItemProps) {
return (
<Box
sx={[
(theme) => ({
py: 2,
px: 3,
gap: 2,
display: 'flex',
alignItems: 'center',
borderBottom: `dashed 1px ${theme.vars.palette.divider}`,
}),
...(Array.isArray(sx) ? sx : [sx]),
]}
{...other}
>
<Avatar
variant="rounded"
alt={item.title}
src={item.coverUrl}
sx={{ width: 48, height: 48, flexShrink: 0 }}
/>
<ListItemText
primary={<Link color="inherit">{item.title}</Link>}
secondary={item.description}
slotProps={{
primary: { noWrap: true },
secondary: {
noWrap: true,
sx: { mt: 0.5 },
},
}}
/>
<Box sx={{ flexShrink: 0, typography: 'caption', color: 'text.disabled' }}>
{fToNow(item.postedAt)}
</Box>
</Box>
);
}

View File

@ -0,0 +1,77 @@
import type { CardProps } from '@mui/material/Card';
import type { TimelineItemProps } from '@mui/lab/TimelineItem';
import Card from '@mui/material/Card';
import Timeline from '@mui/lab/Timeline';
import TimelineDot from '@mui/lab/TimelineDot';
import Typography from '@mui/material/Typography';
import CardHeader from '@mui/material/CardHeader';
import TimelineContent from '@mui/lab/TimelineContent';
import TimelineSeparator from '@mui/lab/TimelineSeparator';
import TimelineConnector from '@mui/lab/TimelineConnector';
import TimelineItem, { timelineItemClasses } from '@mui/lab/TimelineItem';
import { fDateTime } from 'src/utils/format-time';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: {
id: string;
type: string;
title: string;
time: string | number | null;
}[];
};
export function AnalyticsOrderTimeline({ title, subheader, list, sx, ...other }: Props) {
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Timeline
sx={{ m: 0, p: 3, [`& .${timelineItemClasses.root}:before`]: { flex: 0, padding: 0 } }}
>
{list.map((item, index) => (
<Item key={item.id} item={item} lastItem={index === list.length - 1} />
))}
</Timeline>
</Card>
);
}
// ----------------------------------------------------------------------
type ItemProps = TimelineItemProps & {
lastItem: boolean;
item: Props['list'][number];
};
function Item({ item, lastItem, ...other }: ItemProps) {
return (
<TimelineItem {...other}>
<TimelineSeparator>
<TimelineDot
color={
(item.type === 'order1' && 'primary') ||
(item.type === 'order2' && 'success') ||
(item.type === 'order3' && 'info') ||
(item.type === 'order4' && 'warning') ||
'error'
}
/>
{lastItem ? null : <TimelineConnector />}
</TimelineSeparator>
<TimelineContent>
<Typography variant="subtitle2">{item.title}</Typography>
<Typography variant="caption" sx={{ color: 'text.disabled' }}>
{fDateTime(item.time)}
</Typography>
</TimelineContent>
</TimelineItem>
);
}

View File

@ -0,0 +1,179 @@
import type { BoxProps } from '@mui/material/Box';
import type { CardProps } from '@mui/material/Card';
import { useState } from 'react';
import { usePopover } from 'minimal-shared/hooks';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import Stack from '@mui/material/Stack';
import Popover from '@mui/material/Popover';
import Divider from '@mui/material/Divider';
import MenuList from '@mui/material/MenuList';
import Checkbox from '@mui/material/Checkbox';
import IconButton from '@mui/material/IconButton';
import CardHeader from '@mui/material/CardHeader';
import FormControlLabel from '@mui/material/FormControlLabel';
import MenuItem, { menuItemClasses } from '@mui/material/MenuItem';
import { Iconify } from 'src/components/iconify';
import { Scrollbar } from 'src/components/scrollbar';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: {
id: string;
name: string;
}[];
};
export function AnalyticsTasks({ title, subheader, list, sx, ...other }: Props) {
const [selected, setSelected] = useState(['2']);
const handleClickComplete = (taskId: string) => {
const tasksCompleted = selected.includes(taskId)
? selected.filter((value) => value !== taskId)
: [...selected, taskId];
setSelected(tasksCompleted);
};
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} sx={{ mb: 1 }} />
<Scrollbar sx={{ minHeight: 304 }}>
<Stack divider={<Divider sx={{ borderStyle: 'dashed' }} />} sx={{ minWidth: 560 }}>
{list.map((item) => (
<TaskItem
key={item.id}
item={item}
selected={selected.includes(item.id)}
onChange={() => handleClickComplete(item.id)}
/>
))}
</Stack>
</Scrollbar>
</Card>
);
}
// ----------------------------------------------------------------------
type TaskItemProps = BoxProps & {
selected: boolean;
item: Props['list'][number];
onChange: (id: string) => void;
};
function TaskItem({ item, selected, onChange, sx, ...other }: TaskItemProps) {
const menuActions = usePopover();
const handleMarkComplete = () => {
menuActions.onClose();
console.info('MARK COMPLETE', item.id);
};
const handleShare = () => {
menuActions.onClose();
console.info('SHARE', item.id);
};
const handleEdit = () => {
menuActions.onClose();
console.info('EDIT', item.id);
};
const handleDelete = () => {
menuActions.onClose();
console.info('DELETE', item.id);
};
return (
<>
<Box
sx={[
() => ({
pl: 2,
pr: 1,
py: 1.5,
display: 'flex',
...(selected && {
color: 'text.disabled',
textDecoration: 'line-through',
}),
}),
...(Array.isArray(sx) ? sx : [sx]),
]}
{...other}
>
<FormControlLabel
label={item.name}
control={
<Checkbox
disableRipple
checked={selected}
onChange={onChange}
slotProps={{ input: { id: `${item.name}-checkbox` } }}
/>
}
sx={{ flexGrow: 1, m: 0 }}
/>
<IconButton color={menuActions.open ? 'inherit' : 'default'} onClick={menuActions.onOpen}>
<Iconify icon="eva:more-vertical-fill" />
</IconButton>
</Box>
<Popover
open={menuActions.open}
anchorEl={menuActions.anchorEl}
onClose={menuActions.onClose}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
>
<MenuList
disablePadding
sx={{
p: 0.5,
gap: 0.5,
display: 'flex',
flexDirection: 'column',
[`& .${menuItemClasses.root}`]: {
pl: 1,
pr: 2,
gap: 2,
borderRadius: 0.75,
[`&.${menuItemClasses.selected}`]: { bgcolor: 'action.selected' },
},
}}
>
<MenuItem onClick={handleMarkComplete}>
<Iconify icon="solar:check-circle-bold" />
Mark complete
</MenuItem>
<MenuItem onClick={handleEdit}>
<Iconify icon="solar:pen-bold" />
Edit
</MenuItem>
<MenuItem onClick={handleShare}>
<Iconify icon="solar:share-bold" />
Share
</MenuItem>
<Divider sx={{ borderStyle: 'dashed' }} />
<MenuItem onClick={handleDelete} sx={{ color: 'error.main' }}>
<Iconify icon="solar:trash-bin-trash-bold" />
Delete
</MenuItem>
</MenuList>
</Popover>
</>
);
}

View File

@ -0,0 +1,64 @@
import type { CardProps } from '@mui/material/Card';
import { varAlpha } from 'minimal-shared/utils';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import Typography from '@mui/material/Typography';
import { fShortenNumber } from 'src/utils/format-number';
import { Iconify } from 'src/components/iconify';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
list: { value: string; label: string; total: number }[];
};
export function AnalyticsTrafficBySite({ title, subheader, list, sx, ...other }: Props) {
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Box
sx={{
p: 3,
gap: 2,
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
}}
>
{list.map((site) => (
<Box
key={site.label}
sx={(theme) => ({
py: 2.5,
display: 'flex',
borderRadius: 1.5,
textAlign: 'center',
alignItems: 'center',
flexDirection: 'column',
border: `solid 1px ${varAlpha(theme.vars.palette.grey['500Channel'], 0.12)}`,
})}
>
{site.value === 'twitter' && <Iconify width={32} icon="socials:twitter" />}
{site.value === 'facebook' && <Iconify width={32} icon="socials:facebook" />}
{site.value === 'google' && <Iconify width={32} icon="socials:google" />}
{site.value === 'linkedin' && <Iconify width={32} icon="socials:linkedin" />}
<Typography variant="h6" sx={{ mt: 1 }}>
{fShortenNumber(site.total)}
</Typography>
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
{site.label}
</Typography>
</Box>
))}
</Box>
</Card>
);
}

View File

@ -0,0 +1,61 @@
import type { CardProps } from '@mui/material/Card';
import type { ChartOptions } from 'src/components/chart';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import { useTheme, alpha as hexAlpha } from '@mui/material/styles';
import { Chart, useChart } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title?: string;
subheader?: string;
chart: {
colors?: string[];
categories?: string[];
series: {
name: string;
data: number[];
}[];
options?: ChartOptions;
};
};
export function AnalyticsWebsiteVisits({ title, subheader, chart, sx, ...other }: Props) {
const theme = useTheme();
const chartColors = chart.colors ?? [
hexAlpha(theme.palette.primary.dark, 0.8),
hexAlpha(theme.palette.warning.main, 0.8),
];
const chartOptions = useChart({
colors: chartColors,
stroke: { width: 2, colors: ['transparent'] },
xaxis: { categories: chart.categories },
legend: { show: true },
tooltip: { y: { formatter: (value: number) => `${value} visits` } },
...chart.options,
});
return (
<Card sx={sx} {...other}>
<CardHeader title={title} subheader={subheader} />
<Chart
type="bar"
series={chart.series}
options={chartOptions}
slotProps={{ loading: { p: 2.5 } }}
sx={{
pl: 1,
py: 2.5,
pr: 2.5,
height: 364,
}}
/>
</Card>
);
}

View File

@ -0,0 +1,142 @@
import type { CardProps } from '@mui/material/Card';
import type { PaletteColorKey } from 'src/theme/core';
import type { ChartOptions } from 'src/components/chart';
import { varAlpha } from 'minimal-shared/utils';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import { useTheme } from '@mui/material/styles';
import { fNumber, fPercent, fShortenNumber } from 'src/utils/format-number';
import { Iconify } from 'src/components/iconify';
import { SvgColor } from 'src/components/svg-color';
import { Chart, useChart } from 'src/components/chart';
// ----------------------------------------------------------------------
type Props = CardProps & {
title: string;
total: number;
percent: number;
color?: PaletteColorKey;
icon: React.ReactNode;
chart: {
series: number[];
categories: string[];
options?: ChartOptions;
};
};
export function AnalyticsWidgetSummary({
sx,
icon,
title,
total,
chart,
percent,
color = 'primary',
...other
}: Props) {
const theme = useTheme();
const chartColors = [theme.palette[color].dark];
const chartOptions = useChart({
chart: { sparkline: { enabled: true } },
colors: chartColors,
xaxis: { categories: chart.categories },
grid: {
padding: {
top: 6,
left: 6,
right: 6,
bottom: 6,
},
},
tooltip: {
y: { formatter: (value: number) => fNumber(value), title: { formatter: () => '' } },
},
markers: {
strokeWidth: 0,
},
...chart.options,
});
const renderTrending = () => (
<Box
sx={{
top: 16,
gap: 0.5,
right: 16,
display: 'flex',
position: 'absolute',
alignItems: 'center',
}}
>
<Iconify width={20} icon={percent < 0 ? 'eva:trending-down-fill' : 'eva:trending-up-fill'} />
<Box component="span" sx={{ typography: 'subtitle2' }}>
{percent > 0 && '+'}
{fPercent(percent)}
</Box>
</Box>
);
return (
<Card
sx={[
() => ({
p: 3,
boxShadow: 'none',
position: 'relative',
color: `${color}.darker`,
backgroundColor: 'common.white',
backgroundImage: `linear-gradient(135deg, ${varAlpha(theme.vars.palette[color].lighterChannel, 0.48)}, ${varAlpha(theme.vars.palette[color].lightChannel, 0.48)})`,
}),
...(Array.isArray(sx) ? sx : [sx]),
]}
{...other}
>
<Box sx={{ width: 48, height: 48, mb: 3 }}>{icon}</Box>
{renderTrending()}
<Box
sx={{
display: 'flex',
flexWrap: 'wrap',
alignItems: 'flex-end',
justifyContent: 'flex-end',
}}
>
<Box sx={{ flexGrow: 1, minWidth: 112 }}>
<Box sx={{ mb: 1, typography: 'subtitle2' }}>{title}</Box>
<Box sx={{ typography: 'h4' }}>{fShortenNumber(total)}</Box>
</Box>
<Chart
type="line"
series={[{ data: chart.series }]}
options={chartOptions}
sx={{ width: 84, height: 56 }}
/>
</Box>
<SvgColor
src="/assets/background/shape-square.svg"
sx={{
top: 0,
left: -20,
width: 240,
zIndex: -1,
height: 240,
opacity: 0.24,
position: 'absolute',
color: `${color}.main`,
}}
/>
</Card>
);
}

View File

@ -0,0 +1,156 @@
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { DashboardContent } from 'src/layouts/dashboard';
import { _posts, _tasks, _traffic, _timeline } from 'src/_mock';
import { AnalyticsNews } from '../analytics-news';
import { AnalyticsTasks } from '../analytics-tasks';
import { AnalyticsCurrentVisits } from '../analytics-current-visits';
import { AnalyticsOrderTimeline } from '../analytics-order-timeline';
import { AnalyticsWebsiteVisits } from '../analytics-website-visits';
import { AnalyticsWidgetSummary } from '../analytics-widget-summary';
import { AnalyticsTrafficBySite } from '../analytics-traffic-by-site';
import { AnalyticsCurrentSubject } from '../analytics-current-subject';
import { AnalyticsConversionRates } from '../analytics-conversion-rates';
// ----------------------------------------------------------------------
export function ChartsView() {
return (
<DashboardContent maxWidth="xl">
<Typography variant="h4" sx={{ mb: { xs: 3, md: 5 } }}>
Hi, Welcome back 👋
</Typography>
<Grid container spacing={3}>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Weekly sales"
percent={2.6}
total={714000}
icon={<img alt="Weekly sales" src="/assets/icons/glass/ic-glass-bag.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [22, 8, 35, 50, 82, 84, 77, 12],
}}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="New users"
percent={-0.1}
total={1352831}
color="secondary"
icon={<img alt="New users" src="/assets/icons/glass/ic-glass-users.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [56, 47, 40, 62, 73, 30, 23, 54],
}}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Purchase orders"
percent={2.8}
total={1723315}
color="warning"
icon={<img alt="Purchase orders" src="/assets/icons/glass/ic-glass-buy.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [40, 70, 50, 28, 70, 75, 7, 64],
}}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<AnalyticsWidgetSummary
title="Messages"
percent={3.6}
total={234}
color="error"
icon={<img alt="Messages" src="/assets/icons/glass/ic-glass-message.svg" />}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [56, 30, 23, 54, 47, 40, 62, 73],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsCurrentVisits
title="Current visits"
chart={{
series: [
{ label: 'America', value: 3500 },
{ label: 'Asia', value: 2500 },
{ label: 'Europe', value: 1500 },
{ label: 'Africa', value: 500 },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsWebsiteVisits
title="Website visits"
subheader="(+43%) than last year"
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
series: [
{ name: 'Team A', data: [43, 33, 22, 37, 67, 68, 37, 24, 55] },
{ name: 'Team B', data: [51, 70, 47, 67, 40, 37, 24, 70, 24] },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsConversionRates
title="Conversion rates"
subheader="(+43%) than last year"
chart={{
categories: ['Italy', 'Japan', 'China', 'Canada', 'France'],
series: [
{ name: '2022', data: [44, 55, 41, 64, 22] },
{ name: '2023', data: [53, 32, 33, 52, 13] },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsCurrentSubject
title="Current subject"
chart={{
categories: ['English', 'History', 'Physics', 'Geography', 'Chinese', 'Math'],
series: [
{ name: 'Series 1', data: [80, 50, 30, 40, 100, 20] },
{ name: 'Series 2', data: [20, 30, 40, 80, 20, 80] },
{ name: 'Series 3', data: [44, 76, 78, 13, 43, 10] },
],
}}
/>
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsNews title="News" list={_posts.slice(0, 5)} />
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsOrderTimeline title="Order timeline" list={_timeline} />
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<AnalyticsTrafficBySite title="Traffic by site" list={_traffic} />
</Grid>
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsTasks title="Tasks" list={_tasks} />
</Grid>
</Grid>
</DashboardContent>
);
}

View File

@ -0,0 +1 @@
export * from './charts-view';