feat: Add light/dark mode support with backend persistence

This commit is contained in:
Yunxiao Xu
2026-02-17 00:32:15 -08:00
parent 3881ca6fd8
commit de25dc8a4d
17 changed files with 253 additions and 18 deletions

View File

@@ -0,0 +1,55 @@
import { createContext, useContext, useEffect, useState } from "react"
import { AuthService } from "@/services/auth"
type Theme = "light" | "dark"
interface ThemeContextType {
theme: Theme
setTheme: (theme: Theme) => void
toggleTheme: () => void
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined)
export function ThemeProvider({
children,
initialTheme = "light",
}: {
children: React.ReactNode
initialTheme?: Theme
}) {
const [theme, setThemeState] = useState<Theme>(initialTheme)
useEffect(() => {
const root = window.document.documentElement
root.classList.remove("light", "dark")
root.classList.add(theme)
}, [theme])
const setTheme = async (newTheme: Theme) => {
setThemeState(newTheme)
try {
await AuthService.updateTheme(newTheme)
} catch (error) {
console.error("Failed to sync theme to backend:", error)
}
}
const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light")
}
return (
<ThemeContext.Provider value={{ theme, setTheme, toggleTheme }}>
{children}
</ThemeContext.Provider>
)
}
export const useTheme = () => {
const context = useContext(ThemeContext)
if (context === undefined) {
throw new Error("useTheme must be used within a ThemeProvider")
}
return context
}