Ops-dashboard/app/caddy/page.tsx
Janpeter Visser 84d7bb0add fix(caddy): val terug op nginx-grammar voor Caddyfile syntax-highlighting
Shiki 1.29 bundelt geen 'caddyfile' grammar — runtime error "Language
'caddyfile' is not included in this bundle". Nginx-grammar is syntactisch
het dichtst bij (directives + nested braces + reverse_proxy lijkt op
location-blocks), dus levert acceptabele kleuring zonder dependency
toe te voegen. Echte Caddyfile-grammar zou via een externe TextMate
JSON moeten worden geladen — later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:29:34 +02:00

72 lines
2.4 KiB
TypeScript

import { redirect } from 'next/navigation'
import Link from 'next/link'
import { codeToHtml } from 'shiki'
import { getCurrentUser } from '@/lib/session'
import { execAgent } from '@/lib/agent-client'
import { parseCertList, type CertInfo } from '@/lib/parse-caddy'
import CaddyView from './_components/caddy-view'
export const dynamic = 'force-dynamic'
export default async function CaddyPage() {
const user = await getCurrentUser()
if (!user) redirect('/login')
let configHtml = ''
let configError: string | null = null
try {
const raw = await execAgent('caddy_show_config')
// shiki 1.29 bundelt geen caddyfile-grammar; nginx is syntactisch het
// dichtst bij (directives + braces + reverse_proxy lijkt op locations)
configHtml = await codeToHtml(raw || '# (empty)', {
lang: 'nginx',
theme: 'github-dark',
})
} catch (err) {
configError = err instanceof Error ? err.message : 'failed'
}
let initialCerts: CertInfo[] = []
let certsError: string | null = null
try {
const raw = await execAgent('caddy_list_certs')
initialCerts = parseCertList(raw)
} catch (err) {
certsError = err instanceof Error ? err.message : 'failed'
}
return (
<div className="min-h-screen bg-background p-6">
<div className="mx-auto max-w-6xl space-y-8">
<div>
<h1 className="text-2xl font-semibold tracking-tight">Caddy</h1>
<p className="text-sm text-muted-foreground">Config view and TLS certificate status</p>
</div>
<section className="space-y-3">
<div className="flex items-center justify-between">
<h2 className="text-lg font-medium tracking-tight">Caddyfile</h2>
<Link
href="/caddy/edit"
className="rounded-md border border-border px-3 py-1 text-xs hover:bg-muted/50 transition-colors"
>
Edit
</Link>
</div>
{configError ? (
<div className="rounded-lg border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive">
{configError}
</div>
) : (
<div
className="overflow-x-auto rounded-lg border border-border text-sm [&>pre]:p-4"
dangerouslySetInnerHTML={{ __html: configHtml }}
/>
)}
</section>
<CaddyView initialCerts={initialCerts} certsError={certsError} />
</div>
</div>
)
}