diff --git a/frontend/src/components/layout/Header.tsx b/frontend/src/components/layout/Header.tsx
index 0f5e8df..05d8cb9 100644
--- a/frontend/src/components/layout/Header.tsx
+++ b/frontend/src/components/layout/Header.tsx
@@ -18,7 +18,8 @@ import {
} from '@/components/ui/popover'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Separator } from '@/components/ui/separator'
-import { Bell, CheckCheck, LogOut, Menu } from 'lucide-react'
+import { Bell, CheckCheck, LogOut, Menu, Moon, Sun } from 'lucide-react'
+import { useTheme } from '@/hooks/useTheme'
interface HeaderProps {
onToggleSidebar: () => void
@@ -27,6 +28,7 @@ interface HeaderProps {
export function Header({ onToggleSidebar }: HeaderProps) {
const { user, logout } = useAuth()
const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotifications()
+ const { theme, toggleTheme } = useTheme()
const initials = user?.username
? user.username
@@ -54,6 +56,12 @@ export function Header({ onToggleSidebar }: HeaderProps) {
+ {/* Dark mode toggle */}
+
+
{/* Notification bell with dropdown */}
diff --git a/frontend/src/hooks/useTheme.ts b/frontend/src/hooks/useTheme.ts
new file mode 100644
index 0000000..a3d54d8
--- /dev/null
+++ b/frontend/src/hooks/useTheme.ts
@@ -0,0 +1,29 @@
+import { useCallback, useEffect, useState } from 'react'
+
+type Theme = 'light' | 'dark'
+
+const STORAGE_KEY = 'dak-theme'
+
+export function useTheme() {
+ const [theme, setThemeState] = useState(() => {
+ const stored = localStorage.getItem(STORAGE_KEY)
+ if (stored === 'dark' || stored === 'light') return stored
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
+ })
+
+ useEffect(() => {
+ const root = document.documentElement
+ if (theme === 'dark') {
+ root.classList.add('dark')
+ } else {
+ root.classList.remove('dark')
+ }
+ localStorage.setItem(STORAGE_KEY, theme)
+ }, [theme])
+
+ const toggleTheme = useCallback(() => {
+ setThemeState((prev) => (prev === 'dark' ? 'light' : 'dark'))
+ }, [])
+
+ return { theme, toggleTheme }
+}
diff --git a/frontend/src/pages/LoginPage.tsx b/frontend/src/pages/LoginPage.tsx
index 3ff1678..4aa0bb9 100644
--- a/frontend/src/pages/LoginPage.tsx
+++ b/frontend/src/pages/LoginPage.tsx
@@ -9,7 +9,8 @@ import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Alert, AlertDescription } from '@/components/ui/alert'
-import { AlertCircle, Loader2 } from 'lucide-react'
+import { AlertCircle, Loader2, Moon, Sun } from 'lucide-react'
+import { useTheme } from '@/hooks/useTheme'
const loginSchema = z.object({
email: z.string().email('Bitte geben Sie eine gueltige E-Mail-Adresse ein'),
@@ -21,6 +22,7 @@ type LoginFormValues = z.infer
export function LoginPage() {
const { login } = useAuth()
+ const { theme, toggleTheme } = useTheme()
const navigate = useNavigate()
const [error, setError] = useState(null)
const [showMfa, setShowMfa] = useState(false)
@@ -70,6 +72,15 @@ export function LoginPage() {
return (
+
DAK Portal