stremio/apps/admin-ui/src/app/streams/page.tsx
Jos Vooges | STH a5c6fd5fe4 Initial commit: Distributed Stremio Media Cluster V1
Master API, Admin UI, Go media-node, Docker/Dokploy deploy configs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-25 00:17:04 +02:00

85 lines
2.2 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { Nav, useAuth } from "@/components/Nav";
interface Stream {
id: string;
node: string;
status: string;
createdAt: string;
lastActivity: string;
absoluteExpiresAt: string;
title: string;
resolution: string | null;
}
export default function StreamsPage() {
useAuth();
const [streams, setStreams] = useState<Stream[]>([]);
function load() {
fetch("/api/v1/admin/streams", { credentials: "include" })
.then((r) => r.json())
.then((d) => setStreams(d.streams ?? []));
}
useEffect(() => {
load();
const t = setInterval(load, 10000);
return () => clearInterval(t);
}, []);
async function revoke(id: string) {
if (!confirm("Playback-sessie intrekken?")) return;
await fetch(`/api/v1/admin/streams/${id}/revoke`, {
method: "POST",
credentials: "include",
});
load();
}
return (
<>
<Nav />
<div className="container">
<h1 style={{ marginBottom: "2rem", fontSize: "1.75rem" }}>Actieve streams</h1>
<div className="card">
<table>
<thead>
<tr>
<th>Titel</th>
<th>Node</th>
<th>Kwaliteit</th>
<th>Laatste activiteit</th>
<th>Acties</th>
</tr>
</thead>
<tbody>
{streams.map((s) => (
<tr key={s.id}>
<td>{s.title}</td>
<td>{s.node}</td>
<td>{s.resolution ?? "-"}</td>
<td>{new Date(s.lastActivity).toLocaleString()}</td>
<td>
<button className="danger" onClick={() => revoke(s.id)}>
Intrekken
</button>
</td>
</tr>
))}
{streams.length === 0 && (
<tr>
<td colSpan={5} style={{ textAlign: "center", color: "#71717a" }}>
Geen actieve streams
</td>
</tr>
)}
</tbody>
</table>
</div>
</div>
</>
);
}