Files
Magent/frontend/app/changelog/page.tsx
T

117 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import PageHeading from '../ui/PageHeading'
import { useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/navigation'
import { authFetch, clearToken, getApiBase, getToken } from '../lib/auth'
type SiteInfo = {
changelog?: string
}
type ChangelogGroup = {
date: string
entries: string[]
}
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/
const parseChangelog = (raw: string): ChangelogGroup[] => {
const groups: ChangelogGroup[] = []
for (const rawLine of raw.split('\n')) {
const line = rawLine.trim()
if (!line) continue
const [candidateDate, ...messageParts] = line.split('|')
if (DATE_PATTERN.test(candidateDate) && messageParts.length > 0) {
const message = messageParts.join('|').trim()
if (!message) continue
const currentGroup = groups[groups.length - 1]
if (currentGroup?.date === candidateDate) {
currentGroup.entries.push(message)
} else {
groups.push({ date: candidateDate, entries: [message] })
}
continue
}
if (groups.length === 0) {
groups.push({ date: 'Updates', entries: [line] })
} else {
groups[groups.length - 1].entries.push(line)
}
}
return groups
}
export default function ChangelogPage() {
const router = useRouter()
const [groups, setGroups] = useState<ChangelogGroup[]>([])
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
setGroups(parseChangelog(data?.changelog ?? ''))
} catch (err) {
console.error(err)
if (!active) return
setGroups([])
} finally {
if (active) setLoading(false)
}
}
void load()
return () => {
active = false
}
}, [router])
const content = useMemo(() => {
if (loading) {
return <div className="loading-text">Loading changelog...</div>
}
if (groups.length === 0) {
return <div className="meta">No updates posted yet.</div>
}
return (
<div className="changelog-groups">
{groups.map((group) => (
<section key={group.date} className="changelog-group">
<h2>{group.date}</h2>
<ul className="changelog-list">
{group.entries.map((entry, index) => (
<li key={`${group.date}-${entry}-${index}`}>{entry}</li>
))}
</ul>
</section>
))}
</div>
)
}, [groups, loading])
return (
<main className="card changelog-page">
<PageHeading title="Changelog" description="Whats new and improved in Magent." />
{content}
</main>
)
}