- _index.md: 문서 목록 및 버전 관리 - 01~09: 아키텍처, API패턴, 컴포넌트, 폼, 스타일, 인증, 대시보드, 컨벤션 - 10: 문서 API 연동 스펙 (api-specs에서 이관) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
173 lines
4.9 KiB
Markdown
173 lines
4.9 KiB
Markdown
# 03. 컴포넌트 설계
|
|
|
|
> **대상**: 프론트엔드 개발자, 기획자
|
|
> **버전**: 1.0.0
|
|
> **최종 수정**: 2026-03-09
|
|
|
|
---
|
|
|
|
## 1. 설계 원칙
|
|
|
|
- **모든 페이지는 Client Component** (`'use client'` 필수)
|
|
- **Config-Driven**: 설정 객체로 페이지 동작 정의 → 일관성 + 빠른 개발
|
|
- **기존 패턴 우선**: 새 컴포넌트 만들기 전 반드시 유사 컴포넌트 검색
|
|
- **계층 준수**: atoms → molecules → organisms → templates → pages
|
|
|
|
---
|
|
|
|
## 2. 페이지 3대 유형
|
|
|
|
### 2.1 리스트 페이지 → UniversalListPage
|
|
|
|
**사용 현황**: 59+ 페이지
|
|
|
|
```typescript
|
|
// 패턴: page.tsx는 얇은 껍데기, 비즈니스 로직은 도메인 컴포넌트에
|
|
// src/app/[locale]/(protected)/accounting/bills/page.tsx
|
|
'use client';
|
|
import { BillManagement } from '@/components/accounting/BillManagement';
|
|
export default function BillsPage() {
|
|
return <BillManagement />;
|
|
}
|
|
|
|
// src/components/accounting/BillManagement/index.tsx
|
|
export function BillManagement() {
|
|
const config: UniversalListConfig<BillRecord> = {
|
|
title: '어음관리',
|
|
icon: FileText,
|
|
columns: [...],
|
|
actions: { getList: getBills },
|
|
// ... 나머지 설정
|
|
};
|
|
return <UniversalListPage config={config} />;
|
|
}
|
|
```
|
|
|
|
**config로 제어하는 것들:**
|
|
- 컬럼 정의, 정렬, 필터
|
|
- 검색/날짜 선택기
|
|
- 통계 카드
|
|
- 체크박스/선택
|
|
- 액션 버튼
|
|
- 모바일 카드 렌더링
|
|
- Excel 내보내기
|
|
|
|
### 2.2 상세/폼 페이지 → IntegratedDetailTemplate
|
|
|
|
**모드**: create(등록), view(조회), edit(수정)
|
|
|
|
```typescript
|
|
<IntegratedDetailTemplate
|
|
mode="create"
|
|
title="품목 등록"
|
|
fields={fieldDefinitions}
|
|
onSave={handleSave}
|
|
onDelete={handleDelete}
|
|
/>
|
|
```
|
|
|
|
**또는 Card 기반 수동 구성** (기존 패턴):
|
|
```typescript
|
|
<PageLayout>
|
|
<PageHeader title="품목 상세" />
|
|
<Card>
|
|
<CardContent>
|
|
{/* 폼 필드들 */}
|
|
</CardContent>
|
|
</Card>
|
|
</PageLayout>
|
|
```
|
|
|
|
### 2.3 대시보드 → 커스텀 섹션 조합
|
|
|
|
CEO 대시보드처럼 여러 섹션을 조합하는 경우:
|
|
```typescript
|
|
<PageLayout>
|
|
<SummaryNavBar />
|
|
<div className="space-y-6">
|
|
{sectionOrder.map(key => renderSection(key))}
|
|
</div>
|
|
</PageLayout>
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 컴포넌트 계층별 가이드
|
|
|
|
### atoms (src/components/atoms/)
|
|
- 가장 작은 재사용 단위
|
|
- HTML 요소 확장 또는 단일 기능
|
|
- 예: ScrollableButtonGroup, PhoneInput, BusinessNumberInput
|
|
|
|
### molecules (src/components/molecules/)
|
|
- atom 2개 이상 조합
|
|
- **FormField**: Label + Input 통합 (신규 폼 필수)
|
|
- 예: FormField, DateRangeFilter
|
|
|
|
### organisms (src/components/organisms/)
|
|
- 독립적 기능 블록, 페이지에 바로 배치 가능
|
|
- **내보내기 확인**: `src/components/organisms/index.ts`
|
|
|
|
| 컴포넌트 | 용도 |
|
|
|---------|------|
|
|
| PageHeader | 페이지 제목 + 액션 버튼 |
|
|
| PageLayout | 페이지 콘텐츠 래퍼 (패딩/max-width) |
|
|
| DataTable | 범용 데이터 테이블 |
|
|
| StatCards | 통계 카드 모음 |
|
|
| SearchFilter | 검색/필터 바 |
|
|
| SearchableSelectionModal\<T\> | 검색+선택 모달 (제네릭) |
|
|
| MobileCard | 모바일 리스트 카드 |
|
|
|
|
### templates (src/components/templates/)
|
|
- 페이지 전체 구조 정의
|
|
- config 객체로 동작 제어
|
|
|
|
| 템플릿 | 용도 | 사용 수 |
|
|
|--------|------|--------|
|
|
| UniversalListPage | 리스트/목록 페이지 | 59+ |
|
|
| IntegratedDetailTemplate | 상세/등록/수정 페이지 | 10+ |
|
|
|
|
### 도메인 컴포넌트 (src/components/{domain}/)
|
|
- 비즈니스 로직 포함
|
|
- 도메인별 폴더 분류
|
|
|
|
```
|
|
components/
|
|
├── accounting/ # 회계: 입금, 출금, 전표, 어음, 세금계산서
|
|
├── hr/ # 인사: 사원, 급여, 근태
|
|
├── production/ # 생산: 공정, 생산일보
|
|
├── orders/ # 영업: 주문, 견적, 수주
|
|
├── business/ # 경영: CEO 대시보드
|
|
└── common/ # 공통: 계정과목 설정 등 여러 도메인에서 사용
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 새 페이지 만들기 체크리스트
|
|
|
|
### 리스트 페이지
|
|
1. `src/app/[locale]/(protected)/{domain}/{page}/page.tsx` 생성
|
|
2. `src/components/{domain}/{ComponentName}/index.tsx` 생성
|
|
3. `src/components/{domain}/{ComponentName}/actions.ts` 생성
|
|
4. UniversalListPage config 작성
|
|
5. types 정의 (API 응답 → 프론트 타입 변환)
|
|
|
|
### 상세/폼 페이지
|
|
1. 기존 유사 페이지 검색 (패턴 참고)
|
|
2. IntegratedDetailTemplate 사용 가능한지 확인
|
|
3. 아니면 Card 기반 수동 구성
|
|
|
|
### 모달/팝업
|
|
1. `SearchableSelectionModal<T>` 사용 가능한지 먼저 확인
|
|
2. 아니면 Radix Dialog 직접 사용
|
|
3. `alert()`, `confirm()` 사용 금지 → Dialog 또는 toast
|
|
|
|
---
|
|
|
|
## 5. 컴포넌트 레지스트리
|
|
|
|
개발 환경에서 `/dev/component-registry` 접속하면:
|
|
- 전체 컴포넌트 목록 (실시간 스캔)
|
|
- 컴포넌트 간 관계도 (imports, usedBy)
|
|
- 새 컴포넌트 생성 전 기존 컴포넌트 확인 필수
|