Files
sam-react-prod/claudedocs/sales/[PLAN-2025-12-02] sales-pages-migration.md
byeongcheolryu 3be5714805 refactor: 품목관리 시스템 리팩토링 및 Sales 페이지 추가
DynamicItemForm 개선:
- 품목코드 자동생성 기능 추가
- 조건부 표시 로직 개선
- 불필요한 컴포넌트 정리 (DynamicField, DynamicSection 등)
- 타입 시스템 단순화

새로운 기능:
- Sales 페이지 마이그레이션 (견적관리, 거래처관리)
- 공통 컴포넌트 추가 (atoms, molecules, organisms, templates)

문서화:
- 구현 문서 및 참조 문서 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 12:48:41 +09:00

16 KiB

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

작성일: 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: (768px1279px) → 카드 그리드 (23열)
  • 기본 → 카드 단일 열

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줄)

interface StatCardData {
  label: string;
  value: string | number;
  icon?: LucideIcon;
  iconColor?: string;
  trend?: { value: string; isPositive: boolean };
}
  • 2x2 또는 4열 그리드
  • 아이콘 + 라벨 + 값 + 트렌드

SearchFilter (54줄)

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

DataTable (313줄)

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줄)

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 컴포넌트 (선행) 완료

  • StatCards 마이그레이션
  • SearchFilter 마이그레이션
  • DataTable 마이그레이션
  • MobileCard 마이그레이션
  • ListMobileCard + InfoField 마이그레이션
  • TabChip 마이그레이션
  • ListPageTemplate 마이그레이션
  • IntegratedListTemplateV2 마이그레이션
  • BadgeSm 마이그레이션 (추가)
  • StatusBadge 마이그레이션 (추가)
  • IconWithBadge 마이그레이션 (추가)
  • TableActions 마이그레이션 (추가)
  • EmptyState 마이그레이션 (추가)
  • ScreenVersionHistory 마이그레이션 (추가)
  • StandardDialog 마이그레이션 (추가)
  • formatAmount 유틸리티 마이그레이션 (추가)

Phase 2: 거래처관리 (간단한 것 먼저) 완료

  • 라우트 생성: /sales/customers
  • CustomerAccountManagement 마이그레이션
  • 테스트 및 검증 (빌드 통과)

Phase 3: 견적관리 (복잡한 것) 완료

  • 라우트 생성: /sales/quotes
  • QuoteManagement 목록 페이지 마이그레이션
  • Separator 컴포넌트 추가 (의존성)
  • 테스트 및 검증 (빌드 통과)
  • QuoteManagement3Write 분석 및 마이그레이션 (향후 작업)
  • QuoteManagement3Detail 분석 및 마이그레이션 (향후 작업)

7. 주의사항

7.1 React → Next.js 마이그레이션 체크리스트

  • 'use client' 디렉티브 추가 (상태/이벤트 사용 시)
  • localStorage 접근 시 typeof window !== 'undefined' 체크
  • useRouternext/navigation으로 변경
  • 이미지 → next/image 사용
  • 링크 → next/link 사용

6.2 스타일 호환성

  • sam-design: Tailwind CSS + shadcn/ui
  • sam-react-prod: Tailwind CSS + shadcn/ui (동일)
  • cn() 유틸리티 경로 확인 필요

6.3 의존성 확인

# 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/