feat(release): publish minimal self-contained Magent source

This commit is contained in:
Magent release tooling
2026-09-19 16:58:12 +12:00
commit 5fa5d45535
272 changed files with 79305 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
"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>
);
}