From 92fe23d461410ff0a08cc811acc8ff53def89789 Mon Sep 17 00:00:00 2001 From: Till JS Date: Tue, 21 Apr 2026 18:53:46 +0200 Subject: [PATCH] feat(apps): admin panels + module settings as workbench cards Convert 8 admin/settings subroutes into scene-droppable workbench cards so users can arrange them alongside other modules instead of navigating to dedicated subroutes. Admin cards (admin-role-gated inline, fallback gate-screen for non-admins): - admin-users: user search + paginated table - admin-system: service-health grid + monitoring links + env info - admin-user-data: API-backed user browser (detail route stays) - admin-complexity: route now wraps the existing complexity card Module-settings cards (wrap existing form components where available): - broadcast-settings, invoices-settings: wrap SettingsForm / SenderProfileForm - uload-settings: data-stats + JSON export + clear-local-data danger zone - news-preferences: topics/languages/weights/onboarding reset All 8 subroutes reduced to 10-line ListView wrappers; admin layout keeps the role guard so the routes are still gated on direct access. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../apps/web/src/lib/app-registry/apps.ts | 74 +++ .../lib/modules/admin-system/ListView.svelte | 349 +++++++++++++ .../modules/admin-user-data/ListView.svelte | 488 ++++++++++++++++++ .../lib/modules/admin-users/ListView.svelte | 267 ++++++++++ .../broadcast-settings/ListView.svelte | 40 ++ .../modules/invoices-settings/ListView.svelte | 40 ++ .../modules/news-preferences/ListView.svelte | 231 +++++++++ .../modules/uload-settings/ListView.svelte | 203 ++++++++ .../(app)/admin/complexity/+page.svelte | 78 +-- .../routes/(app)/admin/system/+page.svelte | 176 +------ .../routes/(app)/admin/user-data/+page.svelte | 249 +-------- .../src/routes/(app)/admin/users/+page.svelte | 158 +----- .../(app)/broadcasts/settings/+page.svelte | 40 +- .../(app)/invoices/settings/+page.svelte | 40 +- .../(app)/news/preferences/+page.svelte | 217 +------- .../routes/(app)/uload/settings/+page.svelte | 110 +--- 16 files changed, 1742 insertions(+), 1018 deletions(-) create mode 100644 apps/mana/apps/web/src/lib/modules/admin-system/ListView.svelte create mode 100644 apps/mana/apps/web/src/lib/modules/admin-user-data/ListView.svelte create mode 100644 apps/mana/apps/web/src/lib/modules/admin-users/ListView.svelte create mode 100644 apps/mana/apps/web/src/lib/modules/broadcast-settings/ListView.svelte create mode 100644 apps/mana/apps/web/src/lib/modules/invoices-settings/ListView.svelte create mode 100644 apps/mana/apps/web/src/lib/modules/news-preferences/ListView.svelte create mode 100644 apps/mana/apps/web/src/lib/modules/uload-settings/ListView.svelte diff --git a/apps/mana/apps/web/src/lib/app-registry/apps.ts b/apps/mana/apps/web/src/lib/app-registry/apps.ts index c40b57c7b..5c874c392 100644 --- a/apps/mana/apps/web/src/lib/app-registry/apps.ts +++ b/apps/mana/apps/web/src/lib/app-registry/apps.ts @@ -1165,6 +1165,36 @@ registerApp({ }, }); +registerApp({ + id: 'admin-users', + name: 'Admin · Users', + color: '#EF4444', + icon: AddressBook, + views: { + list: { load: () => import('$lib/modules/admin-users/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'admin-system', + name: 'Admin · System', + color: '#EF4444', + icon: HardDrives, + views: { + list: { load: () => import('$lib/modules/admin-system/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'admin-user-data', + name: 'Admin · User Data', + color: '#EF4444', + icon: File, + views: { + list: { load: () => import('$lib/modules/admin-user-data/ListView.svelte') }, + }, +}); + registerApp({ id: 'complexity', name: 'Complexity', @@ -1288,6 +1318,50 @@ registerApp({ }, }); +// ── Module-Settings Cards ──────────────────────────── +// Per-module settings/preferences as workbench cards so they can be +// dropped into any scene without a subroute. + +registerApp({ + id: 'broadcast-settings', + name: 'Broadcast · Settings', + color: '#6366f1', + icon: Gear, + views: { + list: { load: () => import('$lib/modules/broadcast-settings/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'invoices-settings', + name: 'Invoices · Settings', + color: '#059669', + icon: Gear, + views: { + list: { load: () => import('$lib/modules/invoices-settings/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'uload-settings', + name: 'uLoad · Settings', + color: '#0EA5E9', + icon: Gear, + views: { + list: { load: () => import('$lib/modules/uload-settings/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'news-preferences', + name: 'News · Preferences', + color: '#10B981', + icon: Gear, + views: { + list: { load: () => import('$lib/modules/news-preferences/ListView.svelte') }, + }, +}); + registerApp({ id: 'quiz', name: 'Quiz', diff --git a/apps/mana/apps/web/src/lib/modules/admin-system/ListView.svelte b/apps/mana/apps/web/src/lib/modules/admin-system/ListView.svelte new file mode 100644 index 000000000..ecdcfa961 --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/admin-system/ListView.svelte @@ -0,0 +1,349 @@ + + + +{#if !isAdmin} +
+ +

Admin-only

+

Die System-Übersicht ist nur für Admin-Nutzer sichtbar.

+
+{:else} +
+
+
+

System Status

+ {#if !loading} +
+ + {healthyCount}/{totalCount} healthy +
+ {/if} +
+ + {#if loading} +
+ {#each Array(8) as _} +
+ {/each} +
+ {:else} +
+ {#each services as service} +
+ +
+

{service.name}

+

{statusLabels[service.status]}

+
+ {#if service.url !== '-'} + + + + {/if} +
+ {/each} +
+ {/if} +
+ + + +
+

Environment

+
+
+
+ Server + Mac Mini (mana.how) +
+
+ Domain + *.mana.how +
+
+ SSL + Caddy (Auto) +
+
+
+
+ Database + PostgreSQL 16 +
+
+ Cache + Redis 7 +
+
+ Tunnel + Cloudflare +
+
+
+
+
+{/if} + + diff --git a/apps/mana/apps/web/src/lib/modules/admin-user-data/ListView.svelte b/apps/mana/apps/web/src/lib/modules/admin-user-data/ListView.svelte new file mode 100644 index 000000000..3e15a487f --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/admin-user-data/ListView.svelte @@ -0,0 +1,488 @@ + + + +{#if !isAdmin} +
+ +

Admin-only

+

Der Nutzerdaten-Browser ist nur für Admin-Nutzer sichtbar.

+
+{:else} +
+
+
+ Nutzerdaten + {total} Nutzer +
+ +
+ +
+ {#if loading} +
+ {#each Array(5) as _} +
+
+
+
+
+
+
+ {/each} +
+ {:else if error} +
+

{error}

+ +
+ {:else if users.length === 0} +

Keine Nutzer gefunden.

+ {:else} +
+ + + + + + + + + + + + {#each users as user} + + + + + + + + {/each} + +
NutzerRolleRegistriertLetzte Aktivität
+
+
+ {(user.name || user.email)[0].toUpperCase()} +
+
+

{user.name || '—'}

+

{user.email}

+
+
+
+ + {user.role} + + {formatDate(user.createdAt)}{formatRelativeTime(user.lastActiveAt)} + +
+
+ + {#if totalPages > 1} + + {/if} + {/if} +
+
+{/if} + + diff --git a/apps/mana/apps/web/src/lib/modules/admin-users/ListView.svelte b/apps/mana/apps/web/src/lib/modules/admin-users/ListView.svelte new file mode 100644 index 000000000..e2125d2cc --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/admin-users/ListView.svelte @@ -0,0 +1,267 @@ + + + +{#if !isAdmin} +
+ +

Admin-only

+

Die Nutzerverwaltung ist nur für Admin-Nutzer sichtbar.

+
+{:else} +
+
+
+ Users + {filteredUsers.length} / {users.length} +
+ +
+ + + + {#if totalPages > 1} + + {/if} + + {#if error} +

{error}

+ {/if} +
+{/if} + + diff --git a/apps/mana/apps/web/src/lib/modules/broadcast-settings/ListView.svelte b/apps/mana/apps/web/src/lib/modules/broadcast-settings/ListView.svelte new file mode 100644 index 000000000..397367851 --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/broadcast-settings/ListView.svelte @@ -0,0 +1,40 @@ + + + +
+
+
+ Broadcast-Einstellungen + Sender-Defaults, Impressum und Footer +
+
+ +
+ + diff --git a/apps/mana/apps/web/src/lib/modules/invoices-settings/ListView.svelte b/apps/mana/apps/web/src/lib/modules/invoices-settings/ListView.svelte new file mode 100644 index 000000000..9e26797b0 --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/invoices-settings/ListView.svelte @@ -0,0 +1,40 @@ + + + +
+
+
+ Rechnungs-Einstellungen + Absender, Nummernkreis und Standards +
+
+ +
+ + diff --git a/apps/mana/apps/web/src/lib/modules/news-preferences/ListView.svelte b/apps/mana/apps/web/src/lib/modules/news-preferences/ListView.svelte new file mode 100644 index 000000000..582654400 --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/news-preferences/ListView.svelte @@ -0,0 +1,231 @@ + + + +
+
+
+ News-Einstellungen + Themen · Sprachen · Gewichtungen +
+
+ +
+

Themen

+

Welche Themen sollen im Feed auftauchen?

+
+ {#each ALL_TOPICS as topic} + + {/each} +
+
+ +
+

Sprachen

+
+ + +
+
+ +
+

Quellen

+

+ Du blockst aktuell {prefs.blockedSources.length} Quellen. +

+ Quellen verwalten → +
+ +
+

Gelernte Gewichtungen

+

+ Über Reaktionen lernt der Feed deine Vorlieben: + {topicWeightCount} Themen-Gewichte, {sourceWeightCount} Quellen-Gewichte. +

+ +
+ +
+

Onboarding

+

Themen, Sprachen und Quellen neu wählen.

+ +
+
+ + diff --git a/apps/mana/apps/web/src/lib/modules/uload-settings/ListView.svelte b/apps/mana/apps/web/src/lib/modules/uload-settings/ListView.svelte new file mode 100644 index 000000000..d50210b63 --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/uload-settings/ListView.svelte @@ -0,0 +1,203 @@ + + + +
+
+
+ uLoad-Einstellungen + Datenübersicht · Export · Gefahrenzone +
+
+ +
+

Daten

+
+
+

{links.value?.length ?? 0}

+

Links

+
+
+

{tags.value?.length ?? 0}

+

Tags

+
+
+

{folders.value?.length ?? 0}

+

Ordner

+
+
+
+ +
+

Daten exportieren

+

Alle Links, Tags und Ordner als JSON-Datei herunterladen.

+ +
+ +
+

Gefahrenzone

+

+ Löscht alle lokalen uLoad-Daten (Links, Tags, Ordner). Synchronisierte Daten auf dem Server + bleiben erhalten. +

+ +
+
+ + diff --git a/apps/mana/apps/web/src/routes/(app)/admin/complexity/+page.svelte b/apps/mana/apps/web/src/routes/(app)/admin/complexity/+page.svelte index ecbc5ba7c..12d2bf84e 100644 --- a/apps/mana/apps/web/src/routes/(app)/admin/complexity/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/admin/complexity/+page.svelte @@ -1,75 +1,11 @@ -
-
-
-

Complexity Map

-

- Interactive treemap of the entire codebase. Area = lines of code, color = git change - frequency (last 6 months). -

-
- -
- - {#if error} -
-

Map not yet generated.

-

- Run pnpm audit:map from the repo root. It - writes to - static/admin/complexity-map.html. -

-
- {/if} - -
- -
- -
- Related reports -
    -
  • docs/module-health.md — per-module LOC × churn score
  • -
  • docs/module-coupling.md — inter-module imports (fan-in / fan-out)
  • -
  • docs/complexity-hotspots.md — top functions by cognitive complexity
  • -
-

- All reports regenerate automatically every Monday 06:00 UTC via the - module-health GitHub Action. -

-
-
+ diff --git a/apps/mana/apps/web/src/routes/(app)/admin/system/+page.svelte b/apps/mana/apps/web/src/routes/(app)/admin/system/+page.svelte index 38e7ec675..4c0e77c39 100644 --- a/apps/mana/apps/web/src/routes/(app)/admin/system/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/admin/system/+page.svelte @@ -1,174 +1,10 @@ -
- -
-
-

System Status

- {#if !loading} -
-
- - {healthyCount}/{totalCount} Services Healthy - -
- {/if} -
- - {#if loading} -
- {#each Array(8) as _} -
- {/each} -
- {:else} -
- {#each services as service} -
-
-
-

{service.name}

-

{statusLabels[service.status]}

-
- {#if service.url !== '-'} - - - - {/if} -
- {/each} -
- {/if} -
- - - - - -
-

Environment

-
-
-
- Server - Mac Mini (mana.how) -
-
- Domain - *.mana.how -
-
- SSL - Caddy (Auto) -
-
-
-
- Database - PostgreSQL 16 -
-
- Cache - Redis 7 -
-
- Tunnel - Cloudflare -
-
-
-
-
+ diff --git a/apps/mana/apps/web/src/routes/(app)/admin/user-data/+page.svelte b/apps/mana/apps/web/src/routes/(app)/admin/user-data/+page.svelte index c41b9dc39..0d93e29e2 100644 --- a/apps/mana/apps/web/src/routes/(app)/admin/user-data/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/admin/user-data/+page.svelte @@ -1,246 +1,11 @@ -
-
-
-

Nutzerdaten

-

Durchsuche und analysiere Nutzerdaten aller Projekte

-
-
- - -
-
- - -
- - {total} Nutzer gefunden - -
- - -
-
-

Nutzer

-
- {#if loading} -
- {#each Array(5) as _} -
-
-
-
-
-
-
- {/each} -
- {:else if error} -
-

{error}

- -
- {:else} -
- - - - - - - - - - - - {#each users as user} - - - - - - - - {/each} - -
- Nutzer - - Rolle - - Registriert - - Letzte Aktivitat - - Aktionen -
-
-
- - {(user.name || user.email)[0].toUpperCase()} - -
-
-

{user.name || '-'}

-

{user.email}

-
-
-
- - {user.role} - - - {formatDate(user.createdAt)} - - {formatRelativeTime(user.lastActiveAt)} - - -
-
- - {#if users.length === 0} -
Keine Nutzer gefunden
- {/if} - - - {#if totalPages > 1} -
- - - Seite {page} von {totalPages} - - -
- {/if} - {/if} -
-
+ diff --git a/apps/mana/apps/web/src/routes/(app)/admin/users/+page.svelte b/apps/mana/apps/web/src/routes/(app)/admin/users/+page.svelte index dc78331bd..7f02b456b 100644 --- a/apps/mana/apps/web/src/routes/(app)/admin/users/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/admin/users/+page.svelte @@ -1,156 +1,10 @@ -
- -
-
- - -
- - {filteredUsers.length} of {users.length} users - -
- - - - - - {#if totalPages > 1} -
- - Seite {currentPage} von {totalPages} - -
- - -
-
- {/if} - - {#if error} -
-

{error}

-
- {/if} -
+ diff --git a/apps/mana/apps/web/src/routes/(app)/broadcasts/settings/+page.svelte b/apps/mana/apps/web/src/routes/(app)/broadcasts/settings/+page.svelte index 2d385300e..d680aa4be 100644 --- a/apps/mana/apps/web/src/routes/(app)/broadcasts/settings/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/broadcasts/settings/+page.svelte @@ -1,40 +1,12 @@ - Broadcast-Einstellungen - Mana + Broadcast-Einstellungen — Mana -
-
-

Broadcast-Einstellungen

-

Sender-Defaults, Impressum und Footer für alle neuen Kampagnen.

-
- - -
- - + diff --git a/apps/mana/apps/web/src/routes/(app)/invoices/settings/+page.svelte b/apps/mana/apps/web/src/routes/(app)/invoices/settings/+page.svelte index 96f565e24..24bfb64e4 100644 --- a/apps/mana/apps/web/src/routes/(app)/invoices/settings/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/invoices/settings/+page.svelte @@ -1,40 +1,12 @@ - Rechnungs-Einstellungen - Mana + Rechnungs-Einstellungen — Mana -
-
-

Rechnungs-Einstellungen

-

Absender, Nummernkreis und Standards für alle neuen Rechnungen.

-
- - -
- - + diff --git a/apps/mana/apps/web/src/routes/(app)/news/preferences/+page.svelte b/apps/mana/apps/web/src/routes/(app)/news/preferences/+page.svelte index 4b4623d9c..3d162b887 100644 --- a/apps/mana/apps/web/src/routes/(app)/news/preferences/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/news/preferences/+page.svelte @@ -1,217 +1,12 @@ - - Einstellungen — News — Mana + News-Einstellungen — Mana -
-
- -

News-Einstellungen

-
- -
-

Themen

-

Welche Themen sollen im Feed auftauchen?

-
- {#each ALL_TOPICS as topic} - - {/each} -
-
- -
-

Sprachen

-
- - -
-
- -
-

Quellen

-

- Du blockst aktuell {prefs.blockedSources.length} Quellen. -

- Quellen verwalten → -
- -
-

Gelernte Gewichtungen

-

- Über Reaktionen lernt der Feed deine Vorlieben: - {topicWeightCount} Themen-Gewichte, {sourceWeightCount} Quellen-Gewichte. -

- -
- -
-

Onboarding

-

Themen, Sprachen und Quellen neu wählen.

- -
-
- - + diff --git a/apps/mana/apps/web/src/routes/(app)/uload/settings/+page.svelte b/apps/mana/apps/web/src/routes/(app)/uload/settings/+page.svelte index f92e72733..c8520e78d 100644 --- a/apps/mana/apps/web/src/routes/(app)/uload/settings/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/uload/settings/+page.svelte @@ -1,110 +1,12 @@ - Settings - uLoad - Mana + uLoad-Einstellungen — Mana -
-
- - - -

uLoad Einstellungen

-
- - -
-

Daten

-
-
-

{links.value?.length ?? 0}

-

Links

-
-
-

{tags.value?.length ?? 0}

-

Tags

-
-
-

{folders.value?.length ?? 0}

-

Ordner

-
-
-
- - -
-

Daten exportieren

-

Exportiere alle Links, Tags und Ordner als JSON-Datei.

- -
- - -
-

Gefahrenzone

-

- Loescht alle lokalen uLoad-Daten (Links, Tags, Ordner). Synchronisierte Daten auf dem Server - bleiben erhalten. -

- -
-
+