Initial project structure cleanup

This commit is contained in:
litoral05
2026-05-08 16:57:55 +01:00
commit 8075104243
59 changed files with 22335 additions and 0 deletions
@@ -0,0 +1,169 @@
import { useEffect, useState } from 'react';
import {
Area,
AreaChart,
CartesianGrid,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from 'recharts';
import { Card } from '@/components/ui/Card';
import { vpsApi } from '@/services/vpsApi';
type TrafficPoint = {
time: string;
downloadMbps: number;
uploadMbps: number;
};
const MAX_POINTS = 24;
export function NetworkTrafficChart() {
const [points, setPoints] = useState<
TrafficPoint[]
>([]);
const [error, setError] = useState('');
useEffect(() => {
let mounted = true;
async function loadTraffic() {
try {
const response =
await vpsApi.networkTraffic();
if (!mounted) {
return;
}
const point: TrafficPoint = {
time: new Date(
response.updatedAt,
).toLocaleTimeString(),
downloadMbps:
response.downloadMbps,
uploadMbps:
response.uploadMbps,
};
setPoints((currentPoints) => [
...currentPoints.slice(
-(MAX_POINTS - 1),
),
point,
]);
setError('');
} catch (err) {
if (mounted) {
setError(String(err));
}
}
}
loadTraffic();
const intervalId = window.setInterval(
loadTraffic,
3000,
);
return () => {
mounted = false;
window.clearInterval(intervalId);
};
}, []);
return (
<Card className="h-full">
<div className="mb-4 flex items-center justify-between">
<div>
<h3 className="font-semibold text-white">
Network Traffic
</h3>
<p className="text-xs text-slate-500">
Live wg0 RX/TX throughput
</p>
</div>
<span className="rounded-lg border border-white/10 bg-slate-900 px-3 py-1 text-xs text-slate-400">
3s refresh
</span>
</div>
{error && (
<div className="mb-3 rounded-xl border border-red-500/20 bg-red-500/10 p-3 text-xs text-red-300">
{error}
</div>
)}
<div className="h-72">
<ResponsiveContainer
width="100%"
height="100%"
>
<AreaChart data={points}>
<CartesianGrid
strokeDasharray="3 3"
stroke="rgba(148,163,184,.12)"
/>
<XAxis
dataKey="time"
stroke="#94a3b8"
fontSize={12}
minTickGap={24}
/>
<YAxis
stroke="#94a3b8"
fontSize={12}
tickFormatter={(value) =>
`${value} Mbps`
}
/>
<Tooltip
contentStyle={{
background: '#0b1522',
border:
'1px solid rgba(255,255,255,.1)',
borderRadius: 12,
}}
formatter={(value) => [
`${Number(value).toFixed(
3,
)} Mbps`,
'',
]}
/>
<Area
type="monotone"
dataKey="downloadMbps"
name="Download"
stroke="#19d16f"
fill="#19d16f"
fillOpacity={0.2}
/>
<Area
type="monotone"
dataKey="uploadMbps"
name="Upload"
stroke="#3b82f6"
fill="#3b82f6"
fillOpacity={0.16}
/>
</AreaChart>
</ResponsiveContainer>
</div>
</Card>
);
}