feat(theme): add dark mode with next-themes and settings toggle
This commit is contained in:
@@ -6,13 +6,22 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
import { Switch } from "@/components/ui/switch"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { notifySuccess } from "@/lib/toast"
|
||||
import type { UserRole } from "@/lib/types"
|
||||
import type { ThemePreference } from "@/store/auth"
|
||||
import { useAuthStore } from "@/store/auth"
|
||||
import { Camera } from "lucide-react"
|
||||
import { useTheme } from "next-themes"
|
||||
import Link from "next/link"
|
||||
import { useRef, useState } from "react"
|
||||
|
||||
@@ -32,6 +41,14 @@ export default function SettingsPage() {
|
||||
const fileRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
const isRoleVerified = (role: UserRole) => verifiedRoles.includes(role)
|
||||
const { theme, setTheme } = useTheme()
|
||||
const setThemePreference = useAuthStore((s) => s.setThemePreference)
|
||||
|
||||
function handleThemeChange(value: string) {
|
||||
const pref = value as ThemePreference
|
||||
setTheme(pref)
|
||||
setThemePreference(pref)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-6">
|
||||
@@ -174,6 +191,27 @@ export default function SettingsPage() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">外观设置</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label>主题模式</Label>
|
||||
<Select value={theme} onValueChange={handleThemeChange}>
|
||||
<SelectTrigger className="w-32">
|
||||
<SelectValue placeholder="选择主题" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="light">浅色模式</SelectItem>
|
||||
<SelectItem value="dark">深色模式</SelectItem>
|
||||
<SelectItem value="system">跟随系统</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">通知偏好</CardTitle>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ export default function RootLayout({
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<html lang="zh-CN">
|
||||
<html lang="zh-CN" suppressHydrationWarning>
|
||||
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
|
||||
<Providers>{children}</Providers>
|
||||
</body>
|
||||
|
||||
+10
-5
@@ -1,8 +1,10 @@
|
||||
"use client"
|
||||
|
||||
import { GlobalLoginDialog } from "@/components/global-login-dialog"
|
||||
import { ThemeSyncEffect } from "@/components/theme-sync"
|
||||
import { TooltipProvider } from "@/components/ui/tooltip"
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||
import { ThemeProvider } from "next-themes"
|
||||
import { useState } from "react"
|
||||
import { Toaster } from "sonner"
|
||||
|
||||
@@ -21,11 +23,14 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<TooltipProvider>
|
||||
{children}
|
||||
<Toaster richColors position="top-center" />
|
||||
<GlobalLoginDialog />
|
||||
</TooltipProvider>
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
||||
<TooltipProvider>
|
||||
<ThemeSyncEffect />
|
||||
{children}
|
||||
<Toaster richColors position="top-center" />
|
||||
<GlobalLoginDialog />
|
||||
</TooltipProvider>
|
||||
</ThemeProvider>
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user