mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
fix
This commit is contained in:
40
napcat.webui/src/components/ColorPicker.tsx
Normal file
40
napcat.webui/src/components/ColorPicker.tsx
Normal 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
|
@@ -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>
|
||||
)
|
||||
|
@@ -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 (
|
||||
|
106
napcat.webui/src/pages/dashboard/config/theme.tsx
Normal file
106
napcat.webui/src/pages/dashboard/config/theme.tsx
Normal 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
|
Reference in New Issue
Block a user