refactor(WEB): 공통 훅(useDeleteDialog, useStatsLoader) 및 CRUD 서비스 추출
- useDeleteDialog 훅 추출로 삭제 다이얼로그 로직 공통화 - useStatsLoader 훅 추출로 통계 로딩 패턴 공통화 - create-crud-service 유틸 추가 - 차량관리/견적/출고/검사 등 리스트 컴포넌트 간소화 - RankManagement actions 정리 - 프로덕션 로거 불필요 출력 제거 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
src/hooks/useStatsLoader.ts
Normal file
49
src/hooks/useStatsLoader.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
'use client';
|
||||
|
||||
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 };
|
||||
}
|
||||
Reference in New Issue
Block a user