diff --git a/index.html b/index.html
index 427d1f2..1267038 100644
--- a/index.html
+++ b/index.html
@@ -5,6 +5,20 @@
RADIUS Admin
+
+
+
diff --git a/src/App.tsx b/src/App.tsx
index d4204bc..8cb108a 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,12 +1,29 @@
import { NavLink, Navigate, Route, Routes } from 'react-router-dom'
-import { LogOut, Router, Wifi } from 'lucide-react'
+import { LogOut, Moon, Router, Sun, Wifi } from 'lucide-react'
import { useAuth } from '@/auth/auth'
+import { useTheme } from '@/lib/theme'
import { Login } from '@/pages/Login'
import { Devices } from '@/pages/Devices'
import { Vlans } from '@/pages/Vlans'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
+function ThemeToggle() {
+ const { theme, toggle } = useTheme()
+ return (
+
+ )
+}
+
function Nav() {
const { logout } = useAuth()
const linkClass = ({ isActive }: { isActive: boolean }) =>
@@ -28,9 +45,12 @@ function Nav() {
VLANs
-
+
+
+
+
)
diff --git a/src/lib/theme.tsx b/src/lib/theme.tsx
new file mode 100644
index 0000000..9007117
--- /dev/null
+++ b/src/lib/theme.tsx
@@ -0,0 +1,38 @@
+import { createContext, useCallback, useContext, useEffect, useState, type ReactNode } from 'react'
+
+type Theme = 'light' | 'dark'
+const STORAGE = 'radui.theme'
+
+interface ThemeState {
+ theme: Theme
+ toggle: () => void
+}
+
+const ThemeContext = createContext(null)
+
+function initialTheme(): Theme {
+ const saved = localStorage.getItem(STORAGE)
+ if (saved === 'light' || saved === 'dark') return saved
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
+}
+
+export function ThemeProvider({ children }: { children: ReactNode }) {
+ const [theme, setTheme] = useState(initialTheme)
+
+ useEffect(() => {
+ document.documentElement.classList.toggle('dark', theme === 'dark')
+ localStorage.setItem(STORAGE, theme)
+ }, [theme])
+
+ const toggle = useCallback(() => {
+ setTheme((t) => (t === 'dark' ? 'light' : 'dark'))
+ }, [])
+
+ return {children}
+}
+
+export function useTheme(): ThemeState {
+ const ctx = useContext(ThemeContext)
+ if (!ctx) throw new Error('useTheme must be used within ThemeProvider')
+ return ctx
+}
diff --git a/src/main.tsx b/src/main.tsx
index 6b0375b..f24acae 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -4,15 +4,18 @@ import { BrowserRouter } from 'react-router-dom'
import './index.css'
import App from './App.tsx'
import { AuthProvider } from './auth/auth.tsx'
+import { ThemeProvider } from './lib/theme.tsx'
import { Toaster } from './components/ui/sonner.tsx'
createRoot(document.getElementById('root')!).render(
-
-
-
-
-
-
+
+
+
+
+
+
+
+
,
)