This commit is contained in:
bietiaop
2025-02-08 22:43:53 +08:00
parent f8c396b1fe
commit 2e013ed4f5
7 changed files with 444 additions and 278 deletions

View File

@@ -0,0 +1,40 @@
import { Popover, PopoverContent, PopoverTrigger } from '@heroui/popover'
import React from 'react'
import { ColorResult, SketchPicker } from 'react-color'
// 假定 heroui 提供的 Popover组件
interface ColorPickerProps {
color: string
onChange: (color: string) => void
}
const ColorPicker: React.FC<ColorPickerProps> = ({ color, onChange }) => {
const handleChange = (colorResult: ColorResult) => {
const hsl = colorResult.hsl
const color = `${hsl.h} ${hsl.s}% ${hsl.l}%`
onChange(color)
}
return (
<Popover>
<PopoverTrigger>
<div
style={{
background: color,
width: 36,
height: 14,
borderRadius: 2,
cursor: 'pointer',
border: '1px solid #ddd'
}}
/>
</PopoverTrigger>
<PopoverContent>
<SketchPicker color={color} onChange={handleChange} />
</PopoverContent>
</Popover>
)
}
export default ColorPicker

View File

@@ -6,6 +6,7 @@ import { useNavigate, useSearchParams } from 'react-router-dom'
import ChangePasswordCard from './change_password'
import LoginConfigCard from './login'
import OneBotConfigCard from './onebot'
import ThemeConfigCard from './theme'
import WebUIConfigCard from './webui'
export interface ConfigPageProps {
@@ -58,7 +59,6 @@ export default function ConfigPage() {
<WebUIConfigCard />
</ConfingPageItem>
</Tab>
<Tab title="登录配置" key="login">
<ConfingPageItem>
<LoginConfigCard />
@@ -69,6 +69,12 @@ export default function ConfigPage() {
<ChangePasswordCard />
</ConfingPageItem>
</Tab>
<Tab title="主题配置" key="theme">
<ConfingPageItem>
<ThemeConfigCard />
</ConfingPageItem>
</Tab>
</Tabs>
</section>
)

View File

@@ -47,11 +47,11 @@ const LoginConfigCard = () => {
}
})
const onRefresh = async (shotTip = true) => {
const onRefresh = async () => {
try {
setLoading(true)
await refreshQuickLogin()
if (shotTip) toast.success('刷新成功')
toast.success('刷新成功')
} catch (error) {
const msg = (error as Error).message
toast.error(`刷新失败: ${msg}`)
@@ -64,10 +64,6 @@ const LoginConfigCard = () => {
reset()
}, [quickLoginData])
useEffect(() => {
onRefresh(false)
}, [])
if (loading) return <PageLoading loading={true} />
return (

View File

@@ -0,0 +1,106 @@
import { useRequest } from 'ahooks'
import { useEffect } from 'react'
import { Controller, useForm } from 'react-hook-form'
import toast from 'react-hot-toast'
import ColorPicker from '@/components/ColorPicker'
import SaveButtons from '@/components/button/save_buttons'
import PageLoading from '@/components/page_loading'
import WebUIManager from '@/controllers/webui_manager'
const ThemeConfigCard = () => {
const { data, loading, error, refreshAsync } = useRequest(
WebUIManager.getThemeConfig
)
const {
control,
handleSubmit: handleOnebotSubmit,
formState: { isSubmitting },
setValue: setOnebotValue
} = useForm<{
theme: ThemeConfig
}>({
defaultValues: {
theme: {
dark: {},
light: {}
}
}
})
const reset = () => {
if (data) setOnebotValue('theme', data)
}
const onSubmit = handleOnebotSubmit((data) => {
try {
WebUIManager.setThemeConfig(data.theme)
toast.success('保存成功')
} catch (error) {
const msg = (error as Error).message
toast.error(`保存失败: ${msg}`)
}
})
const onRefresh = async () => {
try {
await refreshAsync()
toast.success('刷新成功')
} catch (error) {
const msg = (error as Error).message
toast.error(`刷新失败: ${msg}`)
}
}
if (loading) return <PageLoading loading={true} />
if (error)
return (
<div className="py-24 text-danger-500 text-center">{error.message}</div>
)
const colorKeys = [
'--heroui-background',
'--heroui-primary',
'--heroui-danger'
] as const
return (
<>
<title> - NapCat WebUI</title>
<div className="flex-shrink-0 w-full"></div>
{(['dark', 'light'] as const).map((mode) => (
<div key={mode}>
<h3>{mode === 'dark' ? '暗色主题' : '亮色主题'}</h3>
{colorKeys.map((key) => (
<div
key={key}
style={{ display: 'flex', alignItems: 'center', marginBottom: 8 }}
>
<label style={{ width: 150 }}>{key}</label>
<Controller
control={control}
name={`theme.${mode}.${key}`}
render={({ field: { value, onChange } }) => {
console.log(value)
const hslArray = value?.split(' ') ?? [0, 0, 0]
const color = `hsl(${hslArray[0]}, ${hslArray[1]}, ${hslArray[2]})`
return <ColorPicker color={color} onChange={onChange} />
}}
/>
</div>
))}
</div>
))}
<SaveButtons
onSubmit={onSubmit}
reset={reset}
isSubmitting={isSubmitting}
refresh={onRefresh}
/>
</>
)
}
export default ThemeConfigCard