second version

This commit is contained in:
Dusan Vojacek
2026-04-03 14:23:16 +02:00
parent 897b95f728
commit 9f4126946d
105 changed files with 9738 additions and 1470 deletions

View File

@@ -0,0 +1,63 @@
import { useEffect, useRef, useState } from 'react'
type LogRecord = {
ts?: string
level?: string
logger?: string
msg?: string
}
export function Logs() {
const [lines, setLines] = useState<LogRecord[]>([])
const bottomRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const ws = new WebSocket(`${proto}//${window.location.host}/ws/logs`)
ws.onmessage = (ev) => {
try {
const rec = JSON.parse(ev.data as string) as LogRecord
setLines((prev) => {
const next = [...prev, rec]
return next.length > 500 ? next.slice(-500) : next
})
} catch {
/* ignore */
}
}
return () => ws.close()
}, [])
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
}, [lines.length])
return (
<div className="min-h-screen bg-slate-950 p-4 text-slate-100 md:p-8">
<div className="mx-auto max-w-5xl">
<h1 className="text-xl font-bold text-white">Logy EMS</h1>
<p className="mt-1 text-sm text-slate-500">Stream z backendu (WebSocket)</p>
<pre className="mt-6 max-h-[calc(100vh-8rem)] overflow-auto rounded-xl border border-slate-800 bg-slate-900/80 p-4 font-mono text-xs leading-relaxed">
{lines.map((r, i) => (
<div
key={`${i}-${r.ts}-${r.msg}`}
className={
r.level === 'ERROR'
? 'text-red-300'
: r.level === 'WARNING'
? 'text-amber-200'
: 'text-slate-300'
}
>
<span className="text-slate-600">{r.ts ?? '—'} </span>
<span className="text-slate-500">[{r.level ?? '?'}] </span>
<span className="text-slate-500">{r.logger ?? ''}: </span>
{r.msg ?? ''}
</div>
))}
<div ref={bottomRef} />
</pre>
</div>
</div>
)
}