diff --git a/src/content/docs/changelog/index.mdx b/src/content/docs/changelog/index.mdx index 180d8b52..48ab8923 100644 --- a/src/content/docs/changelog/index.mdx +++ b/src/content/docs/changelog/index.mdx @@ -11,6 +11,10 @@ seo: Notable changes to the kit, newest first. +## 2026-07-04 + +- **Dashboard: tenants can now edit their own branding.** The Multitenancy module already exposed current-tenant theme endpoints gated on `Tenants.ViewTheme` (basic) + `Tenants.UpdateTheme` (a tenant-assignable permission), but the only UI lived in the admin console — a tenant had no way to manage its own brand. The dashboard now ships a **Settings → Branding** tab: light + dark colour palettes (swatch + hex), brand-asset URLs (logo, dark logo, favicon) with inline previews, a live theme preview, and reset-to-defaults. The tab renders only for holders of `Tenants.UpdateTheme` (mirroring the sidebar permission gate) and its calls are current-tenant-scoped — no `tenant:` header, unlike the operator editor. Scope matches the admin card's v1 (palette + brand assets; typography/layout on the DTO are omitted). This edits the stored `TenantTheme`; per-tenant *rendering* of app chrome is still opt-in — see [theming](/docs/frontend/theming/). See [#1329](https://github.com/fullstackhero/dotnet-starter-kit/pull/1329). + ## 2026-06-20 - **The `fsh` CLI and `dotnet new` template are now on NuGet as stable `10.0.0`.** The two distribution packages that 10.0.0 had been waiting on have shipped: `FullStackHero.CLI` (install with `dotnet tool install -g FullStackHero.CLI` — no more `--prerelease`) and `FullStackHero.NET.StarterKit` (`dotnet new install FullStackHero.NET.StarterKit`). Because `fsh new` scaffolds *from* that template, the one-command flow is now end-to-end: `dotnet tool install -g FullStackHero.CLI && fsh new MyApp` produces a fully renamed project — unique JWT signing key, generated Docker secrets, `npm install` run, initial commit on `main`. The [Install](/docs/getting-started/install/) and [CLI](/docs/cli/) pages now lead with the CLI as the recommended path; `git clone` and the GitHub template remain available for reading the source or zero-install runs. See the [10.0.0 release](https://github.com/fullstackhero/dotnet-starter-kit/releases/tag/10.0.0). diff --git a/src/content/docs/frontend/dashboard.mdx b/src/content/docs/frontend/dashboard.mdx index 0be36efc..e08e84cf 100644 --- a/src/content/docs/frontend/dashboard.mdx +++ b/src/content/docs/frontend/dashboard.mdx @@ -46,7 +46,7 @@ clients/dashboard/src/pages/ ├── identity/ Tenant-scoped admin: users, roles, groups (+ detail pages) ├── invoices.tsx Invoice list + invoice-detail.tsx ├── subscription.tsx Current plan + billing status -├── settings/ Profile, security (2FA), appearance, notifications, API keys +├── settings/ Profile, security (2FA), appearance, branding, notifications, API keys ├── system/ Sessions, trash (recycle bin) — plus health + audits routes ├── tickets/ File ticket, list, detail, comments ├── impersonation-ended.tsx Graceful landing when an operator grant ends @@ -65,7 +65,7 @@ A few notes: The dashboard's appearance system is **per-user**: light/dark/system mode, an accent colour (presets or a custom hue), font, density, and reduced motion — all stored in localStorage and applied via CSS custom properties (Settings → Appearance). The neutral chassis is deliberately untinted so the accent does the branding work. -Per-**tenant** branding lives server-side as the Multitenancy module's `TenantTheme` (palette, brand assets, typography, layout) with a permission-gated editor in the admin console. Full details: [theming](/docs/frontend/theming/). +Per-**tenant** branding lives server-side as the Multitenancy module's `TenantTheme` (palette, brand assets, typography, layout). A tenant admin edits their **own** tenant's brand from **Settings → Branding** (light + dark palettes + logo/favicon URLs, with a live preview and reset-to-defaults) — the tab is permission-gated on `Tenants.UpdateTheme` and the calls are current-tenant-scoped (no `tenant:` header). Operators can still edit any tenant's brand from the admin console. Full details: [theming](/docs/frontend/theming/). ## Chat — the realtime showcase diff --git a/src/content/docs/frontend/theming.mdx b/src/content/docs/frontend/theming.mdx index 9b1eedaf..1cb5eea3 100644 --- a/src/content/docs/frontend/theming.mdx +++ b/src/content/docs/frontend/theming.mdx @@ -14,10 +14,10 @@ seo: Theming in the kit has two layers that are easy to conflate, so let's name them up front: -1. **Per-tenant branding** — the Multitenancy module owns a `TenantTheme` aggregate (colour palettes, brand assets, typography, layout) with permission-gated read/update/reset endpoints and an editor in the admin console. Themes are **data, not deploys** — editing one never requires a rebuild. +1. **Per-tenant branding** — the Multitenancy module owns a `TenantTheme` aggregate (colour palettes, brand assets, typography, layout) with permission-gated read/update/reset endpoints. Two editors write it: operators edit any tenant from the admin console, and a tenant admin edits their **own** tenant from the dashboard's **Settings → Branding** (gated on `Tenants.UpdateTheme`, current-tenant-scoped). Themes are **data, not deploys** — editing one never requires a rebuild. 2. **Per-user appearance** — the dashboard ships a rich appearance system (light/dark/system mode, accent colour, font, density, reduced motion) that each **user** controls from Settings → Appearance and that persists in localStorage. -The `TenantTheme` store + editor are fully wired end-to-end on the backend and admin side. The dashboard does **not yet** read `TenantTheme` to repaint its chrome per tenant — its visual identity today comes from the per-user appearance system. If you want full white-label rendering, the wiring point is small and described [below](#rendering-tenanttheme-in-your-own-frontend). +The `TenantTheme` store + both editors are fully wired end-to-end. What's **not yet** wired is *rendering*: neither app reads `TenantTheme` to repaint its chrome per tenant — visual identity today comes from the per-user appearance system, and the dashboard's Branding tab edits the stored theme without yet consuming it for its own paint. If you want full white-label rendering, the wiring point is small and described [below](#rendering-tenanttheme-in-your-own-frontend). ## The `TenantTheme` model