# 판매관리 페이지 마이그레이션 계획

> **작성일**: 2025-12-02
> **소스**: `sam-design/sam-design`
> **타겟**: `sam-react-prod` (Next.js)
> **예상 소요 시간**: 4~6시간

---

## 0. 예상 작업 시간

| Phase | 작업 내용 | 예상 시간 |
|-------|----------|----------|
| Phase 1 | 공통 UI 컴포넌트 (~1,400줄) | 1~2시간 |
| Phase 2 | 거래처관리 (~500줄) | 30분~1시간 |
| Phase 3 | 견적관리 + 하위 컴포넌트 (~1,500줄+) | 2~3시간 |
| **총합** | **~3,400줄+** | **4~6시간** |

> **참고**: 테스트/디버깅 시간 포함, 예상치 못한 이슈 발생 시 추가 소요 가능

---

## 1. 마이그레이션 대상 요약

| 페이지 | 파일 | 크기 | 분할 필요 | 템플릿 |
|--------|------|------|----------|--------|
| 견적관리 | `QuoteManagement.tsx` | 1,001줄 | O (경계선) | IntegratedListTemplateV2 |
| 거래처관리 | `CustomerAccountManagement.tsx` | 425줄 | X | ListPageTemplate |

---

## 2. 견적관리 (`QuoteManagement.tsx`)

### 2.1 파일 정보
- **경로**: `sam-design/src/components/QuoteManagement.tsx`
- **크기**: 1,001줄
- **템플릿**: `IntegratedListTemplateV2`

### 2.2 컴포넌트 구조
```
QuoteManagement
├── IntegratedListTemplateV2 (목록 템플릿)
│   ├── PageHeader (제목: "견적 목록")
│   ├── StatCards (4개 통계 카드)
│   │   ├── 이번 달 견적 금액
│   │   ├── 진행중 견적 금액
│   │   ├── 이번 주 신규 견적
│   │   └── 이번 달 수주 전환율
│   ├── SearchFilter (검색바)
│   ├── TabChip 탭
│   │   ├── 전체
│   │   ├── 최초작성
│   │   ├── 수정중
│   │   ├── 최종확정
│   │   └── 수주전환
│   ├── DataTable (데스크톱 테이블)
│   └── ListMobileCard (모바일 카드)
├── QuoteManagement3Write (등록/수정 화면)
├── QuoteManagement3Detail (상세 화면)
├── QuoteDetailView (상세 화면 - 샘플용)
└── StandardDialog (산출내역서/삭제 확인)
```

### 2.3 주요 기능
- 목록 조회 (페이지네이션, 검색, 필터)
- 탭 기반 상태 필터링
- 체크박스 선택 + 일괄 삭제
- 모바일 인피니티 스크롤
- CRUD (등록/조회/수정/삭제)
- 산출내역서 다이얼로그

### 2.4 분할 제안
```
src/app/[locale]/(protected)/sales/quotes/
├── page.tsx                    # 목록 (라우팅 + 상태 관리)
├── components/
│   ├── QuoteList.tsx          # 목록 컴포넌트
│   ├── QuoteTableRow.tsx      # 테이블 행
│   └── QuoteMobileCard.tsx    # 모바일 카드
├── create/
│   └── page.tsx               # 견적 등록
├── [id]/
│   ├── page.tsx               # 견적 상세
│   └── edit/
│       └── page.tsx           # 견적 수정
```

### 2.5 의존성 컴포넌트
| 컴포넌트 | 경로 | 마이그레이션 필요 |
|----------|------|------------------|
| IntegratedListTemplateV2 | templates/ | O |
| PageHeader | organisms/ | 이미 존재 |
| PageLayout | organisms/ | 이미 존재 |
| StatCards | organisms/ | O |
| SearchFilter | organisms/ | O |
| TabChip | atoms/ | O |
| ListMobileCard | organisms/ | O |
| DataTable | organisms/ | O |
| StandardDialog | molecules/ | O |
| QuoteManagement3Write | components/ | O (별도 분석 필요) |
| QuoteManagement3Detail | components/ | O (별도 분석 필요) |

---

## 3. 거래처관리 (`CustomerAccountManagement.tsx`)

### 3.1 파일 정보
- **경로**: `sam-design/src/components/CustomerAccountManagement.tsx`
- **크기**: 425줄
- **템플릿**: `ListPageTemplate`

### 3.2 컴포넌트 구조
```
CustomerAccountManagement
├── ListPageTemplate (목록 템플릿)
│   ├── PageHeader (제목: "매출처 목록")
│   ├── StatCards (3개 통계 카드)
│   │   ├── 전체 거래처
│   │   ├── 활성 거래처
│   │   └── 비활성 거래처
│   ├── SearchFilter (검색바)
│   ├── DataTable (데스크톱 테이블)
│   │   └── columns: 코드, 거래처명, 사업자번호, 대표자, 전화번호, 업태, 업종, 상태, 관리
│   └── MobileCard (모바일 카드)
└── Dialog (등록/수정 모달)
    └── FormFields: 거래처명, 사업자번호, 대표자, 전화번호, 주소, 이메일, 업태, 업종
```

### 3.3 주요 기능
- 거래처 목록 조회 (검색)
- CRUD (등록/수정/삭제)
- 모달 기반 폼

### 3.4 Next.js 구조 제안
```
src/app/[locale]/(protected)/sales/customers/
├── page.tsx                    # 목록 + 모달 (425줄이라 단일 파일 가능)
└── components/
    └── CustomerForm.tsx        # 폼 분리 (선택)
```

### 3.5 의존성 컴포넌트
| 컴포넌트 | 경로 | 마이그레이션 필요 |
|----------|------|------------------|
| ListPageTemplate | templates/ | O |
| PageHeader | organisms/ | 이미 존재 |
| PageLayout | organisms/ | 이미 존재 |
| StatCards | organisms/ | O |
| SearchFilter | organisms/ | O |
| DataTable | organisms/ | O |
| MobileCard | organisms/ | O |
| Dialog | ui/ | 이미 존재 |

---

## 4. 공통 테이블 UI 기준 (중요)

### 4.1 최종 기준: 견적관리 페이지 테이블

> **공통 테이블 UI는 `QuoteManagement.tsx`의 테이블 형태를 최종 기준으로 적용**

거래처관리를 포함한 모든 목록 페이지는 견적관리 페이지의 테이블 UI를 따릅니다.

### 4.2 테이블 화면 구조

```
┌─────────────────────────────────────────────────────────────┐
│ [PageHeader] 견적 목록                          [등록 버튼] │
├─────────────────────────────────────────────────────────────┤
│ [StatCards] 4개 통계 카드 (2x2 또는 4열)                    │
├─────────────────────────────────────────────────────────────┤
│ [SearchFilter] 검색바 + 추가 필터                           │
├─────────────────────────────────────────────────────────────┤
│ [TabChip] 전체 | 최초작성 | 수정중 | 최종확정 | 수주전환    │
├───┬───────────────────────────────────────────────────┬─────┤
│ ☐ │ 번호 | 견적번호 | 접수일 | 상태 | ... | 비고 | 작업   │
├───┼───────────────────────────────────────────────────┼─────┤
│ ☐ │ 10   | Q2024-001| 2024-01 | 진행 | ... | -    | [편집]│
│ ☐ │ 9    | Q2024-002| 2024-01 | 확정 | ... | -    | [편집]│
├───┴───────────────────────────────────────────────────┴─────┤
│ [Pagination] 전체 100개 중 1-20개 표시   [이전] 1 2 3 [다음]│
└─────────────────────────────────────────────────────────────┘
```

### 4.3 반응형 구조

| 화면 크기 | 뷰 타입 | 특징 |
|-----------|---------|------|
| **데스크톱** (1280px+) | 테이블 뷰 | 체크박스 + 전체 컬럼 + 페이지네이션 |
| **태블릿** (~1279px) | 카드 뷰 | 2~3열 그리드 + 인피니티 스크롤 |
| **모바일** (~767px) | 카드 뷰 | 1열 + 인피니티 스크롤 |

**반응형 전환 기준**:
- `xl:` (1280px+) → 테이블 뷰
- `md:` (768px~1279px) → 카드 그리드 (2~3열)
- 기본 → 카드 단일 열

### 4.4 테이블 기능 목록

#### 필수 기능
- [ ] **체크박스 선택**: 개별 선택 + 전체 선택
- [ ] **일괄 삭제**: 2개 이상 선택 시 삭제 버튼 표시
- [ ] **역순 번호**: totalCount 기준 역순 (최신이 1번이 아닌 N번)
- [ ] **행 클릭**: 상세 페이지로 이동
- [ ] **액션 버튼**: 선택된 행에만 수정/삭제 버튼 표시

#### 페이지네이션 (데스크톱)
- [ ] 페이지당 20개 표시
- [ ] 현재 페이지 표시 (1-20 / 100개)
- [ ] 이전/다음 버튼
- [ ] 페이지 번호 (현재 ±2 범위)

#### 인피니티 스크롤 (모바일/태블릿)
- [ ] Intersection Observer 사용
- [ ] 20개씩 추가 로드
- [ ] Sentinel 요소로 트리거

### 4.5 적용 대상

| 페이지 | 적용 내용 |
|--------|----------|
| **견적관리** | 기준 페이지 (이미 적용됨) |
| **거래처관리** | 동일한 테이블 UI 적용 필요 |
| **향후 목록 페이지** | 모두 동일한 공통 테이블 UI 사용 |

### 4.6 공통 테이블 컴포넌트 구조

```
공통 테이블 UI
├── IntegratedListTemplateV2 (템플릿)
│   ├── PageHeader
│   ├── StatCards
│   ├── SearchFilter
│   ├── TabChip (선택적)
│   ├── DataTable (데스크톱)
│   │   ├── 체크박스 컬럼
│   │   ├── 데이터 컬럼들
│   │   ├── 액션 컬럼
│   │   └── 페이지네이션
│   └── ListMobileCard (모바일/태블릿)
│       ├── 체크박스
│       ├── 헤더 뱃지
│       ├── 정보 그리드
│       └── 액션 버튼 (선택 시)
```

---

## 5. 공통 UI 컴포넌트 마이그레이션

### 5.1 마이그레이션 필요 목록

| 컴포넌트 | 소스 경로 | 타겟 경로 | 크기 | 우선순위 |
|----------|----------|----------|------|----------|
| StatCards | organisms/StatCards.tsx | organisms/ | 53줄 | P1 |
| SearchFilter | organisms/SearchFilter.tsx | organisms/ | 54줄 | P1 |
| DataTable | organisms/DataTable.tsx | organisms/ | 313줄 | P1 |
| MobileCard | organisms/MobileCard.tsx | organisms/ | 104줄 | P1 |
| ListMobileCard | organisms/ListMobileCard.tsx | organisms/ | 169줄 | P1 |
| TabChip | atoms/TabChip.tsx | atoms/ | ~50줄 | P2 |
| ListPageTemplate | templates/ListPageTemplate.tsx | templates/ | 143줄 | P2 |
| IntegratedListTemplateV2 | templates/IntegratedListTemplateV2.tsx | templates/ | 491줄 | P2 |
| StandardDialog | molecules/StandardDialog.tsx | molecules/ | ~150줄 | P3 |
| InfoField | organisms/ListMobileCard.tsx | organisms/ | 8줄 | P1 |

### 5.2 Next.js 타겟 구조
```
src/components/
├── atoms/
│   └── TabChip.tsx                 # NEW
├── molecules/
│   └── StandardDialog.tsx          # NEW
├── organisms/
│   ├── PageHeader.tsx              # 기존
│   ├── PageLayout.tsx              # 기존
│   ├── StatCards.tsx               # NEW
│   ├── SearchFilter.tsx            # NEW
│   ├── DataTable.tsx               # NEW
│   ├── MobileCard.tsx              # NEW
│   └── ListMobileCard.tsx          # NEW
├── templates/
│   ├── ListPageTemplate.tsx        # NEW
│   └── IntegratedListTemplateV2.tsx # NEW
└── ui/                             # 기존 (변경 없음)
```

### 5.3 컴포넌트 상세

#### StatCards (53줄)
```typescript
interface StatCardData {
  label: string;
  value: string | number;
  icon?: LucideIcon;
  iconColor?: string;
  trend?: { value: string; isPositive: boolean };
}
```
- 2x2 또는 4열 그리드
- 아이콘 + 라벨 + 값 + 트렌드

#### SearchFilter (54줄)
```typescript
interface SearchFilterProps {
  searchValue: string;
  onSearchChange: (value: string) => void;
  searchPlaceholder?: string;
  filterButton?: boolean;
  onFilterClick?: () => void;
  extraActions?: ReactNode;
}
```
- 검색 아이콘 + Input
- 모바일 플레이스홀더 변경

#### DataTable (313줄)
```typescript
interface Column<T> {
  key: keyof T | string;
  label: string;
  type?: CellType; // text, number, currency, date, status, badge, actions, custom
  render?: (value: any, row: T, index?: number) => ReactNode;
}
```
- 타입별 셀 렌더링
- 페이지네이션 지원
- 로딩/빈 상태 처리

#### ListMobileCard (169줄)
```typescript
interface ListMobileCardProps {
  id: string;
  isSelected: boolean;
  onToggleSelection: () => void;
  onCardClick?: () => void;
  headerBadges?: ReactNode;
  title: string;
  statusBadge?: ReactNode;
  infoGrid: ReactNode;
  actions?: ReactNode;
}
```
- 체크박스 포함
- 선택 시 스타일 변경
- InfoField 하위 컴포넌트

---

## 6. 작업 순서 (권장)

### Phase 1: 공통 UI 컴포넌트 (선행) ✅ 완료
- [x] StatCards 마이그레이션
- [x] SearchFilter 마이그레이션
- [x] DataTable 마이그레이션
- [x] MobileCard 마이그레이션
- [x] ListMobileCard + InfoField 마이그레이션
- [x] TabChip 마이그레이션
- [x] ListPageTemplate 마이그레이션
- [x] IntegratedListTemplateV2 마이그레이션
- [x] BadgeSm 마이그레이션 (추가)
- [x] StatusBadge 마이그레이션 (추가)
- [x] IconWithBadge 마이그레이션 (추가)
- [x] TableActions 마이그레이션 (추가)
- [x] EmptyState 마이그레이션 (추가)
- [x] ScreenVersionHistory 마이그레이션 (추가)
- [x] StandardDialog 마이그레이션 (추가)
- [x] formatAmount 유틸리티 마이그레이션 (추가)

### Phase 2: 거래처관리 (간단한 것 먼저) ✅ 완료
- [x] 라우트 생성: `/sales/customers`
- [x] CustomerAccountManagement 마이그레이션
- [x] 테스트 및 검증 (빌드 통과)

### Phase 3: 견적관리 (복잡한 것) ✅ 완료
- [x] 라우트 생성: `/sales/quotes`
- [x] QuoteManagement 목록 페이지 마이그레이션
- [x] Separator 컴포넌트 추가 (의존성)
- [x] 테스트 및 검증 (빌드 통과)
- [ ] QuoteManagement3Write 분석 및 마이그레이션 (향후 작업)
- [ ] QuoteManagement3Detail 분석 및 마이그레이션 (향후 작업)

---

## 7. 주의사항

### 7.1 React → Next.js 마이그레이션 체크리스트
- [ ] `'use client'` 디렉티브 추가 (상태/이벤트 사용 시)
- [ ] `localStorage` 접근 시 `typeof window !== 'undefined'` 체크
- [ ] `useRouter` → `next/navigation`으로 변경
- [ ] 이미지 → `next/image` 사용
- [ ] 링크 → `next/link` 사용

### 6.2 스타일 호환성
- sam-design: Tailwind CSS + shadcn/ui
- sam-react-prod: Tailwind CSS + shadcn/ui (동일)
- cn() 유틸리티 경로 확인 필요

### 6.3 의존성 확인
```bash
# sam-design에서 사용하는 라이브러리
- lucide-react
- sonner (toast)
- react-hook-form (폼)
- zod (validation)
```

---

## 7. 예상 작업량

| 항목 | 예상 크기 |
|------|----------|
| 공통 UI 컴포넌트 | ~1,400줄 |
| 거래처관리 | ~500줄 |
| 견적관리 (분할 포함) | ~1,500줄+ |
| **총합** | **~3,400줄+** |

---

## 8. 관련 파일 참조

### sam-design 소스 파일
```
sam-design/sam-design/src/components/
├── QuoteManagement.tsx
├── CustomerAccountManagement.tsx
├── atoms/
│   └── TabChip.tsx
├── molecules/
│   └── StandardDialog.tsx
├── organisms/
│   ├── StatCards.tsx
│   ├── SearchFilter.tsx
│   ├── DataTable.tsx
│   ├── MobileCard.tsx
│   └── ListMobileCard.tsx
└── templates/
    ├── ListPageTemplate.tsx
    └── IntegratedListTemplateV2.tsx
```

### Next.js 타겟 경로
```
sam-react-prod/src/
├── app/[locale]/(protected)/sales/
│   ├── quotes/
│   │   └── page.tsx
│   └── customers/
│       └── page.tsx
└── components/
    ├── atoms/
    ├── molecules/
    ├── organisms/
    └── templates/
```