feat: admin provider UI (types, hooks, guard, settings panel, conditional admin nav)

This commit is contained in:
2026-03-16 03:38:37 +01:00
parent 87f94fcc51
commit 89036ba62d
8 changed files with 367 additions and 26 deletions

View File

@@ -1,21 +1,15 @@
"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";
import { ProviderSettingsPanel } from "./components/provider-settings-panel";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
export default function AdminPage() {
const { token, isLoaded } = useAuthContext();
const router = useRouter();
useEffect(() => {
if (isLoaded && !token) {
router.replace("/login");
}
}, [isLoaded, token, router]);
const { token } = useAuthContext();
const { lines, connected } = useServerLogs(token);
const [localLines, setLocalLines] = useState(lines);
@@ -27,8 +21,6 @@ export default function AdminPage() {
const { data: events = [], isLoading } = useActivityLog(token);
if (!isLoaded || !token) return null;
return (
<div className="flex flex-1 flex-col overflow-hidden">
{/* Page header */}
@@ -37,22 +29,47 @@ export default function AdminPage() {
<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([])}
/>
<Tabs defaultValue="logs" className="flex flex-1 flex-col overflow-hidden">
<div className="border-b border-zinc-800 px-6">
<TabsList className="h-9 bg-transparent p-0 gap-1">
<TabsTrigger
value="logs"
className="rounded-none border-b-2 border-transparent px-3 py-1.5 text-xs data-[state=active]:border-zinc-100 data-[state=active]:bg-transparent data-[state=active]:text-zinc-100"
>
Logs
</TabsTrigger>
<TabsTrigger
value="providers"
className="rounded-none border-b-2 border-transparent px-3 py-1.5 text-xs data-[state=active]:border-zinc-100 data-[state=active]:bg-transparent data-[state=active]:text-zinc-100"
>
Providers
</TabsTrigger>
</TabsList>
</div>
{/* Right: activity log */}
<div className="flex w-80 shrink-0 flex-col overflow-hidden">
<ActivityLogPanel events={events} isLoading={isLoading} />
</div>
</div>
<TabsContent value="logs" className="flex min-h-0 flex-1 overflow-hidden mt-0">
{/* 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>
</TabsContent>
<TabsContent value="providers" className="flex-1 overflow-auto mt-0">
<ProviderSettingsPanel />
</TabsContent>
</Tabs>
</div>
);
}