feat(WEB): Phase 6 IntegratedDetailTemplate 마이그레이션 완료

Phase 6 마이그레이션 (41개 컴포넌트 완료):
- 건설/시공: 협력업체, 시공관리, 기성관리, 발주관리, 계약관리 등
- 영업: 견적관리(V2), 고객관리(V2), 수주관리
- 회계: 청구관리, 매입관리, 매출관리, 거래처관리, 악성채권 등
- 생산: 작업지시, 검수관리
- 출고: 출하관리
- 자재: 입고관리, 재고현황
- 고객센터: 문의관리, 이벤트관리, 공지관리
- 인사: 직원관리
- 설정: 권한관리

주요 변경사항:
- 34개 xxxConfig.ts 파일 생성 (설정 기반 페이지 구성)
- PageLayout/PageHeader → IntegratedDetailTemplate 통합
- 일관된 타이틀/버튼 영역 (목록, 상세, 수정, 삭제)
- 1112줄 코드 감소 (중복 제거)

프로젝트 공통화 현황 분석 문서 추가:
- 상세 페이지 62%, 목록 페이지 82% 공통화 달성
- 추가 공통화 기회 및 로드맵 정리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-01-20 15:51:02 +09:00
parent 6f457b28f3
commit 61e3a0ed60
71 changed files with 4743 additions and 4402 deletions

View File

@@ -1,13 +1,19 @@
'use client';
import { useRouter } from 'next/navigation';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
/**
* 사원 상세 컴포넌트
* IntegratedDetailTemplate 마이그레이션 완료 (2026-01-20)
*
* 특이사항:
* - 기본정보, 인사정보, 사용자정보 카드
* - 수정/삭제 버튼 표시
*/
import { useCallback } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { Users, ArrowLeft, Edit, Trash2 } from 'lucide-react';
import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
import { employeeConfig } from './employeeConfig';
import type { Employee } from './types';
import {
EMPLOYEE_STATUS_LABELS,
@@ -25,21 +31,15 @@ interface EmployeeDetailProps {
}
export function EmployeeDetail({ employee, onEdit, onDelete }: EmployeeDetailProps) {
const router = useRouter();
// onDelete 핸들러 (Promise 반환)
const handleFormDelete = useCallback(async () => {
onDelete();
return { success: true };
}, [onDelete]);
const handleBack = () => {
router.push('/ko/hr/employee-management');
};
return (
<PageLayout>
<PageHeader
title="사원 상세"
description="사원 정보를 확인합니다"
icon={Users}
/>
<div className="space-y-6">
// 폼 콘텐츠 렌더링
const renderFormContent = useCallback(() => (
<div className="space-y-6">
{/* 기본 정보 */}
<Card>
<CardHeader className="flex flex-row items-center justify-between">
@@ -204,24 +204,19 @@ export function EmployeeDetail({ employee, onEdit, onDelete }: EmployeeDetailPro
</Card>
)}
{/* 버튼 영역 */}
<div className="flex items-center justify-between">
<Button variant="outline" onClick={handleBack}>
<ArrowLeft className="w-4 h-4 mr-2" />
</Button>
<div className="flex items-center gap-2">
<Button variant="outline" onClick={onDelete} className="text-destructive hover:bg-destructive hover:text-destructive-foreground">
<Trash2 className="w-4 h-4 mr-2" />
</Button>
<Button onClick={onEdit}>
<Edit className="w-4 h-4 mr-2" />
</Button>
</div>
</div>
</div>
</PageLayout>
</div>
), [employee]);
return (
<IntegratedDetailTemplate
config={employeeConfig}
mode="view"
initialData={employee}
itemId={employee.id}
onEdit={onEdit}
onDelete={handleFormDelete}
renderView={() => renderFormContent()}
renderForm={() => renderFormContent()}
/>
);
}

View File

@@ -0,0 +1,30 @@
import { Users } from 'lucide-react';
import type { DetailConfig } from '@/components/templates/IntegratedDetailTemplate/types';
/**
* 사원 상세 페이지 Config
*
* 참고: 이 config는 타이틀/버튼 영역만 정의
* 폼 내용은 renderView/renderForm에서 처리
*
* 특이사항:
* - view 모드 지원
* - 수정/삭제 버튼 표시
* - 기본정보, 인사정보, 사용자정보 카드
*/
export const employeeConfig: DetailConfig = {
title: '사원 상세',
description: '사원 정보를 확인합니다',
icon: Users,
basePath: '/hr/employee-management',
fields: [], // renderView/renderForm 사용으로 필드 정의 불필요
gridColumns: 2,
actions: {
showBack: true,
showDelete: true,
showEdit: true,
backLabel: '목록으로',
editLabel: '수정',
deleteLabel: '삭제',
},
};