# 리스트 페이지 공통화 현황 분석 > 작성일: 2026-02-05 > 목적: 리스트 페이지 반복 패턴 식별 및 공통화 가능성 분석 --- ## 📊 전체 현황 | 구분 | 수량 | |------|------| | 총 리스트 페이지 | 37개 | | UniversalListPage 사용 | 15개+ | | IntegratedListTemplateV2 직접 사용 | 5개+ | | 레거시 패턴 | 10개+ | --- ## 🏗️ 템플릿 계층 구조 ``` UniversalListPage (최상위 - config 기반) └── IntegratedListTemplateV2 (하위 - props 기반) └── 공통 UI 컴포넌트 ├── PageLayout ├── PageHeader ├── StatCards ├── DateRangeSelector ├── MobileFilter ├── ListMobileCard └── Table, Pagination 등 ``` --- ## 📁 리스트 페이지 목록 및 사용 템플릿 ### UniversalListPage 사용 (최신 패턴) | 파일 | 도메인 | 특징 | |------|--------|------| | `items/ItemListClient.tsx` | 품목관리 | 외부 훅(useItemList) 사용, 엑셀 업로드/다운로드 | | `pricing/PricingListClient.tsx` | 가격관리 | 외부 훅 사용 | | `production/WorkOrders/WorkOrderList.tsx` | 생산 | 공정 기반 탭, 외부 통계 API | | `outbound/ShipmentManagement/ShipmentList.tsx` | 출고 | 캘린더 통합, 날짜범위 필터 | | `outbound/VehicleDispatchManagement/VehicleDispatchList.tsx` | 배차 | - | | `material/ReceivingManagement/ReceivingList.tsx` | 입고 | - | | `material/StockStatus/StockStatusList.tsx` | 재고 | - | | `customer-center/NoticeManagement/NoticeList.tsx` | 공지사항 | 클라이언트 사이드 필터링 | | `customer-center/EventManagement/EventList.tsx` | 이벤트 | 클라이언트 사이드 필터링 | | `customer-center/InquiryManagement/InquiryList.tsx` | 문의 | - | | `customer-center/FAQManagement/FAQList.tsx` | FAQ | - | | `quality/InspectionManagement/InspectionList.tsx` | 품질검사 | - | | `process-management/ProcessListClient.tsx` | 공정관리 | - | | `pricing-table-management/PricingTableListClient.tsx` | 단가표 | - | | `pricing-distribution/PriceDistributionList.tsx` | 가격배포 | - | ### 건설 도메인 (UniversalListPage 사용) | 파일 | 기능 | |------|------| | `construction/management/ProjectListClient.tsx` | 프로젝트 목록 | | `construction/management/ConstructionManagementListClient.tsx` | 공사관리 목록 | | `construction/contract/ContractListClient.tsx` | 계약 목록 | | `construction/estimates/EstimateListClient.tsx` | 견적 목록 | | `construction/bidding/BiddingListClient.tsx` | 입찰 목록 | | `construction/pricing-management/PricingListClient.tsx` | 단가관리 목록 | | `construction/partners/PartnerListClient.tsx` | 협력사 목록 | | `construction/order-management/OrderManagementListClient.tsx` | 발주관리 목록 | | `construction/site-management/SiteManagementListClient.tsx` | 현장관리 목록 | | `construction/site-briefings/SiteBriefingListClient.tsx` | 현장브리핑 목록 | | `construction/handover-report/HandoverReportListClient.tsx` | 인수인계 목록 | | `construction/issue-management/IssueManagementListClient.tsx` | 이슈관리 목록 | | `construction/structure-review/StructureReviewListClient.tsx` | 구조검토 목록 | | `construction/utility-management/UtilityManagementListClient.tsx` | 유틸리티 목록 | | `construction/worker-status/WorkerStatusListClient.tsx` | 작업자 현황 | | `construction/progress-billing/ProgressBillingManagementListClient.tsx` | 기성관리 목록 | ### 기타/레거시 | 파일 | 비고 | |------|------| | `settings/PopupManagement/PopupList.tsx` | 팝업관리 | | `production/WorkResults/WorkResultList.tsx` | 작업실적 | | `quality/PerformanceReportManagement/PerformanceReportList.tsx` | 성과보고서 | | `board/BoardList/BoardListUnified.tsx` | 통합 게시판 | --- ## 🔄 반복 패턴 분석 ### 1. Badge 색상 매핑 (매우 반복적) 각 페이지마다 개별 정의되어 있는 패턴: ```typescript // ItemListClient.tsx const badges: Record = { FG: { variant: 'default', className: 'bg-purple-100 text-purple-700 border-purple-200' }, PT: { variant: 'default', className: 'bg-orange-100 text-orange-700 border-orange-200' }, // ... }; // WorkOrderList.tsx const PRIORITY_COLORS: Record = { '긴급': 'bg-red-100 text-red-700', '우선': 'bg-orange-100 text-orange-700', '일반': 'bg-gray-100 text-gray-700', }; // ShipmentList.tsx - types.ts에서 import export const SHIPMENT_STATUS_STYLES: Record = { ... }; ``` **현황**: - `src/lib/utils/status-config.ts`에 `createStatusConfig` 유틸 존재 - 일부 페이지만 사용 중 (대부분 개별 정의) ### 2. 상태 라벨 정의 (반복적) ```typescript // WorkOrderList.tsx - types.ts에서 import export const WORK_ORDER_STATUS_LABELS: Record = { pending: '대기', in_progress: '진행중', completed: '완료', }; // ShipmentList.tsx - types.ts에서 import export const SHIPMENT_STATUS_LABELS: Record = { ... }; ``` **현황**: 각 도메인 types.ts에서 개별 정의 ### 3. 필터 설정 (filterConfig) ```typescript // WorkOrderList.tsx const filterConfig: FilterFieldConfig[] = [ { key: 'status', label: '상태', type: 'single', options: [ { value: 'waiting', label: '작업대기' }, { value: 'in_progress', label: '진행중' }, { value: 'completed', label: '작업완료' }, ], }, { key: 'priority', label: '우선순위', type: 'single', options: [ { value: 'urgent', label: '긴급' }, { value: 'priority', label: '우선' }, { value: 'normal', label: '일반' }, ], }, ]; ``` **공통 필터 패턴**: - 상태 필터 (대기/진행/완료) - 우선순위 필터 (긴급/우선/일반) - 유형 필터 (전체/유형1/유형2...) ### 4. 행 클릭 핸들러 패턴 ```typescript // 모든 페이지에서 동일한 패턴 const handleRowClick = useCallback( (item: SomeType) => { router.push(`/ko/${basePath}/${item.id}?mode=view`); }, [router] ); ``` ### 5. 테이블 행 렌더링 (renderTableRow) ```typescript // 공통 구조 handleRowClick(item)}> e.stopPropagation()}> {globalIndex} {/* 데이터 컬럼들 */} {getStatusLabel(item.status)} ``` --- ## ✅ 이미 공통화된 것 | 유틸/컴포넌트 | 위치 | 사용률 | |--------------|------|--------| | `UniversalListPage` | templates/ | 높음 (15개+) | | `IntegratedListTemplateV2` | templates/ | 높음 | | `ListMobileCard`, `InfoField` | organisms/ | 높음 | | `MobileFilter` | molecules/ | 높음 | | `DateRangeSelector` | molecules/ | 높음 | | `StatCards` | organisms/ | 높음 | | `createStatusConfig` | lib/utils/ | **낮음** (일부만 사용) | --- ## ❌ 공통화 필요한 것 ### 높은 우선순위 (ROI 높음) | 패턴 | 현황 | 공통화 방안 | |------|------|-------------| | **Badge 색상 매핑** | 각 페이지 개별 정의 | `src/lib/utils/badge-styles.ts` 생성 | | **공통 필터 프리셋** | 각 페이지 개별 정의 | `src/lib/constants/filter-presets.ts` 생성 | | **우선순위 색상** | 각 페이지 개별 정의 | 공통 상수로 추출 | ### 중간 우선순위 | 패턴 | 현황 | 공통화 방안 | |------|------|-------------| | 상태 라벨 | 도메인별 types.ts | 도메인별 유지 (비즈니스 로직) | | 행 클릭 핸들러 | 각 페이지 개별 | UniversalListPage에서 처리 중 | --- ## 📋 공통화 대상 상세 ### 1. Badge 스타일 공통화 **현재 분산된 위치**: - `items/ItemListClient.tsx` - getItemTypeBadge() - `production/WorkOrders/types.ts` - WORK_ORDER_STATUS_COLORS - `outbound/ShipmentManagement/types.ts` - SHIPMENT_STATUS_STYLES - 기타 각 도메인별 개별 정의 **이미 존재하는 공통 유틸** (`src/lib/utils/status-config.ts`): ```typescript export const BADGE_STYLE_PRESETS: Record = { default: 'bg-gray-100 text-gray-800', success: 'bg-green-100 text-green-800', warning: 'bg-yellow-100 text-yellow-800', destructive: 'bg-red-100 text-red-800', info: 'bg-blue-100 text-blue-800', muted: 'bg-gray-100 text-gray-500', orange: 'bg-orange-100 text-orange-800', purple: 'bg-purple-100 text-purple-800', }; ``` **문제**: 존재하지만 대부분의 페이지에서 사용하지 않음 ### 2. 공통 필터 프리셋 **추출 가능한 공통 필터**: ```typescript // 상태 필터 (거의 모든 페이지) export const COMMON_STATUS_FILTER: FilterFieldConfig = { key: 'status', label: '상태', type: 'single', options: [ { value: 'pending', label: '대기' }, { value: 'in_progress', label: '진행중' }, { value: 'completed', label: '완료' }, ], }; // 우선순위 필터 (생산, 출고 등) export const COMMON_PRIORITY_FILTER: FilterFieldConfig = { key: 'priority', label: '우선순위', type: 'single', options: [ { value: 'urgent', label: '긴급' }, { value: 'priority', label: '우선' }, { value: 'normal', label: '일반' }, ], }; ``` ### 3. 우선순위 색상 통합 **현재 상태**: 여러 파일에서 동일한 색상 반복 ```typescript // 긴급: bg-red-100 text-red-700 // 우선: bg-orange-100 text-orange-700 // 일반: bg-gray-100 text-gray-700 ``` --- ## 🎯 권장 액션 ### Phase 1: 즉시 실행 가능 1. **`createStatusConfig` 사용률 높이기** - 기존 유틸 활용도 확인 - 새 페이지 작성 시 필수 사용 권장 2. **공통 필터 프리셋 파일 생성** - 위치: `src/lib/constants/filter-presets.ts` - 상태/우선순위/유형 필터 템플릿 3. **우선순위 색상 상수 통합** - 위치: `src/lib/utils/status-config.ts`에 추가 ### Phase 2: 점진적 적용 1. 신규 페이지는 공통 유틸 필수 사용 2. 기존 페이지는 수정 시 점진적 마이그레이션 3. 기능 변경 없이 import만 변경 --- ## 📊 공통화 효과 예측 | 항목 | Before | After | |------|--------|-------| | Badge 정의 위치 | 37개 파일에 분산 | 1개 파일 (+ import) | | 필터 프리셋 | 각 페이지 개별 | 공통 상수 재사용 | | 색상 변경 시 수정 범위 | 37개 파일 | 1개 파일 | | 신규 페이지 개발 시간 | 기존 페이지 참고 필요 | 공통 유틸 import만 | --- ## 📝 결론 1. **UniversalListPage는 이미 잘 구축됨** - 대부분 리스트가 사용 중 2. **Badge/필터 공통화가 주요 개선점** - 반복 코드 제거 가능 3. **기존 유틸(`createStatusConfig`) 활용도 낮음** - 홍보/가이드 필요 4. **기능 변경 없이 공통화 가능** - 리팩토링 리스크 낮음 --- ## ✅ 공통화 작업 완료 현황 (2026-02-05) ### 생성된 파일 | 파일 | 설명 | |------|------| | `src/lib/constants/filter-presets.ts` | 공통 필터 프리셋 (상태/우선순위/품목유형 등) | | `claudedocs/guides/badge-commonization-guide.md` | Badge 공통화 사용 가이드 | ### 수정된 파일 | 파일 | 변경 내용 | |------|----------| | `src/lib/utils/status-config.ts` | 우선순위/품목유형 설정 추가, 한글 라벨 지원 | | `src/components/production/WorkOrders/WorkOrderList.tsx` | 공통 유틸 적용 (샘플 마이그레이션) | ### 추가된 공통 유틸 **filter-presets.ts**: - `COMMON_STATUS_FILTER` - 대기/진행/완료 - `WORK_STATUS_FILTER` - 작업대기/진행중/작업완료 - `COMMON_PRIORITY_FILTER` - 긴급/우선/일반 - `ITEM_TYPE_FILTER` - 품목유형 - `createSingleFilter()`, `createMultiFilter()` - 커스텀 필터 생성 **status-config.ts**: - `getPriorityLabel()`, `getPriorityStyle()` - 우선순위 (한글/영문 모두 지원) - `getItemTypeLabel()`, `getItemTypeStyle()` - 품목유형 - `COMMON_STATUS_CONFIG`, `WORK_STATUS_CONFIG` 등 - 미리 정의된 상태 설정 ### 샘플 마이그레이션 결과 (WorkOrderList.tsx) **Before**: ```tsx // 개별 정의 const PRIORITY_COLORS: Record = { '긴급': 'bg-red-100 text-red-700', '우선': 'bg-orange-100 text-orange-700', '일반': 'bg-gray-100 text-gray-700', }; const filterConfig: FilterFieldConfig[] = [ { key: 'status', label: '상태', type: 'single', options: [...] }, { key: 'priority', label: '우선순위', type: 'single', options: [...] }, ]; ``` **After**: ```tsx // 공통 유틸 사용 import { WORK_STATUS_FILTER, COMMON_PRIORITY_FILTER } from '@/lib/constants/filter-presets'; import { getPriorityStyle } from '@/lib/utils/status-config'; const filterConfig = [WORK_STATUS_FILTER, COMMON_PRIORITY_FILTER]; ``` **효과**: - 코드 라인 20줄 → 3줄 - 필터 옵션 중복 정의 제거 - 색상 일관성 보장 --- ## 🔄 추가 마이그레이션 (2026-02-05 업데이트) ### 완료된 마이그레이션 | 파일 | 적용 내용 | 효과 | |------|----------|------| | `WorkOrderList.tsx` | WORK_STATUS_FILTER + COMMON_PRIORITY_FILTER + getPriorityStyle | 20줄 → 3줄 | | `ItemListClient.tsx` | getItemTypeStyle (품목유형 Badge) | 17줄 → 4줄 | | `ItemDetailClient.tsx` | getItemTypeStyle (품목유형 Badge) | 17줄 → 4줄 | ### 마이그레이션 제외 대상 (도메인 특화 설정) | 파일 | 제외 사유 | |------|----------| | `PricingListClient.tsx` | 다른 색상 체계 (SM=cyan, BENDING 추가 타입) | | `StockStatus/types.ts` | 레거시 타입 지원 (raw_material, bent_part 등) | | `ShipmentManagement/types.ts` | 다른 우선순위 라벨 (보통/낮음) | | `issue-management/types.ts` | 2단계 우선순위 (긴급/일반만) | | `WipProductionModal.tsx` | 버튼 스타일 우선순위 (Badge 아님) | | `ReceivingList.tsx` | 도메인 특화 상태 (입고대기/입고완료/검사완료) | | HR 페이지들 | 도메인 특화 상태 설정 | | 건설 도메인 페이지들 | 도메인 특화 상태 설정 | ### 분석 결과 요약 1. **공통 유틸 적용 완료 페이지**: 3개 (WorkOrderList, ItemListClient, ItemDetailClient) 2. **도메인 특화 설정 페이지**: 34개 (개별 유지가 적절) 3. **결론**: 대부분의 페이지는 도메인별 특화된 상태/라벨/색상을 사용하며, 이는 비즈니스 로직을 명확히 반영하기 위해 의도된 설계 ### 공통 유틸 권장 사용 시나리오 1. **신규 리스트 페이지 생성 시**: 표준 패턴(대기/진행/완료, 긴급/우선/일반) 사용 2. **품목유형 Badge**: 일관된 색상 적용 필요 시 `getItemTypeStyle` 사용 3. **우선순위 Badge**: 표준 3단계(긴급/우선/일반) 사용 시 `getPriorityStyle` 사용 --- ## 🎨 getPresetStyle 마이그레이션 완료 (2026-02-05 최종) ### 마이그레이션 완료 파일 (22개) | 파일 | 적용 내용 | |------|----------| | `orders/OrderRegistration.tsx` | success, info preset | | `pricing-distribution/PriceDistributionDetail.tsx` | success preset | | `pricing/PricingFormClient.tsx` | purple, info, success preset | | `quality/InspectionManagement/InspectionList.tsx` | success, destructive preset | | `quality/InspectionManagement/InspectionCreate.tsx` | success, destructive preset | | `quality/InspectionManagement/InspectionDetail.tsx` | success, destructive preset | | `accounting/PurchaseManagement/index.tsx` | info preset | | `accounting/PurchaseManagement/PurchaseDetail.tsx` | orange preset (기존) | | `accounting/PurchaseManagement/PurchaseDetailModal.tsx` | orange preset (기존) | | `accounting/VendorManagement/CreditAnalysisModal/CreditAnalysisDocument.tsx` | info preset | | `quotes/QuoteRegistration.tsx` | success preset | | `pricing/PricingHistoryDialog.tsx` | info preset | | `business/construction/management/KanbanColumn.tsx` | info preset | | `business/construction/management/DetailCard.tsx` | warning preset | | `business/construction/management/StageCard.tsx` | warning preset | | `business/construction/management/ProjectCard.tsx` | info preset | | `production/WorkerScreen/WorkCard.tsx` | success, destructive preset | | `production/WorkerScreen/ProcessDetailSection.tsx` | warning preset | | `production/ProductionDashboard/index.tsx` | orange, success preset (기존) | | `items/ItemForm/BOMSection.tsx` | info preset (기존) | | `items/DynamicItemForm/sections/DynamicBOMSection.tsx` | info preset (기존) | | `items/ItemMasterDataManagement/tabs/MasterFieldTab/index.tsx` | info preset | | `customer-center/InquiryManagement/InquiryList.tsx` | warning, success preset (기존) | | `hr/EmployeeManagement/CSVUploadDialog.tsx` | success, destructive preset (기존) | ### 마이그레이션 제외 파일 (유지) | 파일 | 제외 사유 | |------|----------| | `business/MainDashboard.tsx` | CEO 대시보드 - 다양한 데이터 시각화용 고유 색상 (achievement %, overdue days 등) | | `pricing/PricingListClient.tsx` | 도메인 특화 색상 체계 (SM=cyan, BENDING type 등) | | `business/CEODashboard/sections/TodayIssueSection.tsx` | 알림 유형별 고유 색상+아이콘 (notification_type 기반) | | `dev/DevToolbar.tsx` | 개발 도구 (운영 무관) | | `ui/status-badge.tsx` | 이미 status-config.ts 사용 중 | | `items/ItemDetailClient.tsx` | getItemTypeStyle 사용 (도메인 특화) | | `items/ItemListClient.tsx` | getItemTypeStyle 사용 (도메인 특화) | ### 사용된 Preset 유형 통계 | Preset | 사용 횟수 | 용도 | |--------|----------|------| | `success` | 15+ | 완료, 일치, 활성, 긍정적 상태 | | `info` | 10+ | 정보성 라벨, 진행 상태, 문서 타입 | | `warning` | 6+ | 진행중, 주의 필요, 선행 생산 | | `destructive` | 5+ | 오류, 불일치, 긴급 | | `orange` | 3+ | 품의서/지출결의서, 지연 | | `purple` | 2+ | 최종 확정, 특수 상태 | ### 마이그레이션 효과 1. **코드 일관성**: 22개 파일에서 동일한 유틸리티 함수 사용 2. **유지보수성**: 색상 변경 시 `status-config.ts` 한 곳만 수정 3. **가독성 향상**: `getPresetStyle('success')` vs `bg-green-100 text-green-700 border-green-200` 4. **타입 안전성**: TypeScript로 프리셋 이름 자동완성