- 미사용 import/변수/console.log 대량 정리 (100+개 파일) - ItemMasterContext 간소화 (미사용 로직 제거) - IntegratedListTemplateV2 / UniversalListPage 개선 - 결재 컴포넌트(ApprovalBox, DraftBox, ReferenceBox) 정리 - HR 컴포넌트(급여/휴가/부서) 코드 간소화 - globals.css 스타일 정리 및 개선 - AuthenticatedLayout 개선 - middleware CSP 정리 - proxy route 불필요 로깅 제거 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
|
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
import { isNextRedirectError } from '@/lib/utils/redirect-error';
|
|
|
|
/**
|
|
* Stats 데이터 로딩 훅
|
|
*
|
|
* 통계 데이터의 초기 로딩, 수동 업데이트, 재로딩을 관리합니다.
|
|
*
|
|
* @param loadFn - Stats API 호출 함수
|
|
* @param initialData - 초기값 (있으면 자동 로딩 스킵)
|
|
*
|
|
* @example
|
|
* // 기본 사용
|
|
* const { data: stats, reload: reloadStats } = useStatsLoader(getProcessStats);
|
|
*
|
|
* @example
|
|
* // 초기값 제공 (있으면 자동 로딩 스킵)
|
|
* const { data: stats, reload: reloadStats } = useStatsLoader(getContractStats, initialStats);
|
|
*/
|
|
export function useStatsLoader<T>(
|
|
loadFn: () => Promise<{ success: boolean; data?: T }>,
|
|
initialData?: T | null,
|
|
) {
|
|
const [data, setData] = useState<T | null>(initialData ?? null);
|
|
const loadFnRef = useRef(loadFn);
|
|
loadFnRef.current = loadFn;
|
|
|
|
const reload = useCallback(async () => {
|
|
try {
|
|
const result = await loadFnRef.current();
|
|
if (result.success && result.data) {
|
|
setData(result.data);
|
|
}
|
|
} catch (error) {
|
|
if (isNextRedirectError(error)) throw error;
|
|
console.error('[useStatsLoader] error:', error);
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (initialData != null) return;
|
|
reload();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
return { data, setData, reload };
|
|
}
|