refactor frontend and backend modules

This commit is contained in:
2026-05-04 22:57:57 +02:00
parent e0e461502b
commit 8f0a9650b0
17 changed files with 4560 additions and 4416 deletions
+154
View File
@@ -0,0 +1,154 @@
import {
Box,
Card,
CardContent,
Grid,
LinearProgress,
Stack,
Typography,
} from "@mui/material";
interface Props {
used: number;
available: number;
size: number;
usedPct: string;
}
function formatBytes(bytes: number): string {
if (!bytes || bytes === 0) return "0 B";
const units = ["B", "KB", "MB", "GB", "TB"];
let value = bytes;
let unitIdx = 0;
while (value >= 1000 && unitIdx < units.length - 1) {
value /= 1000;
unitIdx++;
}
return `${value.toFixed(1)} ${units[unitIdx]}`;
}
/**
* Dashboard card that summarizes the configured media disk.
*
* It intentionally keeps the progress bar inside the card so the capacity
* signal, raw byte values, and free-space breakdown stay visually grouped.
*/
export function DiskSpaceCard({ used, available, size, usedPct }: Props) {
const pct = Math.max(0, Math.min(100, Number.parseFloat(usedPct) || 0));
const barColor = pct < 70 ? "success" : pct < 90 ? "warning" : "error";
return (
<Card variant="outlined" sx={{ height: "100%" }}>
<CardContent sx={{ p: { xs: 1.5, sm: 2 } }}>
<Stack spacing={1.5}>
<Box>
<Typography
variant="caption"
color="text.secondary"
sx={{ textTransform: "uppercase" }}
>
Disk space
</Typography>
<Typography
variant="h5"
sx={{
fontWeight: 700,
fontSize: { xs: "1.05rem", sm: "1.5rem" },
}}
>
{usedPct} used
</Typography>
</Box>
<Box sx={{ width: "100%" }}>
<LinearProgress
variant="determinate"
value={pct}
color={barColor}
sx={{
height: 12,
borderRadius: 999,
bgcolor: "action.hover",
"& .MuiLinearProgress-bar": {
borderRadius: 999,
},
}}
/>
</Box>
<Grid container spacing={1.5} sx={{ alignItems: "stretch" }}>
<Grid size={{ xs: 12, sm: 4 }}>
<Box
sx={{
p: 1.5,
borderRadius: 2,
bgcolor: "action.hover",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
textAlign: "center",
gap: 0.25,
}}
>
<Typography variant="caption" color="text.secondary">
Used
</Typography>
<Typography variant="body2" sx={{ fontWeight: 600 }}>
{formatBytes(used)}
</Typography>
</Box>
</Grid>
<Grid size={{ xs: 12, sm: 4 }}>
<Box
sx={{
p: 1.5,
borderRadius: 2,
bgcolor: "action.hover",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
textAlign: "center",
gap: 0.25,
}}
>
<Typography variant="caption" color="text.secondary">
Free
</Typography>
<Typography variant="body2" sx={{ fontWeight: 600 }}>
{formatBytes(available)}
</Typography>
</Box>
</Grid>
<Grid size={{ xs: 12, sm: 4 }}>
<Box
sx={{
p: 1.5,
borderRadius: 2,
bgcolor: "action.hover",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
textAlign: "center",
gap: 0.25,
}}
>
<Typography variant="caption" color="text.secondary">
Total
</Typography>
<Typography variant="body2" sx={{ fontWeight: 600 }}>
{formatBytes(size)}
</Typography>
</Box>
</Grid>
</Grid>
</Stack>
</CardContent>
</Card>
);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff