feat: add server-sent events for logging and activity tracking

- Implemented a custom tracing layer (`AppLogLayer`) to capture log events and broadcast them to SSE clients.
- Created admin routes for streaming server logs and listing recent activity logs.
- Added an activity log repository interface and SQLite implementation for persisting activity events.
- Integrated activity logging into user authentication and channel CRUD operations.
- Developed frontend components for displaying server logs and activity logs in the admin panel.
- Enhanced the video player with a stats overlay for monitoring streaming metrics.
This commit is contained in:
2026-03-16 02:21:40 +01:00
parent 4df6522952
commit e805028d46
28 changed files with 893 additions and 8 deletions

View File

@@ -0,0 +1,58 @@
"use client";
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useAuthContext } from "@/context/auth-context";
import { useActivityLog, useServerLogs } from "@/hooks/use-admin";
import { ServerLogsPanel } from "./components/server-logs-panel";
import { ActivityLogPanel } from "./components/activity-log-panel";
export default function AdminPage() {
const { token, isLoaded } = useAuthContext();
const router = useRouter();
useEffect(() => {
if (isLoaded && !token) {
router.replace("/login");
}
}, [isLoaded, token, router]);
const { lines, connected } = useServerLogs(token);
const [localLines, setLocalLines] = useState(lines);
// Sync external lines into local state so Clear can reset without clearing the hook
useEffect(() => {
setLocalLines(lines);
}, [lines]);
const { data: events = [], isLoading } = useActivityLog(token);
if (!isLoaded || !token) return null;
return (
<div className="flex flex-1 flex-col overflow-hidden">
{/* Page header */}
<div className="flex items-center gap-3 border-b border-zinc-800 px-6 py-4">
<h1 className="text-base font-semibold text-zinc-100">Admin</h1>
<span className="text-xs text-zinc-500">System monitoring &amp; logs</span>
</div>
{/* Two-column layout */}
<div className="flex min-h-0 flex-1 overflow-hidden">
{/* Left: server logs */}
<div className="flex min-w-0 flex-1 flex-col overflow-hidden border-r border-zinc-800">
<ServerLogsPanel
lines={localLines}
connected={connected}
onClear={() => setLocalLines([])}
/>
</div>
{/* Right: activity log */}
<div className="flex w-80 shrink-0 flex-col overflow-hidden">
<ActivityLogPanel events={events} isLoading={isLoading} />
</div>
</div>
</div>
);
}