Some checks failed
CI Check / check (push) Has been cancelled
- 创建统一UI三层架构系统(基础层、颜色层、组合层) - 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等) - 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等) - 提取工具函数(validators、formatters、api等) - 创建统一弹窗组件(Modal)和useModal Hook - 添加错误边界和统一状态组件 - 完善类型定义和可访问性支持 - 更新文档(优化记录、优化计划、更新日志)
117 lines
3.0 KiB
TypeScript
117 lines
3.0 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useState } from 'react'
|
|
import type { DashboardData, ToastFn } from '../_components/types'
|
|
|
|
type SystemSettingKey = 'registrationEnabled' | 'userActivationRequired'
|
|
|
|
interface UseDashboardDataOptions {
|
|
showToast?: ToastFn
|
|
}
|
|
|
|
interface RefreshOptions {
|
|
background?: boolean
|
|
}
|
|
|
|
export function useDashboardData({ showToast }: UseDashboardDataOptions = {}) {
|
|
const [data, setData] = useState<DashboardData | null>(null)
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
const [lastUpdated, setLastUpdated] = useState<number | null>(null)
|
|
const [refreshing, setRefreshing] = useState(false)
|
|
|
|
const refresh = useCallback(
|
|
async (options: RefreshOptions = {}) => {
|
|
const { background = false } = options
|
|
if (!background) {
|
|
setLoading(true)
|
|
}
|
|
setRefreshing(true)
|
|
setError(null)
|
|
try {
|
|
const response = await fetch('/api/admin/system-status', { credentials: 'include' })
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
}
|
|
const payload: DashboardData = await response.json()
|
|
setData(payload)
|
|
setLastUpdated(Date.now())
|
|
} catch (err) {
|
|
console.error('Failed to fetch dashboard data:', err)
|
|
const message = err instanceof Error ? err.message : '获取数据失败'
|
|
setError(message)
|
|
} finally {
|
|
if (!background) {
|
|
setLoading(false)
|
|
}
|
|
setRefreshing(false)
|
|
}
|
|
},
|
|
[],
|
|
)
|
|
|
|
const updateSystemSetting = useCallback(
|
|
async (key: SystemSettingKey, value: boolean) => {
|
|
let previousValue: boolean | undefined
|
|
setData((prev) => {
|
|
if (!prev) return prev
|
|
previousValue = prev.systemInfo[key]
|
|
return {
|
|
...prev,
|
|
systemInfo: {
|
|
...prev.systemInfo,
|
|
[key]: value,
|
|
},
|
|
}
|
|
})
|
|
|
|
try {
|
|
const body =
|
|
key === 'registrationEnabled'
|
|
? { enableRegistration: value }
|
|
: { enableUserActivation: value }
|
|
|
|
const response = await fetch('/api/system-settings', {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error('更新失败')
|
|
}
|
|
|
|
showToast?.('设置已更新')
|
|
} catch (err) {
|
|
console.error('Update system setting error:', err)
|
|
setData((prev) => {
|
|
if (!prev) return prev
|
|
return {
|
|
...prev,
|
|
systemInfo: {
|
|
...prev.systemInfo,
|
|
[key]: previousValue ?? prev.systemInfo[key],
|
|
},
|
|
}
|
|
})
|
|
showToast?.('更新失败', 'error')
|
|
throw err
|
|
}
|
|
},
|
|
[showToast],
|
|
)
|
|
|
|
return {
|
|
data,
|
|
loading,
|
|
error,
|
|
refresh,
|
|
updateSystemSetting,
|
|
lastUpdated,
|
|
refreshing,
|
|
}
|
|
}
|
|
|
|
export type UseDashboardDataReturn = ReturnType<typeof useDashboardData>
|
|
|