# 페이지 빌더 (Page Builder) 구현 문서 > **작성일**: 2026-01-22 > **상태**: 개발 중 (테스트 버전) > **경로**: `/dev/page-builder` > **Git 상태**: `.gitignore`에 등록되어 버전 관리 제외 (테스트용) --- ## 1. 개요 ### 1.1 목적 품목기준관리(Item Master Data Management)의 폼 구조를 **시각적으로(WYSIWYG)** 편집할 수 있는 Framer 스타일의 페이지 빌더입니다. ### 1.2 핵심 기능 - 드래그 앤 드롭으로 섹션/필드 배치 - 실시간 미리보기 (데스크탑/태블릿/모바일) - **API 연동**: 품목기준관리 API와 동기화 - 조건부 표시 설정 (필드 값에 따른 섹션/필드 표시/숨김) - Undo/Redo 지원 - JSON 내보내기/가져오기 ### 1.3 접근 방법 ``` URL: http://localhost:3000/dev/page-builder ``` --- ## 2. 파일 구조 ``` src/app/[locale]/(protected)/dev/page-builder/ ├── page.tsx # 페이지 진입점 ├── PageBuilderClient.tsx # 메인 클라이언트 컴포넌트 ├── PLAN.md # 초기 기획 문서 │ ├── components/ │ ├── index.ts # 컴포넌트 배럴 export │ ├── ComponentPalette.tsx # 좌측 컴포넌트 팔레트 (섹션/필드 드래그) │ ├── BuilderCanvas.tsx # 중앙 캔버스 (드롭 영역, 미리보기) │ ├── PropertyPanel.tsx # 우측 속성 패널 (섹션/필드 편집) │ ├── PageSelector.tsx # 페이지 목록 관리 │ └── ConditionEditor.tsx # 조건부 표시 설정 UI │ ├── hooks/ │ ├── usePageBuilder.ts # 섹션/필드 CRUD, 선택 상태 관리 │ ├── usePageManager.ts # 페이지 CRUD, API 연동, 저장/로드 │ ├── useHistory.ts # Undo/Redo 히스토리 관리 │ └── useItemMasterSync.ts # (미사용) 초기 API 동기화 시도 │ ├── types/ │ ├── index.ts # 타입 배럴 export │ ├── builder.types.ts # BuilderPage, BuilderSection, BuilderField 등 │ └── constants.ts # 필드 타입, 섹션 타입 옵션 상수 │ └── utils/ ├── index.ts # 유틸 배럴 export └── transformers.ts # API ↔ Builder 타입 변환 함수 ``` --- ## 3. 핵심 타입 정의 ### 3.1 BuilderPage ```typescript interface BuilderPage { id: string; name: string; // 페이지 이름 (예: "소모품 등록") itemType: ItemType; // 품목 유형 (FG, PT, SM, RM, CS) sections: BuilderSection[]; createdAt: string; updatedAt: string; } ``` ### 3.2 BuilderSection ```typescript interface BuilderSection { id: string; title: string; description?: string; sectionType: SectionType; // BASIC, BOM, CERTIFICATION 등 columns: 1 | 2 | 3; // 레이아웃 열 수 isCollapsible?: boolean; isDefaultOpen?: boolean; fields: BuilderField[]; displayCondition?: DisplayCondition; // 조건부 표시 order: number; } ``` ### 3.3 BuilderField ```typescript interface BuilderField { id: string; name: string; // 필드 라벨 fieldKey: string; // API 키 (예: "item_name") inputType: FieldInputType; // textbox, number, dropdown 등 required: boolean; placeholder?: string; defaultValue?: string; options?: DropdownOption[]; // 드롭다운용 colSpan?: 1 | 2 | 3; description?: string; displayCondition?: DisplayCondition; validationRules?: ValidationRule[]; order: number; } ``` ### 3.4 DisplayCondition (조건부 표시) ```typescript interface DisplayCondition { enabled: boolean; logic: 'AND' | 'OR'; conditions: FieldCondition[]; } interface FieldCondition { fieldKey: string; operator: 'equals' | 'not_equals' | 'contains' | 'not_contains'; expectedValue: string; } ``` --- ## 4. API 연동 ### 4.1 사용하는 API 품목기준관리와 **동일한 API** 사용: ```typescript // src/lib/api/item-master.ts itemMasterApi.init() // 전체 페이지/섹션/필드 조회 itemMasterApi.sections.create(pageId, data) // 섹션 생성 itemMasterApi.sections.update(id, data) // 섹션 수정 itemMasterApi.sections.delete(id) // 섹션 삭제 itemMasterApi.fields.create(sectionId, data)// 필드 생성 itemMasterApi.fields.update(id, data) // 필드 수정 itemMasterApi.fields.delete(id) // 필드 삭제 ``` ### 4.2 API 모드 토글 - **API 모드 ON**: 백엔드 API에서 데이터 로드/저장 - **API 모드 OFF**: localStorage에서 로드/저장 (오프라인 테스트용) - 설정은 localStorage에 저장되어 새로고침 후에도 유지 ### 4.3 동기화 로직 (usePageManager.ts) ```typescript const syncPageToAPI = async (page: BuilderPage) => { // 1. 원본 데이터와 현재 데이터 비교 // 2. 삭제된 섹션/필드 → API DELETE 호출 // 3. 새로 추가된 섹션/필드 → API CREATE 호출 // 4. 수정된 섹션/필드 → API UPDATE 호출 // 5. 완료 후 API에서 최신 데이터 다시 로드 }; ``` ### 4.4 타입 변환 (transformers.ts) ```typescript // API → Builder 변환 transformPagesToBuilder(apiData): BuilderPage[] // Builder → API 변환 transformSectionToAPI(section): APISectionCreateData transformFieldToAPI(field): APIFieldCreateData // ID 구분 (API ID는 숫자, 로컬 ID는 문자열) isApiId(id: string): boolean // "123" → true, "section_abc123" → false ``` --- ## 5. 주요 컴포넌트 설명 ### 5.1 PageBuilderClient.tsx 메인 컴포넌트로 전체 레이아웃 구성: - 상단: 툴바 (미리보기 모드, Undo/Redo, 저장 버튼들) - 좌측: PageSelector + ComponentPalette - 중앙: BuilderCanvas - 우측: PropertyPanel 주요 상태: ```typescript const [isAPIMode, setIsAPIMode] = useState(true); // API 모드 const [previewMode, setPreviewMode] = useState<'desktop' | 'tablet' | 'mobile'>('desktop'); ``` ### 5.2 PageSelector.tsx 페이지 목록 관리: - 페이지 선택/생성/삭제/복제/이름변경 - 호버 시 액션 버튼 표시 (배경색 포함으로 긴 제목도 가리지 않음) ### 5.3 BuilderCanvas.tsx 드래그 앤 드롭 캔버스: - 섹션 드롭 → 새 섹션 추가 - 필드 드롭 → 해당 섹션에 필드 추가 - 요소 클릭 → 선택 (PropertyPanel에서 편집) ### 5.4 PropertyPanel.tsx 선택된 요소의 속성 편집: - 섹션: 제목, 설명, 타입, 열 수, 접기 설정, 조건부 표시 - 필드: 이름, 키, 타입, 필수여부, 옵션, 조건부 표시 ### 5.5 ConditionEditor.tsx 조건부 표시 설정 UI: - 다른 필드 값에 따라 현재 섹션/필드 표시/숨김 - AND/OR 논리 연산 지원 - 여러 조건 추가 가능 --- ## 6. 사용 방법 ### 6.1 기본 워크플로우 1. `/dev/page-builder` 접속 2. **API 모드 ON** 확인 (우측 상단 토글) 3. 좌측에서 페이지 선택 (소모품, 원자재 등) 4. 컴포넌트 팔레트에서 섹션/필드를 캔버스로 드래그 5. 캔버스에서 요소 클릭 → 우측 패널에서 속성 편집 6. **"API 저장"** 버튼 클릭 → 백엔드에 저장 7. 품목기준관리 페이지에서 변경사항 확인 ### 6.2 저장 버튼 종류 | 버튼 | 기능 | |------|------| | API 저장 (초록색) | 현재 페이지를 백엔드 API에 저장 | | 현재 페이지 저장 (JSON) | 현재 페이지를 JSON 파일로 다운로드 | | 전체 저장 | 모든 페이지를 JSON 파일로 다운로드 | | 가져오기 | JSON 파일에서 페이지 데이터 로드 | ### 6.3 Undo/Redo - **실행 취소**: 마지막 작업 취소 - **다시 실행**: 취소한 작업 복원 - 히스토리는 세션 동안만 유지 --- ## 7. 테스트 완료 항목 ### 7.1 API 연동 테스트 (2026-01-22) | 테스트 | 결과 | |--------|------| | 페이지 빌더에서 섹션 제목 수정 | ✅ "기본정보" → "기본정보 (빌더테스트)" | | API 저장 버튼 클릭 | ✅ `PUT /api/proxy/item-master/sections/92` (200 OK) | | 품목기준관리 페이지 반영 확인 | ✅ 변경된 제목 표시 확인 | ### 7.2 UI 수정 (2026-01-22) - 페이지 목록 호버 버튼에 배경색 추가 (긴 제목 가림 방지) --- ## 8. 알려진 이슈 / TODO ### 8.1 현재 이슈 - [ ] 새 섹션/필드 생성 후 order 값 자동 계산 필요 - [ ] BOM 섹션 타입 특수 처리 (자재명세표) - [ ] 드래그 앤 드롭 순서 변경 시 API order 업데이트 ### 8.2 향후 개선 사항 - [ ] 실시간 미리보기에서 실제 폼 렌더링 (DynamicItemForm 연동) - [ ] 필드 유효성 검사 규칙 편집 UI - [ ] 섹션/필드 복사-붙여넣기 - [ ] 다중 선택 및 일괄 편집 - [ ] 변경사항 diff 뷰어 ### 8.3 Git 관련 - 현재 `.gitignore`에 등록되어 있음: `src/app/**/dev/page-builder/` - 정식 배포 시 gitignore에서 제거 필요 --- ## 9. 관련 파일 ### 9.1 품목기준관리 (연동 대상) ``` src/app/[locale]/(protected)/master-data/item-master-data-management/page.tsx src/components/items/ItemMasterDataManagement/ src/lib/api/item-master.ts ``` ### 9.2 동적 품목 폼 (렌더링 대상) ``` src/components/items/DynamicItemForm/ ``` --- ## 10. 참고 문서 - 초기 기획: `src/app/[locale]/(protected)/dev/page-builder/PLAN.md` - API 문서: `claudedocs/api/item-master-api.md` (있다면) --- *마지막 업데이트: 2026-01-22*