feat(ui): redesign UI with Tailwind CSS, CodeMirror 6, and new layout

- Replace all hand-written CSS with Tailwind utility classes
- Upgrade CodeMirror 5 to CodeMirror 6 (scoped @codemirror/* packages)
- Redesign layout with responsive sidebar navigation using JSX/Mithril
- Flatten admin routes (e.g. /admin/presets -> /presets)
- Add "remember me" login option with 2-week persistent cookie
- Add delete confirmation dialogs across admin pages
- Upgrade esbuild from 0.21 to 0.27 and update browser targets
- Add Inter and Roboto Mono variable fonts with subset script
This commit is contained in:
Zaid Humaimidi committed 2026-03-12 14:55:10 -07:00
1 parent a7256620e0
commit 4a191afdec
64 files changed
+4147 -2421

No files matched your search

+4 -4
View File
@@ -1,8 +1,8 @@
import { complement } from "espresso-iisojs";
import { Expression } from "../../types";
import normalize from "./normalize";
import { Clause, SynthContext } from "./synth";
import { and, or } from "./util";
import { Expression } from "../../types.ts";
import normalize from "./normalize.ts";
import { Clause, SynthContext } from "./synth.ts";
import { and, or } from "./util.ts";
type Bookmark = Record<string, null | boolean | number | string>;
+12 -3
View File
@@ -105,6 +105,9 @@ router.post("/login", async (ctx) => {
const username = ctx.request.body.username;
const password = ctx.request.body.password;
const remember = ctx.request.body.remember;
const TWO_WEEKS_SECS = 1209600;
const ONE_DAY_SECS = 86400;
const log = {
message: "Log in",
@@ -115,8 +118,14 @@ router.post("/login", async (ctx) => {
function success(authMethod): void {
log.method = authMethod;
const token = jwt.sign({ username, authMethod }, JWT_SECRET);
ctx.cookies.set(JWT_COOKIE, token, { sameSite: "lax" });
const expiresIn = remember ? TWO_WEEKS_SECS : ONE_DAY_SECS;
const token = jwt.sign({ username, authMethod }, JWT_SECRET, {
expiresIn,
});
ctx.cookies.set(JWT_COOKIE, token, {
sameSite: "lax",
maxAge: remember ? expiresIn * 1000 : null,
});
ctx.body = JSON.stringify(token);
logger.accessInfo(log);
}
@@ -219,7 +228,7 @@ router.get("/", async (ctx) => {
<link rel="shortcut icon" type="image/png" href="${FAVICON_PNG}" />
<link rel="stylesheet" href="${APP_CSS}">
</head>
<body>
<body class="h-full bg-stone-100">
<noscript>GenieACS UI requires JavaScript to work. Please enable JavaScript in your browser.</noscript>
<script>
window.clientConfig = ${JSON.stringify({