Page MenuHomeDevCentral

D3989.id10397.diff
No OneTemporary

D3989.id10397.diff

diff --git a/frontend/src/components/AppNavbar.vue b/frontend/src/components/AppNavbar.vue
--- a/frontend/src/components/AppNavbar.vue
+++ b/frontend/src/components/AppNavbar.vue
@@ -3,9 +3,11 @@
import { RouterLink } from 'vue-router'
import { configApi } from '@/plugins/api'
import { useAuth } from '@/composables/useAuth'
+import { useDarkMode } from '@/composables/useDarkMode'
const config = ref(null)
const { isAuthenticated, logout } = useAuth()
+const { isDark, toggle } = useDarkMode()
onMounted(async () => {
try {
@@ -63,6 +65,21 @@
Admin
</RouterLink>
+ <!-- Dark mode toggle: switches between sun (light) and moon (dark) icons -->
+ <button
+ @click="toggle"
+ class="text-gray-400 hover:text-white transition-colors"
+ :aria-label="isDark ? 'Switch to light mode' : 'Switch to dark mode'"
+ >
+ <!-- Moon icon: shown in light mode -->
+ <svg v-if="!isDark" xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3a7 7 0 109.79 9.79z" />
+ </svg>
+ <!-- Sun icon: shown in dark mode -->
+ <svg v-else xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707M17.657 17.657l-.707-.707M6.343 6.343l-.707-.707M12 8a4 4 0 100 8 4 4 0 000-8z" />
+ </svg>
+ </button>
</div>
</div>
</div>
diff --git a/frontend/src/composables/useDarkmode.js b/frontend/src/composables/useDarkmode.js
new file mode 100644
--- /dev/null
+++ b/frontend/src/composables/useDarkmode.js
@@ -0,0 +1,30 @@
+import { ref } from 'vue'
+
+const STORAGE_KEY = 'servpulse_dark_mode'
+
+// Shared state across all composable instances
+const isDark = ref(false)
+
+const applyDark = (value) => {
+ // Toggle the 'dark' class on <html> for Tailwind dark mode
+ document.documentElement.classList.toggle('dark', value)
+ localStorage.setItem(STORAGE_KEY, value ? 'dark' : 'light')
+ isDark.value = value
+}
+
+const initDarkMode = () => {
+ const saved = localStorage.getItem(STORAGE_KEY)
+ if (saved) {
+ // Use saved preference
+ applyDark(saved === 'dark')
+ } else {
+ // Fall back to system preference
+ applyDark(window.matchMedia('(prefers-color-scheme: dark)').matches)
+ }
+}
+
+const toggle = () => applyDark(!isDark.value)
+
+export function useDarkMode() {
+ return { isDark, toggle, initDarkMode }
+}
diff --git a/frontend/src/main.js b/frontend/src/main.js
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -3,6 +3,10 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
+import { useDarkMode } from '@/composables/useDarkMode'
+
+// Apply dark mode before app mounts to avoid flash
+useDarkMode().initDarkMode()
const app = createApp(App)

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 15, 03:00 (5 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3530009
Default Alt Text
D3989.id10397.diff (3 KB)

Event Timeline