refactor(WEB): 공통코드 클라이언트 훅 전환 및 품목 탭 동적 생성
- common-codes.ts에서 'use server' 제거, 타입/유틸리티만 유지 - useCommonCodes 훅 생성 (클라이언트 /api/proxy/ 패턴, 5분 캐시) - ItemListClient 탭/통계카드를 common_codes 기반 동적 생성으로 전환 - OrderSalesDetailEdit 서버액션 → useCommonCodes 훅 전환 - order-management actions.ts 서버액션 내 공통코드 직접 조회로 변경
This commit is contained in:
@@ -8,10 +8,11 @@
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useState, useEffect, useRef, useMemo } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import type { ItemMaster } from '@/types/item';
|
||||
import { ITEM_TYPE_LABELS } from '@/types/item';
|
||||
import { useCommonCodes } from '@/hooks/useCommonCodes';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
@@ -352,25 +353,50 @@ export default function ItemListClient() {
|
||||
}
|
||||
};
|
||||
|
||||
// 탭 옵션 (품목 유형별)
|
||||
const tabs: TabOption[] = [
|
||||
{ value: 'all', label: '전체', count: totalStats.totalAll, color: 'gray' },
|
||||
{ value: 'FG', label: '제품', count: totalStats.totalFG, color: 'purple' },
|
||||
{ value: 'PT', label: '부품', count: totalStats.totalPT, color: 'orange' },
|
||||
{ value: 'SM', label: '부자재', count: totalStats.totalSM, color: 'green' },
|
||||
{ value: 'RM', label: '원자재', count: totalStats.totalRM, color: 'blue' },
|
||||
{ value: 'CS', label: '소모품', count: totalStats.totalCS, color: 'gray' },
|
||||
];
|
||||
// 품목 유형 공통코드
|
||||
const { codes: itemTypeCodes } = useCommonCodes('item_type');
|
||||
|
||||
// 통계 카드 (전체 통계)
|
||||
const stats: StatCard[] = [
|
||||
{ label: '전체 품목', value: totalStats.totalAll, icon: Package, iconColor: 'text-blue-600' },
|
||||
{ label: '제품', value: totalStats.totalFG, icon: Package, iconColor: 'text-purple-600' },
|
||||
{ label: '부품', value: totalStats.totalPT, icon: Package, iconColor: 'text-orange-600' },
|
||||
{ label: '부자재', value: totalStats.totalSM, icon: Package, iconColor: 'text-green-600' },
|
||||
{ label: '원자재', value: totalStats.totalRM, icon: Package, iconColor: 'text-cyan-600' },
|
||||
{ label: '소모품', value: totalStats.totalCS, icon: Package, iconColor: 'text-gray-600' },
|
||||
];
|
||||
// 코드별 색상 매핑
|
||||
const codeColorMap: Record<string, string> = {
|
||||
FG: 'purple', PT: 'orange', SM: 'green', RM: 'blue', CS: 'gray',
|
||||
};
|
||||
const codeIconColorMap: Record<string, string> = {
|
||||
FG: 'text-purple-600', PT: 'text-orange-600', SM: 'text-green-600', RM: 'text-cyan-600', CS: 'text-gray-600',
|
||||
};
|
||||
|
||||
// 코드별 통계 매핑
|
||||
const codeCountMap: Record<string, number> = {
|
||||
FG: totalStats.totalFG, PT: totalStats.totalPT, SM: totalStats.totalSM,
|
||||
RM: totalStats.totalRM, CS: totalStats.totalCS,
|
||||
};
|
||||
|
||||
// 탭 옵션 (공통코드 기반 동적 생성)
|
||||
const tabs: TabOption[] = useMemo(() => {
|
||||
const dynamicTabs: TabOption[] = itemTypeCodes.map((code) => ({
|
||||
value: code.code,
|
||||
label: code.name,
|
||||
count: codeCountMap[code.code] ?? 0,
|
||||
color: codeColorMap[code.code] ?? 'gray',
|
||||
}));
|
||||
return [
|
||||
{ value: 'all', label: '전체', count: totalStats.totalAll, color: 'gray' },
|
||||
...dynamicTabs,
|
||||
];
|
||||
}, [itemTypeCodes, totalStats]);
|
||||
|
||||
// 통계 카드 (공통코드 기반 동적 생성)
|
||||
const stats: StatCard[] = useMemo(() => {
|
||||
const dynamicStats: StatCard[] = itemTypeCodes.map((code) => ({
|
||||
label: code.name,
|
||||
value: codeCountMap[code.code] ?? 0,
|
||||
icon: Package,
|
||||
iconColor: codeIconColorMap[code.code] ?? 'text-gray-600',
|
||||
}));
|
||||
return [
|
||||
{ label: '전체 품목', value: totalStats.totalAll, icon: Package, iconColor: 'text-blue-600' },
|
||||
...dynamicStats,
|
||||
];
|
||||
}, [itemTypeCodes, totalStats]);
|
||||
|
||||
// UniversalListPage Config
|
||||
const config: UniversalListConfig<ItemMaster> = {
|
||||
|
||||
Reference in New Issue
Block a user