fix: enforce dark mode for pre-auth screens

addresses #332 - login and setup screens now consistently use dark mode, with theme preferences only applied after authentication
This commit is contained in:
Pulse Monitor
2025-08-18 20:33:19 +00:00
parent e9187e5986
commit 002df44d11
3 changed files with 32 additions and 72 deletions
+27 -13
View File
@@ -73,13 +73,8 @@ function App() {
// Version info
const [versionInfo, setVersionInfo] = createSignal<VersionInfo | null>(null);
// Dark mode - check localStorage first, only use system preference if never set
const savedDarkMode = localStorage.getItem(STORAGE_KEYS.DARK_MODE);
const [darkMode, setDarkMode] = createSignal(
savedDarkMode !== null
? savedDarkMode === 'true'
: window.matchMedia('(prefers-color-scheme: dark)').matches
);
// Dark mode - only apply user preferences after authentication
const [darkMode, setDarkMode] = createSignal(false);
// Toggle dark mode
const toggleDarkMode = () => {
@@ -94,12 +89,7 @@ function App() {
logger.info('Theme changed', { mode: newMode ? 'dark' : 'light' });
};
// Initialize dark mode - ensure it matches the signal
if (darkMode()) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
// Don't initialize dark mode here - will be handled based on auth state
// Check auth on mount
onMount(async () => {
@@ -146,12 +136,36 @@ function App() {
setNeedsAuth(false);
// Only initialize WebSocket after successful auth check
setWsStore(getGlobalWebSocketStore());
// Apply user's theme preference only after successful authentication
const savedDarkMode = localStorage.getItem(STORAGE_KEYS.DARK_MODE);
const prefersDark = savedDarkMode !== null
? savedDarkMode === 'true'
: window.matchMedia('(prefers-color-scheme: dark)').matches;
setDarkMode(prefersDark);
if (prefersDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}
} catch (error) {
console.error('Auth check error:', error);
// On error, try to proceed without auth
setNeedsAuth(false);
setWsStore(getGlobalWebSocketStore());
// Apply theme preference if we're proceeding without auth
const savedDarkMode = localStorage.getItem(STORAGE_KEYS.DARK_MODE);
const prefersDark = savedDarkMode !== null
? savedDarkMode === 'true'
: window.matchMedia('(prefers-color-scheme: dark)').matches;
setDarkMode(prefersDark);
if (prefersDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
} finally {
setIsLoading(false);
}
@@ -16,16 +16,9 @@ export const FirstRunSetup: Component = () => {
const [savedToken, setSavedToken] = createSignal('');
const [copied, setCopied] = createSignal<'password' | 'token' | null>(null);
// Additional setup options
const [darkMode, setDarkMode] = createSignal(
window.matchMedia('(prefers-color-scheme: dark)').matches
);
onMount(() => {
// Apply dark mode immediately if selected
if (darkMode()) {
document.documentElement.classList.add('dark');
}
// Force dark mode for setup screen
document.documentElement.classList.add('dark');
});
const generatePassword = () => {
@@ -80,8 +73,7 @@ export const FirstRunSetup: Component = () => {
body: JSON.stringify({
username: username(),
password: finalPassword,
apiToken: token,
darkMode: darkMode()
apiToken: token
})
});
@@ -103,8 +95,6 @@ export const FirstRunSetup: Component = () => {
setSavedPassword(useCustomPassword() ? password() : generatedPassword());
setSavedToken(token);
// Apply settings - use consistent storage key
localStorage.setItem('darkMode', String(darkMode()));
// Show credentials
setShowCredentials(true);
@@ -263,44 +253,6 @@ IMPORTANT: Keep these credentials secure!
</Show>
</div>
{/* Additional Settings */}
<div class="space-y-4">
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-300">
Initial Configuration
</h3>
{/* Dark Mode */}
<div class="flex items-center justify-between">
<div>
<label class="text-sm text-gray-700 dark:text-gray-300">
Dark Mode
</label>
<p class="text-xs text-gray-500 dark:text-gray-500">
Use dark theme for the dashboard
</p>
</div>
<button
type="button"
onClick={() => {
setDarkMode(!darkMode());
if (!darkMode()) {
document.documentElement.classList.remove('dark');
} else {
document.documentElement.classList.add('dark');
}
}}
class={`relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${
darkMode() ? 'bg-blue-600' : 'bg-gray-200 dark:bg-gray-700'
}`}
>
<span
class={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out ${
darkMode() ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</div>
</div>
{/* Info Box */}
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 space-y-2">
+2 -8
View File
@@ -1,6 +1,5 @@
import { Component, createSignal, Show, onMount, lazy, Suspense } from 'solid-js';
import { setBasicAuth } from '@/utils/apiClient';
import { STORAGE_KEYS } from '@/constants';
// Force include FirstRunSetup with lazy loading
const FirstRunSetup = lazy(() => import('./FirstRunSetup').then(m => ({ default: m.FirstRunSetup })));
@@ -18,13 +17,8 @@ export const Login: Component<LoginProps> = (props) => {
const [loadingAuth, setLoadingAuth] = createSignal(true);
onMount(async () => {
// Apply saved theme preference
const savedTheme = localStorage.getItem(STORAGE_KEYS.DARK_MODE);
if (savedTheme === 'true') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
// Force dark mode for login screen
document.documentElement.classList.add('dark');
console.log('[Login] Starting auth check...');
try {