feat(overview): add file statistics fetching and display in analytics view

This commit is contained in:
OlgunR
2025-12-10 15:00:55 +01:00
parent 214afea43d
commit a01bde914a
4 changed files with 130 additions and 13 deletions

View File

@@ -22,6 +22,8 @@ type Props = CardProps & {
percent: number;
color?: PaletteColorKey;
icon: React.ReactNode;
details?: { label: string; value: number }[];
loading?: boolean;
chart: {
series: number[];
categories: string[];
@@ -37,6 +39,8 @@ export function AnalyticsWidgetSummary({
chart,
percent,
color = 'primary',
details,
loading = false,
...other
}: Props) {
const theme = useTheme();
@@ -114,6 +118,23 @@ export function AnalyticsWidgetSummary({
<Box sx={{ mb: 1, typography: 'subtitle2' }}>{title}</Box>
<Box sx={{ typography: 'h4' }}>{fShortenNumber(total)}</Box>
{details?.length ? (
<Box component="ul" sx={{ mt: 1.5, mb: 0, pl: 0, listStyle: 'none', gap: 0.5, display: 'grid' }}>
{details.map((item) => (
<Box
component="li"
key={item.label}
sx={{ display: 'flex', justifyContent: 'space-between', typography: 'caption', color: 'text.secondary' }}
>
<Box component="span">{item.label}</Box>
<Box component="span" sx={{ color: 'text.primary', fontWeight: 'fontWeightSemiBold' }}>
{loading ? '…' : fShortenNumber(item.value)}
</Box>
</Box>
))}
</Box>
) : null}
</Box>
<Chart

View File

@@ -22,6 +22,8 @@ type Props = CardProps & {
percent: number;
color?: PaletteColorKey;
icon: React.ReactNode;
details?: { label: string; value: number }[];
loading?: boolean;
chart: {
series: number[];
categories: string[];
@@ -37,6 +39,8 @@ export function AnalyticsWidgetSummary({
chart,
percent,
color = 'primary',
details,
loading = false,
...other
}: Props) {
const theme = useTheme();
@@ -114,6 +118,23 @@ export function AnalyticsWidgetSummary({
<Box sx={{ mb: 1, typography: 'subtitle2' }}>{title}</Box>
<Box sx={{ typography: 'h4' }}>{fShortenNumber(total)}</Box>
{details?.length ? (
<Box component="ul" sx={{ mt: 1.5, mb: 0, pl: 0, listStyle: 'none', gap: 0.5, display: 'grid' }}>
{details.map((item) => (
<Box
component="li"
key={item.label}
sx={{ display: 'flex', justifyContent: 'space-between', typography: 'caption', color: 'text.secondary' }}
>
<Box component="span">{item.label}</Box>
<Box component="span" sx={{ color: 'text.primary', fontWeight: 'fontWeightSemiBold' }}>
{loading ? '…' : fShortenNumber(item.value)}
</Box>
</Box>
))}
</Box>
) : null}
</Box>
<Chart

View File

@@ -1,8 +1,11 @@
import { useMemo, useState, useEffect } from 'react';
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 { fetchFileStatsToday } from 'src/services/file-stats-service';
import { AnalyticsNews } from '../analytics-news';
import { AnalyticsTasks } from '../analytics-tasks';
@@ -17,6 +20,53 @@ import { AnalyticsConversionRates } from '../analytics-conversion-rates';
// ----------------------------------------------------------------------
export function OverviewAnalyticsView() {
const [fileStats, setFileStats] = useState({ filed: 0, edited: 0 });
const [loadingFiles, setLoadingFiles] = useState(true);
const visitCategories = useMemo(() => {
const days = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
const today = new Date();
const labels = Array.from({ length: 7 }, (_, idx) => {
const d = new Date(today);
d.setDate(today.getDate() - (6 - idx));
const dayIdx = d.getDay();
return days[dayIdx];
});
labels[labels.length - 1] = 'Heute';
return labels;
}, []);
const baselineFiled = [43, 33, 22, 37, 67, 68];
const baselineEdited = [51, 70, 47, 67, 40, 37];
const visitSeries = [
{
name: 'Dateien abgelegt',
data: [...baselineFiled, fileStats.filed],
},
{
name: 'Dateien bearbeitet',
data: [...baselineEdited, fileStats.edited],
},
];
useEffect(() => {
let active = true;
fetchFileStatsToday()
.then((data) => {
if (active) setFileStats(data);
})
.finally(() => {
if (active) setLoadingFiles(false);
});
return () => {
active = false;
};
}, []);
return (
<DashboardContent maxWidth="xl">
<Typography variant="h4" sx={{ mb: { xs: 3, md: 5 } }}>
@@ -26,13 +76,19 @@ export function OverviewAnalyticsView() {
<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" />}
title="Dateien - Heute"
percent={0}
total={fileStats.filed + fileStats.edited}
icon={<img alt="Dateien" src="/assets/icons/glass/ic-glass-bag.svg" />}
details={[
{ label: 'Dateien abgelegt', value: fileStats.filed },
{ label: 'Dateien bearbeitet', value: fileStats.edited },
]}
loading={loadingFiles}
chart={{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'],
series: [22, 8, 35, 50, 82, 84, 77, 12],
categories: ['Heute'],
series: [fileStats.filed, fileStats.edited],
options: { stroke: { width: 2 } },
}}
/>
</Grid>
@@ -95,14 +151,14 @@ export function OverviewAnalyticsView() {
<Grid size={{ xs: 12, md: 6, lg: 8 }}>
<AnalyticsWebsiteVisits
title="Website visits"
subheader="(+43%) than last year"
title="Dateien verarbeitet"
subheader="(+43%) als letzte Woche"
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] },
],
categories: visitCategories,
series: visitSeries,
options: {
tooltip: { y: { formatter: (value: number) => `${value} Dateien` } },
},
}}
/>
</Grid>

View File

@@ -0,0 +1,19 @@
export type FileStatsToday = {
filed: number;
edited: number;
};
export async function fetchFilesAbgelegtToday(): Promise<number> {
// Mock placeholder: returns number of files placed today
return Promise.resolve(5);
}
export async function fetchFilesBearbeitetToday(): Promise<number> {
// Mock placeholder: returns number of files edited today
return Promise.resolve(20);
}
export async function fetchFileStatsToday(): Promise<FileStatsToday> {
const [filed, edited] = await Promise.all([fetchFilesAbgelegtToday(), fetchFilesBearbeitetToday()]);
return { filed, edited };
}