WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto

feat(web): thread resolvedTheme through admin-themes route factory (ATB-53)

+22 -13
+22 -13
apps/web/src/routes/admin-themes.tsx
··· 8 8 import { isProgrammingError } from "../lib/errors.js"; 9 9 import { logger } from "../lib/logger.js"; 10 10 import { tokensToCss } from "../lib/theme.js"; 11 + import { FALLBACK_THEME, type WebAppEnv } from "../lib/theme-resolution.js"; 11 12 import neobrutalLight from "../styles/presets/neobrutal-light.json"; 12 13 import neobrutalDark from "../styles/presets/neobrutal-dark.json"; 13 14 ··· 234 235 // ─── Route Factory ────────────────────────────────────────────────────────── 235 236 236 237 export function createAdminThemeRoutes(appviewUrl: string) { 237 - const app = new Hono(); 238 + const app = new Hono<WebAppEnv>(); 238 239 239 240 // ── GET /admin/themes ────────────────────────────────────────────────────── 240 241 241 242 app.get("/admin/themes", async (c) => { 243 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 242 244 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 243 245 244 246 if (!auth.authenticated) { ··· 247 249 248 250 if (!canManageThemes(auth)) { 249 251 return c.html( 250 - <BaseLayout title="Access Denied — atBB Forum" auth={auth}> 252 + <BaseLayout title="Access Denied — atBB Forum" auth={auth} resolvedTheme={resolvedTheme}> 251 253 <PageHeader title="Themes" /> 252 254 <p>You don&apos;t have permission to manage themes.</p> 253 255 </BaseLayout>, ··· 313 315 const darkThemes = adminThemes.filter((t) => t.colorScheme === "dark"); 314 316 315 317 return c.html( 316 - <BaseLayout title="Themes — atBB Admin" auth={auth}> 318 + <BaseLayout title="Themes — atBB Admin" auth={auth} resolvedTheme={resolvedTheme}> 317 319 <PageHeader title="Themes" /> 318 320 319 321 {errorMsg && <div class="structure-error-banner">{errorMsg}</div>} ··· 521 523 // ── GET /admin/themes/:rkey ──────────────────────────────────────────────── 522 524 523 525 app.get("/admin/themes/:rkey", async (c) => { 526 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 524 527 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 525 528 if (!auth.authenticated) return c.redirect("/login"); 526 529 if (!canManageThemes(auth)) { 527 530 return c.html( 528 - <BaseLayout title="Access Denied — atBB Admin" auth={auth}> 531 + <BaseLayout title="Access Denied — atBB Admin" auth={auth} resolvedTheme={resolvedTheme}> 529 532 <PageHeader title="Access Denied" /> 530 533 <p>You don&apos;t have permission to manage themes.</p> 531 534 </BaseLayout>, ··· 544 547 const res = await fetch(`${appviewUrl}/api/themes/${themeRkey}`); 545 548 if (res.status === 404) { 546 549 return c.html( 547 - <BaseLayout title="Theme Not Found — atBB Admin" auth={auth}> 550 + <BaseLayout title="Theme Not Found — atBB Admin" auth={auth} resolvedTheme={resolvedTheme}> 548 551 <PageHeader title="Theme Not Found" /> 549 552 <p>This theme does not exist.</p> 550 553 <a href="/admin/themes" class="btn btn-secondary">← Back to themes</a> ··· 579 582 580 583 if (!theme) { 581 584 return c.html( 582 - <BaseLayout title="Theme Unavailable — atBB Admin" auth={auth}> 585 + <BaseLayout title="Theme Unavailable — atBB Admin" auth={auth} resolvedTheme={resolvedTheme}> 583 586 <PageHeader title="Theme Unavailable" /> 584 587 <p>Unable to load theme data. Please try again.</p> 585 588 <a href="/admin/themes" class="btn btn-secondary">← Back to themes</a> ··· 597 600 const fontUrlsText = (theme.fontUrls ?? []).join("\n"); 598 601 599 602 return c.html( 600 - <BaseLayout title={`Edit Theme: ${theme.name} — atBB Admin`} auth={auth}> 603 + <BaseLayout title={`Edit Theme: ${theme.name} — atBB Admin`} auth={auth} resolvedTheme={resolvedTheme}> 601 604 <PageHeader title={`Edit Theme: ${theme.name}`} /> 602 605 603 606 {successMsg && <div class="structure-success-banner">{successMsg}</div>} ··· 750 753 // ── POST /admin/themes ──────────────────────────────────────────────────── 751 754 752 755 app.post("/admin/themes", async (c) => { 756 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 753 757 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 754 758 if (!auth.authenticated) return c.redirect("/login"); 755 759 if (!canManageThemes(auth)) { 756 - return c.html(<BaseLayout title="Access Denied" auth={auth}><p>Access denied.</p></BaseLayout>, 403); 760 + return c.html(<BaseLayout title="Access Denied" auth={auth} resolvedTheme={resolvedTheme}><p>Access denied.</p></BaseLayout>, 403); 757 761 } 758 762 759 763 const cookie = c.req.header("cookie") ?? ""; ··· 815 819 // ── POST /admin/themes/:rkey/duplicate ──────────────────────────────────── 816 820 817 821 app.post("/admin/themes/:rkey/duplicate", async (c) => { 822 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 818 823 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 819 824 if (!auth.authenticated) return c.redirect("/login"); 820 825 if (!canManageThemes(auth)) { 821 - return c.html(<BaseLayout title="Access Denied" auth={auth}><p>Access denied.</p></BaseLayout>, 403); 826 + return c.html(<BaseLayout title="Access Denied" auth={auth} resolvedTheme={resolvedTheme}><p>Access denied.</p></BaseLayout>, 403); 822 827 } 823 828 824 829 const cookie = c.req.header("cookie") ?? ""; ··· 854 859 // ── POST /admin/themes/:rkey/delete ────────────────────────────────────── 855 860 856 861 app.post("/admin/themes/:rkey/delete", async (c) => { 862 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 857 863 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 858 864 if (!auth.authenticated) return c.redirect("/login"); 859 865 if (!canManageThemes(auth)) { 860 - return c.html(<BaseLayout title="Access Denied" auth={auth}><p>Access denied.</p></BaseLayout>, 403); 866 + return c.html(<BaseLayout title="Access Denied" auth={auth} resolvedTheme={resolvedTheme}><p>Access denied.</p></BaseLayout>, 403); 861 867 } 862 868 863 869 const cookie = c.req.header("cookie") ?? ""; ··· 899 905 // ── POST /admin/theme-policy ────────────────────────────────────────────── 900 906 901 907 app.post("/admin/theme-policy", async (c) => { 908 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 902 909 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 903 910 if (!auth.authenticated) return c.redirect("/login"); 904 911 if (!canManageThemes(auth)) { 905 - return c.html(<BaseLayout title="Access Denied" auth={auth}><p>Access denied.</p></BaseLayout>, 403); 912 + return c.html(<BaseLayout title="Access Denied" auth={auth} resolvedTheme={resolvedTheme}><p>Access denied.</p></BaseLayout>, 403); 906 913 } 907 914 908 915 const cookie = c.req.header("cookie") ?? ""; ··· 1003 1010 // ── POST /admin/themes/:rkey/save ───────────────────────────────────────── 1004 1011 1005 1012 app.post("/admin/themes/:rkey/save", async (c) => { 1013 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 1006 1014 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 1007 1015 if (!auth.authenticated) return c.redirect("/login"); 1008 1016 if (!canManageThemes(auth)) { 1009 1017 return c.html( 1010 - <BaseLayout title="Access Denied" auth={auth}> 1018 + <BaseLayout title="Access Denied" auth={auth} resolvedTheme={resolvedTheme}> 1011 1019 <p>Access denied.</p> 1012 1020 </BaseLayout>, 1013 1021 403 ··· 1087 1095 // ── POST /admin/themes/:rkey/reset-to-preset ────────────────────────────── 1088 1096 1089 1097 app.post("/admin/themes/:rkey/reset-to-preset", async (c) => { 1098 + const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; 1090 1099 const auth = await getSessionWithPermissions(appviewUrl, c.req.header("cookie")); 1091 1100 if (!auth.authenticated) return c.redirect("/login"); 1092 1101 if (!canManageThemes(auth)) { 1093 1102 return c.html( 1094 - <BaseLayout title="Access Denied" auth={auth}> 1103 + <BaseLayout title="Access Denied" auth={auth} resolvedTheme={resolvedTheme}> 1095 1104 <p>Access denied.</p> 1096 1105 </BaseLayout>, 1097 1106 403