Wire orphan routes into hub tabs, group Radio into primary/tools rows, show theme/language once on desktop, and remove duplicate page titles under AdminHubChrome.
Co-authored-by: Cursor <[email protected]>
- Add panel_border_color to THEME_COLOR_KEYS and base palettes
- Register panel-border-color CSS variable
- Fetch and inject panel_border_color in ThemeVars
- Add Panel border field to admin theme page
- Replace hardcoded #e9b124 with var(--panel-border-color) in UserView
Light admin derives from the public light theme; dark keeps HK overrides. Remap inputs, cards, muted text, and kill the public wallpaper on admin so fonts and boxes stay readable in both modes.
Co-authored-by: Cursor <[email protected]>
Gate pages and mutations on module PERMS instead of dashboard-only staff checks, add radio view/edit slugs with migration 0015, and expand the operations contract tests.
Co-authored-by: Cursor <[email protected]>
- New client ColorField component shows a live 'Aa' text preview on the
relevant background and a WCAG contrast ratio badge (✓ / ⚠)
- Flags low-contrast (<4.5:1) text fields with a red border and a
one-click 'Use readable color' fix
- Map each text color to the background it sits on (body text -> surface,
button text -> button color, navbar text -> navbar, admin text -> canvas)
- Add a description to every color field explaining what it affects
- Regroup colors into Page & text / Buttons & links / Gradients with
explanatory section intros for both light and dark mode
- Add section intros for light, dark, and admin (HK) modes
- Widen color field layout and show descriptions under each label
- Add 6 new admin color DB keys (admin_canvas, admin_surface, admin_text,
admin_text_muted, admin_border, admin_sidebar_bg) that override the
derived admin palette
- Extract adminPaletteCss() from themePaletteCss() for reuse
- Generate admin CSS variables in both :root and html.dark with overrides
- Persist admin color settings via saveTheme action
- Add Admin panel (HK) section to /admin/theme with color pickers
- Remove production DB dump (db_backup_*.sql) and update.log from git tracking
- Add DB backups to .gitignore
- Replace all console.log/console.error with structured logger module
- Translate Dutch error messages to English (link-discord.ts)
- Remove dead code blocks (register-form.tsx false && pattern)
- Add ESLint flat config with TypeScript, React, Next.js, jsx-a11y, and security plugins
- Add Prettier config
- Add eslint-plugin-security for security-aware linting
- Fix all 119+ ESLint warnings across the codebase:
- Resolve security/detect-object-injection with safe access patterns
- Resolve security/detect-non-literal-fs-filename with path traversal validation
- Replace <img> with next/image <Image> component
- Remove unused variables and imports
- Replace non-null assertions with proper type guards
- Replace <a> with <Link> for internal navigation
- Use next/script Script component for external scripts
- Fix setState-in-useEffect anti-patterns (navbar-color-picker, logo-generator, theme-switcher)
- Add lint and format scripts to package.json
All checks: typecheck ✓, tests 58/58 ✓, lint 0 errors 0 warnings ✓
Grew /admin/theme from colours-only to a full theme editor, all applied
live via website_settings + ThemeVars:
- Typography: body font (10 web-safe + Google options; Google fonts load
via an injected <link>) and H1/H2/H3 sizes (globals.css now reads
--size-heading-* vars).
- Buttons & links: secondary/danger button colours + link/link-hover.
- Custom CSS: a raw textarea injected after the theme variables (staff-
trusted), for anything the controls don't cover.
- Presets: 6 → 13 (added Galaxy, Royal, Cyberpunk, Neon, Coffee, Arctic,
Christmas). ThemeVars now injects all the new vars + the font link.
Verified live (prod, amx_test): saved font=mono / H1=44px / custom CSS →
the public home reflected --font-family "Courier New", --size-heading-h1
44px and the injected rule; reverted the test settings. tsc 0,
vitest 49/49, next build 0.
- New /admin/theme: recolour the whole site from housekeeping. 6 atom-
faithful presets (Atom/Midnight/Ocean/Forest/Sunset/Candy) + per-colour
pickers for the 12 settings ThemeVars injects + border radius. Writes to
website_settings, busts the siteSettings cache, and revalidates the
layout so the new palette applies live with no rebuild. Constants live
in src/lib/theme-presets.ts (a "use server" file can't export objects).
Added to the admin sidebar (System).
- radio/contests/[id] + giveaways/[id] wrapped in ContentCard to match
the public design system.
- Skipped a separate VPN page: /admin/ip already manages the IP
white/blacklist, so it would only duplicate it.
Verified live (prod, amx_test): applied the Ocean preset → home renders
--color-primary #0ea5e9 site-wide; reverted the test rows. tsc 0,
vitest 49/49, next build 0.