import { Navigate, createFileRoute } from "@tanstack/react-router"
import { useQuery } from "@tanstack/react-query"
import { useEffect, useRef, useState } from "react"
import type { ReviewerEvalStatus } from "@/lib/api"
import { AppShell, SettingsSection } from "@/components/AppShell"
import { Button } from "@/components/ui/button"
import { Skeleton } from "@/components/ui/skeleton"
import { api } from "@/lib/api"
import { useSession } from "@/lib/session"
export const Route = createFileRoute("/admin_/evals")({ component: ReviewerEvalPage })
function ReviewerEvalPage() {
const session = useSession()
if (session.isLoading) {
return (
)
}
if (!session.data) return
if (!session.data.is_admin) return
return (
)
}
function useReviewerEvalStatus() {
return useQuery({
queryKey: ["reviewerEval"],
queryFn: api.getReviewerEval,
refetchInterval: (query) =>
query.state.data?.status === "running" ? 5000 : false,
})
}
function ReviewerEvalStatusSection() {
const status = useReviewerEvalStatus()
return (
)
}
function progressLabel(data: ReviewerEvalStatus): string | null {
if (!data.progress) return null
const { completed, total } = data.progress
return `${completed} / ${total ?? "?"}`
}
function ReviewerEvalStatusView({ data }: { data: ReviewerEvalStatus | null }) {
if (!data) {
return (
Loading reviewer eval status…
)
}
const config = data.config_snapshot
return (
)
}
function StatusLine({
label,
value,
strong = false,
}: {
label: string
value: string | null | undefined
strong?: boolean
}) {
return (
{label}:{" "}
{value || "—"}
)
}
function ReviewerEvalLogs() {
const status = useReviewerEvalStatus()
const logTail = status.data?.log_tail ?? null
const running = status.data?.status === "running"
const scrollRef = useRef(null)
const [follow, setFollow] = useState(true)
const [copied, setCopied] = useState(false)
useEffect(() => {
if (follow && scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight
}
}, [logTail, follow])
const copyLogs = async () => {
if (!logTail) return
await navigator.clipboard.writeText(logTail)
setCopied(true)
window.setTimeout(() => setCopied(false), 1500)
}
return (
}
>
{logTail ? (
{
const el = e.currentTarget
const atBottom =
el.scrollHeight - el.scrollTop - el.clientHeight < 24
setFollow(atBottom)
}}
className="max-h-[28rem] overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted/50 p-3 font-mono text-xs text-foreground"
>
{logTail}
) : (
{running
? "Waiting for output…"
: "No output yet. Trigger the Reviewer eval GitHub Action to see logs here."}
)}
)
}