'use client' import { useEffect, useMemo, useState } from 'react' import { useRouter } from 'next/navigation' import { authFetch, clearToken, getApiBase, getToken } from '../lib/auth' type SiteInfo = { changelog?: string } const parseChangelog = (raw: string) => raw .split('\n') .map((line) => line.trim()) .filter(Boolean) export default function ChangelogPage() { const router = useRouter() const [entries, setEntries] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { const token = getToken() if (!token) { router.push('/login') return } let active = true const load = async () => { try { const baseUrl = getApiBase() const response = await authFetch(`${baseUrl}/site/info`) if (!response.ok) { if (response.status === 401) { clearToken() router.push('/login') return } throw new Error('Failed to load changelog') } const data: SiteInfo = await response.json() if (!active) return setEntries(parseChangelog(data?.changelog ?? '')) } catch (err) { console.error(err) if (!active) return setEntries([]) } finally { if (active) setLoading(false) } } void load() return () => { active = false } }, [router]) const content = useMemo(() => { if (loading) { return
Loading changelog...
} if (entries.length === 0) { return
No updates posted yet.
} return ( ) }, [entries, loading]) return (

Changelog

Latest updates and release notes.

{content}
) }