93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
/**
|
||
* useDataFetch Hook
|
||
*
|
||
* 统一的数据获取Hook
|
||
* 提供用户数据、部门数据、Tab数据的获取功能
|
||
* 从主页面提取,减少重复代码
|
||
*
|
||
* @created 2025-01-XX(从 page.tsx 提取)
|
||
* @hook
|
||
*/
|
||
|
||
'use client'
|
||
|
||
import { useCallback } from 'react'
|
||
import type { AdminTab, Department, ToastFn, User } from '../_components/types'
|
||
import type { Dispatch, SetStateAction } from 'react'
|
||
import { parseErrorResponse } from '../_utils/api'
|
||
|
||
interface UseDataFetchOptions {
|
||
showToast: ToastFn
|
||
departmentCollator: Intl.Collator
|
||
setUsers: Dispatch<SetStateAction<User[]>>
|
||
setDepartments: Dispatch<SetStateAction<Department[]>>
|
||
}
|
||
|
||
export function useDataFetch({
|
||
showToast,
|
||
departmentCollator,
|
||
setUsers,
|
||
setDepartments,
|
||
}: UseDataFetchOptions) {
|
||
const loadUsersData = useCallback(async () => {
|
||
try {
|
||
const response = await fetch('/api/admin/users?pageSize=1000')
|
||
if (response.ok) {
|
||
const data = await response.json()
|
||
setUsers(data.users || [])
|
||
} else {
|
||
const errorData = await parseErrorResponse(response)
|
||
console.error('Error fetching users:', errorData)
|
||
showToast(errorData.error || '获取用户列表失败', 'error')
|
||
}
|
||
} catch (error) {
|
||
console.error('Error fetching users:', error)
|
||
showToast('获取用户列表失败', 'error')
|
||
}
|
||
}, [setUsers, showToast])
|
||
|
||
const fetchDepartments = useCallback(async () => {
|
||
try {
|
||
const response = await fetch('/api/departments')
|
||
if (response.ok) {
|
||
const data = await response.json()
|
||
const sorted = Array.isArray(data)
|
||
? [...data].sort((a, b) => departmentCollator.compare(a.name, b.name))
|
||
: []
|
||
setDepartments(sorted)
|
||
} else {
|
||
const errorData = await parseErrorResponse(response)
|
||
showToast(errorData.error || '获取部门列表失败', 'error')
|
||
}
|
||
} catch (error) {
|
||
console.error('Error fetching departments:', error)
|
||
showToast('获取部门列表失败', 'error')
|
||
}
|
||
}, [departmentCollator, setDepartments, showToast])
|
||
|
||
const fetchTabData = useCallback(
|
||
async (tab: AdminTab) => {
|
||
switch (tab) {
|
||
case 'users':
|
||
await Promise.all([loadUsersData(), fetchDepartments()])
|
||
break
|
||
case 'departments':
|
||
await fetchDepartments()
|
||
break
|
||
default:
|
||
break
|
||
}
|
||
},
|
||
[fetchDepartments, loadUsersData],
|
||
)
|
||
|
||
return {
|
||
loadUsersData,
|
||
fetchDepartments,
|
||
fetchTabData,
|
||
}
|
||
}
|
||
|
||
export type UseDataFetchReturn = ReturnType<typeof useDataFetch>
|
||
|