File transfer

This commit is contained in:
2026-06-11 20:33:44 -05:00
parent 2cb1d58264
commit b362357bcb
58 changed files with 5096 additions and 4 deletions

View File

@@ -0,0 +1,55 @@
/**
* Traffic Chart — Recharts line chart for bandwidth over time
* Ball Studios <https://git.balls.studio>
*/
import React from 'react';
import {
LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer,
} from 'recharts';
interface DataPoint {
rx_bytes: number;
tx_bytes: number;
recorded_at: string;
}
interface Props { data: DataPoint[]; }
function formatTick(bytes: number): string {
if (bytes < 1024) return `${bytes}B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)}K`;
return `${(bytes / 1024 / 1024).toFixed(1)}M`;
}
export default function TrafficChart({ data }: Props) {
if (data.length === 0) {
return <div className='addon-empty'>No historical data available yet.</div>;
}
const chartData = data.map(d => ({
time: new Date(d.recorded_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
rx: d.rx_bytes,
tx: d.tx_bytes,
}));
return (
<ResponsiveContainer width='100%' height={260}>
<LineChart data={chartData} margin={{ top: 8, right: 20, left: 0, bottom: 0 }}>
<CartesianGrid strokeDasharray='3 3' stroke='rgba(255,255,255,0.08)' />
<XAxis dataKey='time' tick={{ fill: '#9ca3af', fontSize: 11 }} tickLine={false} />
<YAxis tickFormatter={formatTick} tick={{ fill: '#9ca3af', fontSize: 11 }} tickLine={false} />
<Tooltip
contentStyle={{ background: '#1f2937', border: 'none', borderRadius: 8 }}
formatter={(v: number, name: string) => [
`${(v / 1024 / 1024).toFixed(2)} MB`,
name === 'rx' ? '⬇ Inbound' : '⬆ Outbound',
]}
/>
<Legend formatter={(v) => v === 'rx' ? '⬇ Inbound' : '⬆ Outbound'} />
<Line type='monotone' dataKey='rx' stroke='#34d399' dot={false} strokeWidth={2} />
<Line type='monotone' dataKey='tx' stroke='#60a5fa' dot={false} strokeWidth={2} />
</LineChart>
</ResponsiveContainer>
);
}