Master API, Admin UI, Go media-node, Docker/Dokploy deploy configs. Co-authored-by: Cursor <cursoragent@cursor.com>
85 lines
2.2 KiB
TypeScript
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>
|
|
</>
|
|
);
|
|
}
|