feat(WEB): IntegratedDetailTemplate 통합 템플릿 구현 및 Phase 1~8 마이그레이션

- Phase 1: 기안함(DocumentCreate) 마이그레이션
- Phase 2: 작업지시(WorkOrderCreate/Edit) 마이그레이션
- Phase 3: 출하(ShipmentCreate/Edit) 마이그레이션
- Phase 4: 사원(EmployeeForm) 마이그레이션
- Phase 5: 게시판(BoardForm) 마이그레이션
- Phase 6: 1:1문의(InquiryForm) 마이그레이션
- Phase 7: 공정(ProcessForm) 마이그레이션
- Phase 8: 수입검사/품질검사(InspectionCreate) 마이그레이션
- DetailActions에 showSave 옵션 추가
- 각 도메인별 config 파일 생성

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
유병철
2026-01-20 19:31:07 +09:00
parent 6b0ffc810b
commit 62ef2b1ff9
24 changed files with 861 additions and 534 deletions

View File

@@ -1,11 +1,16 @@
'use client';
import { useState, useEffect, useRef } from 'react';
/**
* 사원 등록/수정/상세 폼 컴포넌트
* IntegratedDetailTemplate 마이그레이션 (2025-01-20)
*/
import { useState, useEffect, useCallback } from 'react';
import { useDaumPostcode } from '@/hooks/useDaumPostcode';
import { useRouter, useParams } from 'next/navigation';
import { toast } from 'sonner';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
import { employeeCreateConfig, employeeEditConfig, employeeConfig } from './employeeConfig';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
@@ -17,7 +22,7 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Users, Plus, Trash2, ArrowLeft, Save, Settings, Camera, Edit } from 'lucide-react';
import { Plus, Trash2, Settings, Camera } from 'lucide-react';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { FieldSettingsDialog } from './FieldSettingsDialog';
import type {
@@ -357,16 +362,12 @@ export function EmployeeForm({
router.push(`/${locale}/hr/employee-management`);
};
return (
<PageLayout>
{/* 헤더 + 버튼 영역 */}
<div className="flex items-start justify-between mb-6">
<PageHeader
title={title}
description={description}
icon={Users}
/>
{!isViewMode && (
// ===== 폼 콘텐츠 렌더링 =====
const renderFormContent = useCallback(() => (
<>
{/* 항목 설정 버튼 */}
{!isViewMode && (
<div className="flex justify-end mb-4">
<Button
type="button"
variant="outline"
@@ -375,10 +376,10 @@ export function EmployeeForm({
<Settings className="w-4 h-4 mr-2" />
</Button>
)}
</div>
</div>
)}
<form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-6">
{/* 사원 정보 - 프로필 사진 + 기본 정보 */}
<Card>
<CardHeader>
@@ -932,31 +933,7 @@ export function EmployeeForm({
</CardContent>
</Card>
{/* 버튼 영역 */}
<div className="flex items-center justify-between">
<Button type="button" variant="outline" onClick={handleCancel}>
<ArrowLeft className="w-4 h-4 mr-2" />
</Button>
{isViewMode ? (
<div className="flex gap-2">
<Button type="button" onClick={onEdit}>
<Edit className="w-4 h-4 mr-2" />
</Button>
<Button type="button" variant="destructive" onClick={onDelete}>
<Trash2 className="w-4 h-4 mr-2" />
</Button>
</div>
) : (
<Button type="submit">
<Save className="w-4 h-4 mr-2" />
{mode === 'create' ? '등록' : '저장'}
</Button>
)}
</div>
</form>
</div>
{/* 항목 설정 모달 */}
<FieldSettingsDialog
@@ -965,6 +942,33 @@ export function EmployeeForm({
settings={fieldSettings}
onSave={handleSaveFieldSettings}
/>
</PageLayout>
</>
), [
formData, errors, isViewMode, mode, fieldSettings, showFieldSettings,
ranks, titles, departments, handleChange, handleSaveFieldSettings,
handleAddDepartmentPosition, handleRemoveDepartmentPosition,
handleDepartmentSelect, handlePositionSelect, openPostcode,
]);
// Config 선택 (create/edit/view)
const getConfig = () => {
if (mode === 'view') return employeeConfig;
if (mode === 'edit') return employeeEditConfig;
return employeeCreateConfig;
};
return (
<IntegratedDetailTemplate
config={getConfig()}
mode={mode}
isLoading={false}
isSubmitting={false}
onBack={handleCancel}
onCancel={handleCancel}
onSubmit={handleSubmit}
onEdit={onEdit}
onDelete={onDelete}
renderForm={renderFormContent}
/>
);
}

View File

@@ -1,6 +1,40 @@
'use client';
import { Users } from 'lucide-react';
import type { DetailConfig } from '@/components/templates/IntegratedDetailTemplate/types';
/**
* 사원 등록 페이지 Config
* IntegratedDetailTemplate 마이그레이션 (2025-01-20)
*/
export const employeeCreateConfig: DetailConfig = {
title: '사원 등록',
description: '새로운 사원을 등록합니다',
icon: Users,
basePath: '/hr/employee-management',
fields: [],
actions: {
showBack: true,
showEdit: false,
showDelete: false,
showSave: true,
submitLabel: '등록',
},
};
/**
* 사원 수정 페이지 Config
*/
export const employeeEditConfig: DetailConfig = {
...employeeCreateConfig,
title: '사원 수정',
description: '사원 정보를 수정합니다',
actions: {
...employeeCreateConfig.actions,
submitLabel: '저장',
},
};
/**
* 사원 상세 페이지 Config
*