Fix dashboard BigInt crash when storage fields are missing.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
39ecf1af56
commit
9b557cee54
2 changed files with 39 additions and 15 deletions
|
|
@ -15,10 +15,17 @@ interface Dashboard {
|
|||
currentBandwidth: string;
|
||||
}
|
||||
|
||||
function formatBytes(bytes: string): string {
|
||||
const n = BigInt(bytes);
|
||||
function formatBytes(bytes: string | number | null | undefined): string {
|
||||
if (bytes === null || bytes === undefined || bytes === "") return "0 B";
|
||||
let n: bigint;
|
||||
try {
|
||||
n = typeof bytes === "bigint" ? bytes : BigInt(String(bytes));
|
||||
} catch {
|
||||
return "0 B";
|
||||
}
|
||||
const units = ["B", "KB", "MB", "GB", "TB"];
|
||||
let val = Number(n);
|
||||
if (!Number.isFinite(val)) return "0 B";
|
||||
let i = 0;
|
||||
while (val >= 1024 && i < units.length - 1) {
|
||||
val /= 1024;
|
||||
|
|
@ -30,12 +37,21 @@ function formatBytes(bytes: string): string {
|
|||
export default function DashboardPage() {
|
||||
useAuth();
|
||||
const [data, setData] = useState<Dashboard | null>(null);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/v1/admin/dashboard", { credentials: "include" })
|
||||
.then((r) => r.json())
|
||||
.then(setData)
|
||||
.catch(console.error);
|
||||
.then(async (r) => {
|
||||
const json = await r.json();
|
||||
if (!r.ok) {
|
||||
throw new Error(json.error?.message ?? `HTTP ${r.status}`);
|
||||
}
|
||||
setData(json);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
setError(err instanceof Error ? err.message : "Laden mislukt");
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
@ -43,42 +59,48 @@ export default function DashboardPage() {
|
|||
<Nav />
|
||||
<div className="container">
|
||||
<h1 style={{ marginBottom: "2rem", fontSize: "1.75rem" }}>Dashboard</h1>
|
||||
{error && <div className="error">{error}</div>}
|
||||
{data && (
|
||||
<div className="grid">
|
||||
<div className="card">
|
||||
<h2>Nodes Online</h2>
|
||||
<div className="value">{data.nodesOnline}</div>
|
||||
<div className="value">{data.nodesOnline ?? 0}</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2>Nodes Offline</h2>
|
||||
<div className="value">{data.nodesOffline}</div>
|
||||
<div className="value">{data.nodesOffline ?? 0}</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2>Movies</h2>
|
||||
<div className="value">{data.movies}</div>
|
||||
<div className="value">{data.movies ?? 0}</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2>Series</h2>
|
||||
<div className="value">{data.series}</div>
|
||||
<div className="value">{data.series ?? 0}</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2>Episodes</h2>
|
||||
<div className="value">{data.episodes}</div>
|
||||
<div className="value">{data.episodes ?? 0}</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2>Active Streams</h2>
|
||||
<div className="value">{data.activeStreams}</div>
|
||||
<div className="value">{data.activeStreams ?? 0}</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2>Total Storage</h2>
|
||||
<div className="value" style={{ fontSize: "1.5rem" }}>{formatBytes(data.totalStorage)}</div>
|
||||
<div className="value" style={{ fontSize: "1.5rem" }}>
|
||||
{formatBytes(data.totalStorage)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="card">
|
||||
<h2>Free Storage</h2>
|
||||
<div className="value" style={{ fontSize: "1.5rem" }}>{formatBytes(data.freeStorage)}</div>
|
||||
<div className="value" style={{ fontSize: "1.5rem" }}>
|
||||
{formatBytes(data.freeStorage)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!data && !error && <p style={{ color: "#71717a" }}>Laden...</p>}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -29,8 +29,10 @@ interface Movie {
|
|||
files: MovieFile[];
|
||||
}
|
||||
|
||||
function formatBytes(bytes: string): string {
|
||||
let val = Number(bytes);
|
||||
function formatBytes(bytes: string | number | null | undefined): string {
|
||||
const valNum = Number(bytes ?? 0);
|
||||
if (!Number.isFinite(valNum) || valNum < 0) return "0 B";
|
||||
let val = valNum;
|
||||
const units = ["B", "KB", "MB", "GB", "TB"];
|
||||
let i = 0;
|
||||
while (val >= 1024 && i < units.length - 1) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue