Spaces:
Running
Running
Download apps/admin/src/app/(dashboard)/observability/errors/page.tsx from Benaah/MicProtocol: direct link, hf CLI and curl.
- Browser
- Download file 7.53 kB
-
https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/admin/src/app/(dashboard)/observability/errors/page.tsx
- Command line
-
hf download 'hf://spaces/Benaah/MicProtocol/apps/admin/src/app/(dashboard)/observability/errors/page.tsx'
-
curl -L -o page.tsx 'https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/admin/src/app/(dashboard)/observability/errors/page.tsx'
7.53 kB
| "use client"; | |
| import React from "react"; | |
| import { AlertCircle, Database, Clock, AlertTriangle } from "lucide-react"; | |
| import { trpc } from "@/lib/trpc"; | |
| import { cn } from "@/lib/utils"; | |
| import { AdminHeader } from "@/components/shell/AdminHeader"; | |
| import { Card, CardContent, CardHeader, CardTitle } from "@micprotocol/ui"; | |
| import { Badge } from "@micprotocol/ui"; | |
| import { Button } from "@micprotocol/ui"; | |
| import { ago } from "@/lib/utils"; | |
| export default function ObservabilityErrorsPage() { | |
| const { data: errors, isLoading } = trpc.audit.list.useQuery( | |
| { limit: 50 }, | |
| { refetchInterval: 30_000 }, | |
| ); | |
| const items = errors?.items ?? []; | |
| const total = items.length; | |
| const critical = items.filter((e: any) => e.severity === "critical").length; | |
| const unresolved = items.filter((e: any) => !e.resolved).length; | |
| const today = items.filter((e: any) => new Date(e.createdAt).toDateString() === new Date().toDateString()).length; | |
| return ( | |
| <div className="animate-fade-in"> | |
| <AdminHeader | |
| title="Error Hub" | |
| subtitle="Platform errors, exceptions, and stack traces" | |
| refreshing={isLoading} | |
| /> | |
| <div className="space-y-6 p-6"> | |
| {/* KPI strip */} | |
| <div className="grid gap-4 sm:grid-cols-4"> | |
| <Card className="p-5 border border-[var(--border-color)]"> | |
| <p className="text-xs font-mono text-[var(--text-secondary)] uppercase tracking-wide">Total Errors</p> | |
| <p className="mt-2 font-display text-2xl font-bold text-[var(--color-error)]">{total}</p> | |
| </Card> | |
| <Card className="p-5 border border-[var(--border-color)]"> | |
| <p className="text-xs font-mono text-[var(--text-secondary)] uppercase tracking-wide">Critical</p> | |
| <p className="mt-2 font-display text-2xl font-bold text-[var(--color-error)]">{critical}</p> | |
| </Card> | |
| <Card className="p-5 border border-[var(--border-color)]"> | |
| <p className="text-xs font-mono text-[var(--text-secondary)] uppercase tracking-wide">Unresolved</p> | |
| <p className="mt-2 font-display text-2xl font-bold text-[var(--color-warning)]">{unresolved}</p> | |
| </Card> | |
| <Card className="p-5 border border-[var(--border-color)]"> | |
| <p className="text-xs font-mono text-[var(--text-secondary)] uppercase tracking-wide">Today</p> | |
| <p className="mt-2 font-display text-2xl font-bold text-[var(--color-info)]">{today}</p> | |
| </Card> | |
| </div> | |
| {/* Errors table */} | |
| <Card> | |
| <CardHeader> | |
| <CardTitle className="flex items-center gap-2"> | |
| <AlertCircle className="size-4 text-[var(--color-error)]" /> Recent Errors | |
| </CardTitle> | |
| </CardHeader> | |
| <CardContent className="p-0"> | |
| <div className="-mx-4 -my-2 overflow-x-auto"> | |
| <table className="w-full text-left border-collapse"> | |
| <thead> | |
| <tr className="border-b border-[var(--border-color-subtle)]"> | |
| <th className="pb-3 text-[var(--text-tertiary)] text-xs uppercase tracking-wider font-medium w-24">Error ID</th> | |
| <th className="pb-3 text-[var(--text-tertiary)] text-xs uppercase tracking-wider font-medium w-24">Message</th> | |
| <th className="pb-3 text-[var(--text-tertiary)] text-xs uppercase tracking-wider font-medium text-center w-20">Severity</th> | |
| <th className="pb-3 text-[var(--text-tertiary)] text-xs uppercase tracking-wider font-medium text-center w-20">Status</th> | |
| <th className="pb-3 text-[var(--text-tertiary)] text-xs uppercase tracking-wider font-medium w-24">Source</th> | |
| <th className="pb-3 text-[var(--text-tertiary)] text-xs uppercase tracking-wider font-medium text-right w-28">Occurred</th> | |
| <th className="pb-3 text-[var(--text-tertiary)] text-xs uppercase tracking-wider font-medium text-right w-24">Actions</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {isLoading ? ( | |
| [...Array(5)].map((_, i) => ( | |
| <tr key={i} className="border-b border-[var(--border-color-subtle)]"> | |
| <td colSpan={7} className="py-12 text-center text-[var(--text-tertiary)]"> | |
| <div className="skeleton w-full h-16 mx-auto max-w-xs" /> | |
| </td> | |
| </tr> | |
| )) | |
| ) : items.length === 0 ? ( | |
| <tr> | |
| <td colSpan={7} className="py-12 text-center text-[var(--text-tertiary)]"> | |
| No errors recorded. Platform is healthy. | |
| </td> | |
| </tr> | |
| ) : ( | |
| items.map((e: any) => ( | |
| <tr key={e.id} className="border-b border-[var(--border-color-subtle)] hover:bg-[var(--bg-tertiary)]/30 transition-colors"> | |
| <td className="py-4 font-mono text-xs text-[var(--text-secondary)]"> | |
| {e.id.slice(0, 8)}… | |
| </td> | |
| <td className="py-4 text-xs text-[var(--text-secondary)] truncate" style={{ maxWidth: 220 }}> | |
| {e.message ?? "—"} | |
| </td> | |
| <td className="py-4 text-xs text-center"> | |
| <Badge className={cn("capitalize text-xs", severityClass(e.severity))}> | |
| {e.severity} | |
| </Badge> | |
| </td> | |
| <td className="py-4 text-xs text-center"> | |
| <Badge className={cn("capitalize text-xs", e.resolved ? "bg-[var(--color-success)]/20 border-[var(--color-success)]/30 text-[var(--color-success)]" : "border-transparent text-[var(--text-tertiary)]")}> | |
| {e.resolved ? "resolved" : "open"} | |
| </Badge> | |
| </td> | |
| <td className="py-4 text-xs text-[var(--text-secondary)] font-mono truncate" style={{ maxWidth: 150 }}> | |
| {e.source ?? "—"} | |
| </td> | |
| <td className="py-4 text-xs text-[var(--text-tertiary)] text-right"> | |
| {new Date(e.createdAt).toLocaleString()} | |
| </td> | |
| <td className="py-4 text-sm text-right"> | |
| <Button variant="ghost" size="sm" disabled={e.resolved} onClick={() => {}}> | |
| <AlertTriangle size={14} className="mr-1" /> | |
| </Button> | |
| </td> | |
| </tr> | |
| )) | |
| )} | |
| </tbody> | |
| </table> | |
| </div> | |
| </CardContent> | |
| </Card> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| function severityClass(s: string): string { | |
| switch (s) { | |
| case "critical": return "bg-[var(--color-error)] border-[var(--color-error)] text-[var(--text-primary)]"; | |
| case "high": return "bg-[var(--color-error)]/10 border-[var(--color-error)]/20 text-[var(--color-error)]"; | |
| case "medium": return "bg-[var(--color-warning)]/10 border-[var(--color-warning)]/20 text-[var(--color-warning)]"; | |
| case "low": return "bg-[var(--color-info)]/10 border-[var(--color-info)]/20 text-[var(--color-info)]"; | |
| default: return "border-transparent"; | |
| } | |
| } | |