# EstimateDetailForm.tsx 파일 분할 계획서

## 현황 분석

- **파일 위치**: `src/components/business/juil/estimates/EstimateDetailForm.tsx`
- **현재 라인 수**: 2,088줄
- **문제점**: 단일 파일에 모든 섹션, 핸들러, 상태 관리가 집중되어 유지보수 어려움

## 파일 구조 분석

### 현재 구조 (라인 범위)

| 구분 | 라인 | 설명 |
|------|------|------|
| Imports | 1-56 | React, UI 컴포넌트, 타입 |
| 상수/유틸 | 58-75 | MOCK_MATERIALS, MOCK_EXPENSES, formatAmount |
| Props | 77-81 | EstimateDetailFormProps |
| State | 88-127 | formData, 로딩, 다이얼로그, 모달 상태 |
| 핸들러 - 네비게이션 | 130-140 | handleBack, handleEdit, handleCancel |
| 핸들러 - 저장/삭제 | 143-182 | handleSave, handleConfirmSave, handleDelete, handleConfirmDelete |
| 핸들러 - 견적 요약 | 185-227 | handleAddSummaryItem, handleRemoveSummaryItem, handleSummaryItemChange |
| 핸들러 - 공과 상세 | 230-259 | handleAddExpenseItem, handleRemoveExpenseItem, handleExpenseItemChange |
| 핸들러 - 단가 조정 | 262-283 | handlePriceAdjustmentChange |
| 핸들러 - 견적 상세 | 286-343 | handleAddDetailItem, handleRemoveDetailItem, handleDetailItemChange |
| 핸들러 - 파일 업로드 | 346-435 | handleDocumentUpload, handleDocumentRemove, 드래그앤드롭 |
| useMemo | 438-482 | pageTitle, pageDescription, headerActions |
| JSX - 견적 정보 | 496-526 | 견적 정보 Card |
| JSX - 현장설명회 | 528-551 | 현장설명회 정보 Card |
| JSX - 입찰 정보 | 553-736 | 입찰 정보 Card + 파일 업로드 |
| JSX - 견적 요약 | 738-890 | 견적 요약 정보 Table |
| JSX - 공과 상세 | 892-1071 | 공과 상세 Table |
| JSX - 단가 조정 | 1073-1224 | 품목 단가 조정 Table |
| JSX - 견적 상세 | 1226-2017 | 견적 상세 Table (가장 큰 섹션) |
| 모달/다이얼로그 | 2020-2085 | 전자결재, 견적서, 삭제/저장 다이얼로그 |

---

## 분할 계획

### 1단계: 섹션 컴포넌트 분리

```
src/components/business/juil/estimates/
├── EstimateDetailForm.tsx          # 메인 컴포넌트 (축소)
├── sections/
│   ├── index.ts                    # 섹션 export
│   ├── EstimateInfoSection.tsx     # 견적 정보 + 현장설명회 + 입찰 정보
│   ├── EstimateSummarySection.tsx  # 견적 요약 정보
│   ├── ExpenseDetailSection.tsx    # 공과 상세
│   ├── PriceAdjustmentSection.tsx  # 품목 단가 조정
│   └── EstimateDetailTableSection.tsx  # 견적 상세 테이블
├── hooks/
│   ├── index.ts                    # hooks export
│   └── useEstimateCalculations.ts  # 계산 로직 (면적, 무게, 단가 등)
└── utils/
    ├── index.ts                    # utils export
    ├── constants.ts                # MOCK_MATERIALS, MOCK_EXPENSES
    └── formatters.ts               # formatAmount
```

### 2단계: 각 파일 상세

#### 2.1 constants.ts (~20줄)
```typescript
// MOCK_MATERIALS, MOCK_EXPENSES 이동
export const MOCK_MATERIALS = [...];
export const MOCK_EXPENSES = [...];
```

#### 2.2 formatters.ts (~10줄)
```typescript
// formatAmount 함수 이동
export function formatAmount(amount: number): string { ... }
```

#### 2.3 useEstimateCalculations.ts (~100줄)
```typescript
// 견적 상세 테이블의 계산 로직 분리
// - 면적, 무게, 철제스크린, 코킹, 레일, 하장 등 계산
// - 합계 계산 로직
export function useEstimateCalculations(
  item: EstimateDetailItem,
  priceAdjustmentData: PriceAdjustmentData,
  useAdjustedPrice: boolean
) { ... }

export function calculateTotals(
  items: EstimateDetailItem[],
  priceAdjustmentData: PriceAdjustmentData,
  useAdjustedPrice: boolean
) { ... }
```

#### 2.4 EstimateInfoSection.tsx (~250줄)
```typescript
// 견적 정보 + 현장설명회 + 입찰 정보 Card 3개
// 파일 업로드 영역 포함
interface EstimateInfoSectionProps {
  formData: EstimateDetailFormData;
  setFormData: React.Dispatch<React.SetStateAction<EstimateDetailFormData>>;
  isViewMode: boolean;
  documentInputRef: React.RefObject<HTMLInputElement>;
}
```

#### 2.5 EstimateSummarySection.tsx (~200줄)
```typescript
// 견적 요약 정보 테이블
interface EstimateSummarySectionProps {
  summaryItems: EstimateSummaryItem[];
  summaryMemo: string;
  isViewMode: boolean;
  onAddItem: () => void;
  onRemoveItem: (id: string) => void;
  onItemChange: (id: string, field: keyof EstimateSummaryItem, value: string | number) => void;
  onMemoChange: (memo: string) => void;
}
```

#### 2.6 ExpenseDetailSection.tsx (~200줄)
```typescript
// 공과 상세 테이블
interface ExpenseDetailSectionProps {
  expenseItems: ExpenseItem[];
  isViewMode: boolean;
  onAddItems: (count: number) => void;
  onRemoveSelected: () => void;
  onItemChange: (id: string, field: keyof ExpenseItem, value: string | number) => void;
  onSelectItem: (id: string, selected: boolean) => void;
  onSelectAll: (selected: boolean) => void;
}
```

#### 2.7 PriceAdjustmentSection.tsx (~200줄)
```typescript
// 품목 단가 조정 테이블
interface PriceAdjustmentSectionProps {
  priceAdjustmentData: PriceAdjustmentData;
  isViewMode: boolean;
  onPriceChange: (key: string, value: number) => void;
  onSave: () => void;
  onApplyAll: () => void;
  onReset: () => void;
}
```

#### 2.8 EstimateDetailTableSection.tsx (~600줄)
```typescript
// 견적 상세 테이블 (가장 큰 섹션)
interface EstimateDetailTableSectionProps {
  detailItems: EstimateDetailItem[];
  priceAdjustmentData: PriceAdjustmentData;
  useAdjustedPrice: boolean;
  isViewMode: boolean;
  onAddItems: (count: number) => void;
  onRemoveItem: (id: string) => void;
  onRemoveSelected: () => void;
  onItemChange: (id: string, field: keyof EstimateDetailItem, value: string | number) => void;
  onSelectItem: (id: string, selected: boolean) => void;
  onSelectAll: (selected: boolean) => void;
  onApplyAdjustedPrice: () => void;
  onReset: () => void;
}
```

---

## 분할 후 예상 라인 수

| 파일 | 예상 라인 수 |
|------|-------------|
| EstimateDetailForm.tsx (메인) | ~300줄 |
| EstimateInfoSection.tsx | ~250줄 |
| EstimateSummarySection.tsx | ~200줄 |
| ExpenseDetailSection.tsx | ~200줄 |
| PriceAdjustmentSection.tsx | ~200줄 |
| EstimateDetailTableSection.tsx | ~600줄 |
| useEstimateCalculations.ts | ~100줄 |
| constants.ts | ~20줄 |
| formatters.ts | ~10줄 |
| **총합** | ~1,880줄 (약 10% 감소) |

---

## 실행 순서

### Phase 1: 유틸리티 분리 (5분)
- [ ] `utils/constants.ts` 생성
- [ ] `utils/formatters.ts` 생성
- [ ] `utils/index.ts` 생성

### Phase 2: 계산 로직 분리 (10분)
- [ ] `hooks/useEstimateCalculations.ts` 생성
- [ ] `hooks/index.ts` 생성

### Phase 3: 섹션 컴포넌트 분리 (30분)
- [ ] `sections/EstimateInfoSection.tsx` 생성
- [ ] `sections/EstimateSummarySection.tsx` 생성
- [ ] `sections/ExpenseDetailSection.tsx` 생성
- [ ] `sections/PriceAdjustmentSection.tsx` 생성
- [ ] `sections/EstimateDetailTableSection.tsx` 생성
- [ ] `sections/index.ts` 생성

### Phase 4: 메인 컴포넌트 리팩토링 (10분)
- [ ] EstimateDetailForm.tsx에서 분리된 컴포넌트 import
- [ ] 핸들러 정리 및 props 전달
- [ ] 불필요한 코드 제거

### Phase 5: 검증 (5분)
- [ ] TypeScript 빌드 확인
- [ ] 기능 동작 확인

---

## 주의사항

1. **상태 관리**: formData, setFormData는 메인 컴포넌트에서 관리, 섹션에 props로 전달
2. **타입 일관성**: 기존 types.ts의 타입 그대로 사용
3. **핸들러 위치**: 핸들러는 메인 컴포넌트에 유지, 섹션에 콜백으로 전달
4. **조정단가 상태**: appliedPrices, useAdjustedPrice는 메인 컴포넌트에서 관리

---

## 5가지 수정사항 (분할 후 진행)

| # | 항목 | 수정 위치 (분할 후) |
|---|------|-------------------|
| 2 | 품목 단가 초기화 → 품목 단가만 | PriceAdjustmentSection.tsx |
| 3 | 견적 상세 인풋 필드 추가 | EstimateDetailTableSection.tsx |
| 4 | 견적 상세 초기화 버튼 수정 | EstimateDetailTableSection.tsx |
| 5 | 각 섹션별 초기화 분리 | 각 Section 컴포넌트 |