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:
유병철
2026-02-09 20:42:05 +09:00
parent 3ea6a57a10
commit 4d79b178e3
22 changed files with 588 additions and 619 deletions

View File

@@ -12,6 +12,7 @@
import { useState, useEffect, useMemo, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { useStatsLoader } from '@/hooks/useStatsLoader';
import {
ClipboardCheck,
Plus,
@@ -53,11 +54,7 @@ export function InspectionList() {
const router = useRouter();
// ===== 통계 =====
const [statsData, setStatsData] = useState<InspectionStats>({
receptionCount: 0,
inProgressCount: 0,
completedCount: 0,
});
const { data: statsData, reload: reloadStats } = useStatsLoader(getInspectionStats);
// ===== 날짜 범위 =====
const today = new Date();
@@ -77,22 +74,6 @@ export function InspectionList() {
const [calendarStatusFilter, setCalendarStatusFilter] = useState<string>('전체');
const [calendarInspectorFilter, setCalendarInspectorFilter] = useState<string>('전체');
// 초기 통계 로드
useEffect(() => {
const loadStats = async () => {
try {
const result = await getInspectionStats();
if (result.success && result.data) {
setStatsData(result.data);
}
} catch (error) {
if (isNextRedirectError(error)) throw error;
console.error('[InspectionList] loadStats error:', error);
}
};
loadStats();
}, []);
// 캘린더 데이터 로드
const loadCalendarData = useCallback(async () => {
try {
@@ -164,19 +145,19 @@ export function InspectionList() {
() => [
{
label: '접수',
value: statsData.receptionCount,
value: statsData?.receptionCount ?? 0,
icon: FileInput,
iconColor: 'text-gray-600',
},
{
label: '진행중',
value: statsData.inProgressCount,
value: statsData?.inProgressCount ?? 0,
icon: Loader2,
iconColor: 'text-blue-600',
},
{
label: '완료',
value: statsData.completedCount,
value: statsData?.completedCount ?? 0,
icon: CheckCircle2,
iconColor: 'text-green-600',
},
@@ -236,10 +217,7 @@ export function InspectionList() {
if (result.success) {
// 통계 재로드
const statsResult = await getInspectionStats();
if (statsResult.success && statsResult.data) {
setStatsData(statsResult.data);
}
await reloadStats();
return {
success: true,