flnxi-Wu/app/admin/_hooks/useDashboardData.ts
2025-11-22 17:56:24 +08:00

128 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* useDashboardData Hook
*
* 仪表板数据获取Hook
* 统一管理监控仪表板的数据获取逻辑
* 包括数据加载、错误处理、刷新等功能
*
* @created 2025-01-XX(从 page.tsx 提取)
* @hook
*/
'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>