diff --git a/app/(main)/[locale]/login/page.tsx b/app/(main)/[locale]/login/page.tsx index fbddc90e..be9f2d8c 100644 --- a/app/(main)/[locale]/login/page.tsx +++ b/app/(main)/[locale]/login/page.tsx @@ -9,6 +9,7 @@ import { Input } from "@/components/ui/input"; import { useAuthStore } from "@/stores/auth-store"; import { useAccountStore } from "@/stores/account-store"; import { useThemeStore } from "@/stores/theme-store"; +import { resolveThemeLogo } from "@/lib/theme-logo"; import { useShallow } from "zustand/react/shallow"; import { useConfig } from "@/hooks/use-config"; import { apiFetch, getPathPrefix, toRouterPath, withBasePath } from "@/lib/browser-navigation"; @@ -135,6 +136,10 @@ export default function LoginPage() { const { theme, setTheme, initializeTheme } = useThemeStore(useShallow((s) => ({ theme: s.theme, setTheme: s.setTheme, initializeTheme: s.initializeTheme }))); const { appName, jmapServerUrl: configuredServerUrl, oauthEnabled, oauthOnly, oauthClientId: globalOauthClientId, oauthIssuerUrl: globalOauthIssuerUrl, oauthScopes, rememberMeEnabled, devMode, demoMode, loginLogoLightUrl, loginLogoDarkUrl, loginCompanyName, loginImprintUrl, loginPrivacyPolicyUrl, loginWebsiteUrl, loginLogoMaxHeight, loginLogoMaxWidth, loginShowHeading, loginShowSubtitle, loginShowTotp, loginShowVersion, isLoading: configLoading, error: configError, autoSsoEnabled, embeddedMode: _embeddedMode, allowCustomJmapEndpoint, jmapServers, jmapServerAutoPickByDomain } = useConfig(); const resolvedTheme = useThemeStore((s) => s.resolvedTheme); + const { activeThemeId, installedThemes } = useThemeStore(useShallow((s) => ({ activeThemeId: s.activeThemeId, installedThemes: s.installedThemes }))); + // Active theme may carry its own brand logo (VNClagoon wordmark, SRC mark); + // fall back to the globally configured login logo. + const effLoginLogo = resolveThemeLogo(installedThemes, activeThemeId, resolvedTheme === 'dark', loginLogoLightUrl, loginLogoDarkUrl); // Login logo sizing: when a max height/width is configured, drop the fixed // 64×64 box so the logo (e.g. a wide wordmark) can render at its true size. @@ -740,7 +745,7 @@ export default function LoginPage() {
{appName} @@ -890,7 +895,7 @@ export default function LoginPage() {
{appName} s.resolvedTheme); + const activeThemeId = useThemeStore((s) => s.activeThemeId); + const installedThemes = useThemeStore((s) => s.installedThemes); const { supportsCalendar } = useCalendarStore(); const { mailboxes } = useEmailStore(); const client = useAuthStore((s) => s.client); @@ -462,7 +465,7 @@ export function NavigationRail({ )} > {(() => { - const logoUrl = withBasePath(resolvedTheme === 'dark' ? (appLogoDarkUrl || appLogoLightUrl) : (appLogoLightUrl || appLogoDarkUrl)); + const logoUrl = withBasePath(resolveThemeLogo(installedThemes, activeThemeId, resolvedTheme === 'dark', appLogoLightUrl, appLogoDarkUrl)); return logoUrl ? (
t.id === activeThemeId) : undefined; + if (theme) { + const themed = isDark + ? (theme.logoDarkUrl ?? theme.logoLightUrl) + : (theme.logoLightUrl ?? theme.logoDarkUrl); + if (themed) return themed; + } + return isDark ? (fallbackDark || fallbackLight) : (fallbackLight || fallbackDark); +} diff --git a/vnc/VNC-CHANGES.md b/vnc/VNC-CHANGES.md index 23f17dae..c394a4bb 100644 --- a/vnc/VNC-CHANGES.md +++ b/vnc/VNC-CHANGES.md @@ -32,6 +32,11 @@ that merging new upstream releases stays a triage exercise, not an archaeology d | 2026-08-03 | `stores/theme-store.ts` | default `theme`/`resolvedTheme` → `dark` | dark-first per VNClagoon styleguide | | 2026-08-03 | `lib/builtin-themes.ts` | add `builtin-src` theme (Swiss red on white, light-first) | 2nd brand theme (SRC Advisory); VNClagoon stays default | | 2026-08-03 | `public/branding/src-logo.svg` (new) | SRC mountain mark | SRC brand (placeholder — swap official) | +| 2026-08-03 | `lib/plugin-types.ts` | add optional `logoLightUrl`/`logoDarkUrl` to InstalledTheme | per-theme brand logos | +| 2026-08-03 | `lib/theme-logo.ts` (new) | `resolveThemeLogo()` helper | pick active theme's logo, fall back to global | +| 2026-08-03 | `lib/builtin-themes.ts` | set logos on vnclagoon (wordmark) + src (mark) | logo switches with the brand theme | +| 2026-08-03 | `app/(main)/[locale]/login/page.tsx` | login logo uses active theme's logo | brand-switch on login | +| 2026-08-03 | `components/layout/navigation-rail.tsx` | nav-rail logo uses active theme's logo | brand-switch in app | _Note: Vercel was tried and **abandoned** on 2026-08-03. Bulwark writes to a local data dir (`/app/data/*`); Vercel serverless has a read-only filesystem → crash