feat(branding): force color mode (dark or light) site-wide
This commit is contained in:
@@ -18,7 +18,14 @@ export const GlobalThemeProvider: React.FC<GlobalThemeProviderProps> = ({ childr
|
||||
|
||||
if (!themeAppliedRef.current && settingsData?.theme_config && !isGalleryPage) {
|
||||
themeAppliedRef.current = true;
|
||||
setTheme(settingsData.theme_config);
|
||||
// Honor instance-wide force color mode: when set, override the
|
||||
// theme's own colorMode so legacy themes can't render light against
|
||||
// a force-dark instance (or vice-versa).
|
||||
const forced = settingsData.branding_force_color_mode;
|
||||
const themeWithForce = forced
|
||||
? { ...settingsData.theme_config, colorMode: forced }
|
||||
: settingsData.theme_config;
|
||||
setTheme(themeWithForce);
|
||||
}
|
||||
}, [settingsData, setTheme]);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ interface AdminHeaderProps {
|
||||
export const AdminHeader: React.FC<AdminHeaderProps> = ({ onMenuClick }) => {
|
||||
const navigate = useNavigate();
|
||||
const { user, logout } = useAdminAuth();
|
||||
const { isDark, toggle: toggleDarkMode } = useAdminDarkMode();
|
||||
const { isDark, toggle: toggleDarkMode, forcedMode } = useAdminDarkMode();
|
||||
const { t } = useTranslation();
|
||||
const { format } = useLocalizedDate();
|
||||
const { formatTimeAgo } = useLocalizedTimeAgo();
|
||||
@@ -116,14 +116,17 @@ export const AdminHeader: React.FC<AdminHeaderProps> = ({ onMenuClick }) => {
|
||||
{/* Language Selector */}
|
||||
<LanguageSelector />
|
||||
|
||||
{/* Dark Mode Toggle */}
|
||||
<button
|
||||
onClick={toggleDarkMode}
|
||||
className="p-2 text-neutral-500 dark:text-neutral-400 hover:text-neutral-700 dark:hover:text-neutral-200 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-lg transition-colors"
|
||||
title={isDark ? t('admin.lightMode', 'Switch to light mode') : t('admin.darkMode', 'Switch to dark mode')}
|
||||
>
|
||||
{isDark ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
||||
</button>
|
||||
{/* Dark Mode Toggle — hidden entirely when an admin has locked
|
||||
the instance to a specific mode via Branding > Force color mode. */}
|
||||
{!forcedMode && (
|
||||
<button
|
||||
onClick={toggleDarkMode}
|
||||
className="p-2 text-neutral-500 dark:text-neutral-400 hover:text-neutral-700 dark:hover:text-neutral-200 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-lg transition-colors"
|
||||
title={isDark ? t('admin.lightMode', 'Switch to light mode') : t('admin.darkMode', 'Switch to dark mode')}
|
||||
>
|
||||
{isDark ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{/* Notifications */}
|
||||
<div className="relative" ref={notificationRef}>
|
||||
|
||||
@@ -341,6 +341,13 @@ export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
|
||||
themeToApply = settingsData.theme_config;
|
||||
}
|
||||
|
||||
// Honor instance-wide force color mode (Branding > Force color mode).
|
||||
// The branding-level lock wins over per-event themes so a force-dark
|
||||
// instance never accidentally renders a light gallery (and vice-versa).
|
||||
if (themeToApply && settingsData.branding_force_color_mode) {
|
||||
themeToApply = { ...themeToApply, colorMode: settingsData.branding_force_color_mode };
|
||||
}
|
||||
|
||||
// Apply theme with a small delay to ensure it overrides any global theme
|
||||
if (themeToApply) {
|
||||
// Use setTimeout to ensure this runs after any global theme application
|
||||
|
||||
Reference in New Issue
Block a user