# 레이아웃 추가 가이드

화면관리 시스템에서 새로운 레이아웃을 추가하는 방법을 설명합니다.

## 📋 목차

1. [현재 지원하는 레이아웃](#현재-지원하는-레이아웃)
2. [CLI를 이용한 자동 생성](#cli를-이용한-자동-생성)
3. [생성된 파일 구조](#생성된-파일-구조)
4. [레이아웃 커스터마이징](#레이아웃-커스터마이징)
5. [카드 레이아웃 상세 가이드](#카드-레이아웃-상세-가이드)
6. [고급 설정](#고급-설정)
7. [문제 해결](#문제-해결)

---

## 🎨 현재 지원하는 레이아웃

### 기본 레이아웃 (Basic)

#### 1. 그리드 레이아웃 (Grid Layout)

- **ID**: `grid`
- **존 개수**: 4개 (동적 설정 가능)
- **특징**: 격자 형태의 균등 분할 레이아웃
- **용도**: 카드, 대시보드 위젯 배치

#### 2. 플렉스박스 레이아웃 (Flexbox Layout)

- **ID**: `flexbox`
- **존 개수**: 2개 (동적 설정 가능)
- **특징**: 가로/세로 방향 설정 가능, 자동 크기 조정
- **방향 설정**: 수평(`row`) / 수직(`column`)
- **용도**: 반응형 레이아웃, 사이드바 구조

#### 3. 분할 레이아웃 (Split Layout)

- **ID**: `split`
- **존 개수**: 2개
- **특징**: 좌우 또는 상하 분할
- **용도**: 마스터-디테일 화면, 비교 화면

### 네비게이션 레이아웃 (Navigation)

#### 4. 아코디언 레이아웃 (Accordion Layout)

- **ID**: `accordion`
- **존 개수**: 3개
- **특징**: 접을 수 있는 섹션들
- **용도**: FAQ, 설정 패널, 단계별 폼

### 대시보드 레이아웃 (Dashboard)

#### 5. 카드 레이아웃 (Card Layout) ⭐ **데이터 기반**

- **ID**: `card-layout`
- **존 개수**: 6개 (디자인 모드), 데이터 기반 (실행 모드)
- **특징**: 실제 테이블 데이터를 카드 형태로 표시
- **핵심 기능**:
  - 테이블 컬럼 매핑 (타이틀, 서브타이틀, 설명, 이미지)
  - 동적 표시 컬럼 관리
  - 컬럼 라벨 우선 표시
  - 실시간 카드 스타일 설정
  - 한 행당 카드 수, 간격 조정
- **용도**: 상품 목록, 직원 카드, 프로젝트 카드

### 콘텐츠 레이아웃 (Content)

#### 6. 히어로 섹션 레이아웃 (Hero Section Layout)

- **ID**: `hero-section`
- **존 개수**: 3개
- **특징**: 대형 헤더 섹션과 하위 영역들
- **용도**: 랜딩 페이지, 제품 소개

---

## 🚀 CLI를 이용한 자동 생성

### 기본 사용법

```bash
# 기본 형태
node scripts/create-layout.js <레이아웃이름> [옵션]

# 예시
node scripts/create-layout.js card-grid --category=dashboard --zones=6 --description="카드 형태의 그리드 레이아웃"
```

### 📝 사용 가능한 옵션

| 옵션            | 필수 여부 | 기본값      | 설명              | 예시                                |
| --------------- | --------- | ----------- | ----------------- | ----------------------------------- |
| `--category`    | 선택      | `basic`     | 레이아웃 카테고리 | `--category=dashboard`              |
| `--zones`       | 선택      | `2`         | 영역 개수         | `--zones=4`                         |
| `--description` | 선택      | 자동 생성   | 레이아웃 설명     | `--description="사이드바 레이아웃"` |
| `--author`      | 선택      | `Developer` | 작성자 이름       | `--author="김개발"`                 |

### 🏷️ 카테고리 종류

| 카테고리     | 설명          | 예시 레이아웃            |
| ------------ | ------------- | ------------------------ |
| `basic`      | 기본 레이아웃 | 그리드, 플렉스박스, 분할 |
| `navigation` | 네비게이션    | 탭, 아코디언, 메뉴       |
| `dashboard`  | 대시보드      | 카드, 위젯, 차트         |
| `content`    | 콘텐츠        | 헤더-본문, 영웅 섹션     |
| `form`       | 폼            | 입력 폼, 설정 패널       |
| `table`      | 테이블        | 데이터 테이블, 목록      |

### 💡 이름 규칙

레이아웃 이름은 **하이픈(`-`)을 사용한 kebab-case**로 입력하면 자동으로 변환됩니다:

```bash
# 입력: hero-section
📁 디렉토리: hero-section/
🔖 ID: hero-section
📄 클래스명: HeroSection
🔧 변수명: heroSection
```

#### ✅ 올바른 이름 예시

- `card-grid`
- `side-navigation`
- `data-table`
- `hero-section`
- `my-awesome-layout`

#### ❌ 피해야 할 이름

- `CardGrid` (파스칼케이스)
- `card_grid` (스네이크케이스)
- `cardGrid` (카멜케이스)

---

## 📂 생성된 파일 구조

CLI로 레이아웃을 생성하면 다음과 같은 파일들이 자동으로 생성됩니다:

```
lib/registry/layouts/your-layout/
├── index.ts                    # 레이아웃 정의 및 등록
├── YourLayoutLayout.tsx        # React 컴포넌트
├── YourLayoutRenderer.tsx      # 렌더링 로직
├── config.ts                   # 기본 설정
├── types.ts                    # 타입 정의
└── README.md                   # 문서
```

### 🔧 각 파일의 역할

#### 1. `index.ts` - 레이아웃 정의

```typescript
export const YourLayoutDefinition = createLayoutDefinition({
  id: "your-layout",
  name: "yourLayout",
  nameEng: "Your Layout",
  description: "사용자 정의 레이아웃입니다",
  category: "basic",
  component: YourLayoutWrapper,
  defaultConfig: {
    /* 기본 설정 */
  },
  defaultZones: [
    /* 기본 영역들 */
  ],
});
```

#### 2. `YourLayoutLayout.tsx` - React 컴포넌트

```typescript
export const YourLayoutLayout: React.FC<YourLayoutProps> = ({ layout, isDesignMode, renderer, ...props }) => {
  // 레이아웃 UI 구현
};
```

#### 3. `YourLayoutRenderer.tsx` - 렌더링 로직

```typescript
export class YourLayoutRenderer extends AutoRegisteringLayoutRenderer {
  static layoutDefinition = YourLayoutDefinition;

  render(): React.ReactElement {
    return <YourLayoutLayout {...this.props} renderer={this} />;
  }
}
```

---

## 🎨 레이아웃 커스터마이징

### 1. 기본 구조 수정

생성된 `YourLayoutLayout.tsx`에서 레이아웃 구조를 정의합니다:

```typescript
export const YourLayoutLayout: React.FC<YourLayoutProps> = ({
  layout,
  isDesignMode = false,
  renderer,
}) => {
  const yourLayoutConfig = layout.layoutConfig.yourLayout;
  const containerStyle = renderer.getLayoutContainerStyle();

  // 레이아웃별 커스텀 스타일
  const yourLayoutStyle: React.CSSProperties = {
    ...containerStyle,
    display: "grid",
    gridTemplateColumns: "repeat(3, 1fr)",
    gridTemplateRows: "repeat(2, 200px)",
    gap: "16px",
    padding: "16px",
  };

  return (
    <div style={yourLayoutStyle}>
      {layout.zones.map((zone) => {
        const zoneChildren = renderer.getZoneChildren(zone.id);

        return (
          <div key={zone.id} className="zone-area">
            {/* 존 렌더링 */}
            {renderer.renderZone(zone, zoneChildren)}
          </div>
        );
      })}
    </div>
  );
};
```

### 2. 설정 옵션 추가

`config.ts`에서 레이아웃별 설정을 정의합니다:

```typescript
export const YourLayoutConfig = {
  defaultConfig: {
    yourLayout: {
      columns: 3, // 열 개수
      rows: 2, // 행 개수
      gap: 16, // 간격
      aspectRatio: "16:9", // 비율
      backgroundColor: "#ffffff",
      borderRadius: "8px",
    },
  },
};
```

### 3. 타입 정의

`types.ts`에서 설정 타입을 정의합니다:

```typescript
export interface YourLayoutConfig {
  columns?: number;
  rows?: number;
  gap?: number;
  aspectRatio?: string;
  backgroundColor?: string;
  borderRadius?: string;
}

export interface YourLayoutProps extends LayoutRendererProps {
  renderer: YourLayoutRenderer;
}
```

---

## 🎴 카드 레이아웃 상세 가이드

### 개요

카드 레이아웃은 **데이터 기반 레이아웃**으로, 실제 데이터베이스 테이블의 데이터를 카드 형태로 표시합니다. 두 가지 모드로 작동합니다:

- **디자인 모드**: 6개의 존이 있는 일반 레이아웃 (편집기에서)
- **실행 모드**: 테이블 데이터를 기반으로 한 동적 카드 생성

### 🔧 설정 방법

#### 1. 테이블 컬럼 매핑

카드의 각 부분에 어떤 테이블 컬럼을 표시할지 설정합니다:

```typescript
interface CardColumnMapping {
  titleColumn?: string; // 카드 제목에 표시할 컬럼
  subtitleColumn?: string; // 카드 서브타이틀에 표시할 컬럼
  descriptionColumn?: string; // 카드 설명에 표시할 컬럼
  imageColumn?: string; // 카드 이미지에 표시할 컬럼
  displayColumns?: string[]; // 추가로 표시할 컬럼들
}
```

#### 2. 카드 스타일 설정

카드의 외관을 세부적으로 조정할 수 있습니다:

```typescript
interface CardStyle {
  showTitle?: boolean; // 타이틀 표시 여부
  showSubtitle?: boolean; // 서브타이틀 표시 여부
  showDescription?: boolean; // 설명 표시 여부
  showImage?: boolean; // 이미지 표시 여부
  maxDescriptionLength?: number; // 설명 최대 길이
  cardsPerRow?: number; // 한 행당 카드 수
  cardSpacing?: number; // 카드 간격 (px)
}
```

### 📋 사용 가이드

#### 1. 카드 레이아웃 생성

1. **레이아웃 추가**: 템플릿에서 "카드 레이아웃" 선택
2. **테이블 선택**: 화면에서 사용할 테이블 선택
3. **컬럼 매핑**: 상세설정 패널에서 컬럼 매핑 설정

#### 2. 컬럼 매핑 설정

**상세설정 패널**에서 다음을 설정합니다:

1. **타이틀 컬럼**: 카드 제목으로 사용할 컬럼 (예: 상품명, 직원명)
2. **서브타이틀 컬럼**: 카드 부제목으로 사용할 컬럼 (예: 카테고리, 부서)
3. **설명 컬럼**: 카드 설명으로 사용할 컬럼 (예: 상세설명, 상태)
4. **이미지 컬럼**: 카드 이미지로 사용할 컬럼 (이미지 URL)

#### 3. 표시 컬럼 추가

추가로 표시하고 싶은 컬럼들을 동적으로 추가할 수 있습니다:

- **"+ 컬럼 추가"** 버튼 클릭
- 드롭다운에서 원하는 컬럼 선택
- 각 컬럼마다 **"삭제"** 버튼으로 제거 가능

#### 4. 카드 스타일 조정

- **한 행당 카드 수**: 1-6개 설정 가능
- **카드 간격**: 픽셀 단위로 조정
- **표시 옵션**: 타이틀, 서브타이틀, 설명, 이미지 개별 제어
- **설명 최대 길이**: 긴 설명 텍스트 자동 축약

### 🎨 카드 렌더링 로직

#### 라벨 우선 표시

컬럼명 대신 **라벨값을 우선 표시**합니다:

```typescript
// 컬럼 라벨 변환 함수
const getColumnLabel = (columnName: string) => {
  const column = tableColumns.find((col) => col.columnName === columnName);
  return column?.columnLabel || columnName; // 라벨이 있으면 라벨, 없으면 컬럼명
};

// 사용 예시
// 컬럼명: "reg_date" → 라벨: "등록일"
// 컬럼명: "user_name" → 라벨: "사용자명"
```

#### 데이터 가져오기

카드 레이아웃은 다음과 같이 데이터를 가져옵니다:

```typescript
// 테이블 데이터와 컬럼 정보를 병렬로 로드
const [dataResponse, columnsResponse] = await Promise.all([
  tableTypeApi.getTableData(tableName, { page: 1, size: 50 }),
  tableTypeApi.getColumns(tableName),
]);

// 카드 렌더링에 사용
setTableData(dataResponse.data);
setTableColumns(columnsResponse);
```

#### 카드 구조

각 카드는 다음과 같은 구조로 렌더링됩니다:

```typescript
// 카드 내용 구성
<div className="card">
  {/* 이미지 (설정된 경우) */}
  {showImage && imageColumn && (
    <img src={getColumnValue(item, imageColumn)} />
  )}

  {/* 타이틀 */}
  {showTitle && titleColumn && (
    <h3>{getColumnValue(item, titleColumn)}</h3>
  )}

  {/* 서브타이틀 */}
  {showSubtitle && subtitleColumn && (
    <p>{getColumnValue(item, subtitleColumn)}</p>
  )}

  {/* 설명 */}
  {showDescription && descriptionColumn && (
    <p>{truncateText(getColumnValue(item, descriptionColumn), maxLength)}</p>
  )}

  {/* 추가 표시 컬럼들 */}
  {displayColumns?.map(columnName => (
    <div key={columnName}>
      <span>{getColumnLabel(columnName)}:</span>
      <span>{getColumnValue(item, columnName)}</span>
    </div>
  ))}
</div>
```

### 💡 활용 예시

#### 1. 직원 카드

```json
{
  "columnMapping": {
    "titleColumn": "emp_name", // 직원명
    "subtitleColumn": "dept_name", // 부서명
    "descriptionColumn": "position", // 직책
    "imageColumn": "profile_image", // 프로필 사진
    "displayColumns": ["email", "phone", "hire_date"] // 이메일, 전화번호, 입사일
  },
  "cardStyle": {
    "cardsPerRow": 3,
    "cardSpacing": 16,
    "showTitle": true,
    "showSubtitle": true,
    "showDescription": true,
    "showImage": true
  }
}
```

#### 2. 상품 카드

```json
{
  "columnMapping": {
    "titleColumn": "product_name", // 상품명
    "subtitleColumn": "category_name", // 카테고리
    "descriptionColumn": "description", // 상품설명
    "imageColumn": "product_image", // 상품 이미지
    "displayColumns": ["price", "stock", "rating"] // 가격, 재고, 평점
  },
  "cardStyle": {
    "cardsPerRow": 4,
    "cardSpacing": 20,
    "maxDescriptionLength": 80
  }
}
```

#### 3. 프로젝트 카드

```json
{
  "columnMapping": {
    "titleColumn": "project_name", // 프로젝트명
    "subtitleColumn": "status", // 상태
    "descriptionColumn": "description", // 프로젝트 설명
    "displayColumns": ["start_date", "end_date", "manager", "progress"] // 시작일, 종료일, 담당자, 진행률
  },
  "cardStyle": {
    "cardsPerRow": 2,
    "cardSpacing": 24,
    "showImage": false
  }
}
```

### 🔍 주요 특징

#### 1. **실시간 설정 반영**

- 상세설정 패널에서 설정 변경 시 즉시 카드에 반영
- 체크박스로 표시 요소 실시간 제어
- 컬럼 매핑 변경 시 즉시 업데이트

#### 2. **라벨 우선 표시 시스템**

- 데이터베이스 컬럼명 대신 사용자 친화적인 라벨 표시
- 라벨이 없는 경우 컬럼명으로 대체
- 드롭다운에서도 "라벨명 (데이터타입)" 형식으로 표시

#### 3. **동적 컬럼 관리**

- 표시할 컬럼을 자유롭게 추가/제거
- 각 컬럼별 개별 라벨 표시
- 컬럼 순서에 따른 표시 순서 보장

#### 4. **반응형 카드 레이아웃**

- 한 행당 카드 수 조정으로 반응형 구현
- 카드 간격 픽셀 단위 조정
- 자동 높이 조정 및 최소 높이 보장

#### 5. **데이터 안전성**

- 빈 데이터에 대한 폴백 처리
- 잘못된 컬럼 참조 시 오류 방지
- 고유한 key prop으로 React 렌더링 최적화

### 🚨 주의사항

1. **성능 고려**: 대량 데이터 시 페이징 처리 (현재 최대 50개)
2. **이미지 처리**: 이미지 URL이 유효하지 않을 경우 대체 이미지 표시
3. **텍스트 길이**: 긴 텍스트는 자동으로 축약 처리
4. **데이터 타입**: 날짜/시간 데이터의 경우 적절한 포맷팅 필요

---

## 🔧 고급 설정

### 영역(Zone) 관리 시스템

#### 존과 컴포넌트의 관계

레이아웃의 존(Zone)에 컴포넌트를 배치하면 다음과 같은 관계가 형성됩니다:

```typescript
// 존에 배치된 컴포넌트의 구조
interface ComponentInZone {
  id: string;
  parentId: string; // 레이아웃 컴포넌트 ID
  zoneId: string; // 존 ID (새로 추가된 필드)
  position: { x: number; y: number }; // 존 내부 상대 좌표
  // ... 기타 속성들
}
```

#### 존에 컴포넌트 배치하기

1. **드래그앤드롭으로 배치**
   - 테이블이나 컬럼을 레이아웃의 존 영역에 드롭
   - 자동으로 `parentId`와 `zoneId`가 설정됨
   - 존 내부 상대 좌표로 위치 계산

2. **레이아웃 이동 시 함께 이동**
   - 레이아웃 컴포넌트를 이동하면 존에 속한 모든 컴포넌트가 함께 이동
   - 상대적 위치 관계 유지
   - 드래그 중에도 실시간으로 함께 이동

#### 존 드롭 이벤트 처리

각 존은 독립적인 드롭존으로 작동합니다:

```typescript
// 존별 드롭 처리 예시
const handleZoneDrop = (e: React.DragEvent, zoneId: string) => {
  const { type, table, column } = JSON.parse(e.dataTransfer.getData("application/json"));

  const newComponent = {
    id: generateId(),
    type: "widget",
    parentId: layoutId, // 레이아웃을 부모로 설정
    zoneId: zoneId, // 존 ID 설정
    position: {
      // 존 내부 상대 좌표
      x: e.clientX - dropZone.getBoundingClientRect().left,
      y: e.clientY - dropZone.getBoundingClientRect().top,
    },
    // ... 기타 설정
  };
};
```

### 영역(Zone) 커스터마이징

영역별로 다른 스타일을 적용하려면:

```typescript
// 영역별 스타일 계산
const getZoneStyle = (zone: LayoutZone, index: number): React.CSSProperties => {
  const baseStyle = {
    backgroundColor: "#f8f9fa",
    border: "1px solid #e9ecef",
    borderRadius: "4px",
    padding: "12px",
  };

  // 첫 번째 영역은 다른 스타일
  if (index === 0) {
    return {
      ...baseStyle,
      backgroundColor: "#e3f2fd",
      gridColumn: "1 / -1", // 전체 너비
    };
  }

  return baseStyle;
};
```

### 반응형 레이아웃

미디어 쿼리를 사용한 반응형 구현:

```typescript
const getResponsiveStyle = (): React.CSSProperties => {
  return {
    display: "grid",
    gridTemplateColumns: `repeat(auto-fit, minmax(300px, 1fr))`,
    gap: "16px",
    // CSS-in-JS에서는 미디어 쿼리를 직접 사용할 수 없으므로
    // CSS 클래스나 컨테이너 쿼리 사용 권장
  };
};
```

### 애니메이션 추가

CSS 애니메이션을 포함한 레이아웃:

```typescript
const animatedStyle: React.CSSProperties = {
  transition: "all 0.3s ease-in-out",
  opacity: isDesignMode ? 0.9 : 1,
  transform: isDesignMode ? "scale(0.98)" : "scale(1)",
};
```

### 높이 설정 및 styled-jsx 사용

모든 레이아웃에서 부모 높이를 올바르게 따르도록 하는 패턴:

```typescript
export const YourLayoutLayout: React.FC<YourLayoutProps> = ({ layout, isDesignMode, ...props }) => {
  return (
    <div className="layout-container">
      {/* 레이아웃 컨텐츠 */}

      <style jsx>{`
        .layout-container {
          height: 100% !important;
          min-height: 200px !important;
          width: 100% !important;
          display: flex; /* 또는 grid */
          flex-direction: column; /* 필요에 따라 */
        }

        .zone-area {
          flex: 1; /* 존이 사용 가능한 공간을 채우도록 */
          height: 100%; /* 그리드 레이아웃의 경우 */
        }
      `}</style>
    </div>
  );
};
```

#### 레이아웃별 높이 적용 패턴

**1. Flexbox 레이아웃**

```typescript
// FlexboxLayout.tsx
<style jsx>{`
  .flexbox-container {
    height: 100% !important;
    min-height: 200px !important;
    width: 100% !important;
    display: flex !important;
    flex-direction: ${flexDirection === "row" ? "row" : "column"} !important;
  }

  .flexbox-zone {
    flex: 1;
    min-height: 0; /* flexbox 오버플로우 방지 */
  }
`}</style>
```

**2. Grid 레이아웃**

```typescript
// GridLayout.tsx
<style jsx>{`
  .grid-container {
    height: 100% !important;
    min-height: 200px !important;
    width: 100% !important;
    display: grid !important;
    grid-template-columns: repeat(${columns}, 1fr);
    grid-template-rows: repeat(${rows}, 1fr);
  }

  .grid-zone {
    height: 100%;
    width: 100%;
  }
`}</style>
```

**3. Card 레이아웃**

```typescript
// CardLayoutLayout.tsx
<style jsx>{`
  .card-container {
    height: 100% !important;
    min-height: 200px !important;
    width: 100% !important;
    display: grid;
    grid-template-columns: repeat(${cardsPerRow}, 1fr);
    gap: ${cardSpacing}px;
  }
`}</style>
```

#### 중요한 CSS 규칙

1. **`!important` 사용**: Tailwind나 다른 CSS 프레임워크의 스타일을 오버라이드
2. **`height: 100%`**: 부모의 높이를 완전히 따르도록 설정
3. **`min-height`**: 최소 높이 보장으로 너무 작아지지 않도록 방지
4. **`flex: 1`**: 플렉스 아이템이 사용 가능한 공간을 채우도록 설정

---

## 🔄 자동 등록 시스템

### Hot Reload 지원

새 레이아웃은 다음과 같이 자동으로 등록됩니다:

1. **파일 저장 시**: Hot Reload로 즉시 반영
2. **자동 등록**: `AutoRegisteringLayoutRenderer` 상속으로 자동 등록
3. **즉시 사용**: 화면편집기에서 바로 사용 가능

### 수동 등록 (필요한 경우)

`lib/registry/layouts/index.ts`에 직접 추가:

```typescript
// 새 구조 레이아웃들 (자동 등록)
import "./your-layout/YourLayoutRenderer";
```

---

## 🛠️ 문제 해결

### 자주 발생하는 오류

#### 1. "Cannot read properties of undefined" 오류

```typescript
// ❌ 문제: 설정이 없을 때 오류
const config = layout.layoutConfig.yourLayout.someProperty;

// ✅ 해결: 안전한 접근
const config = layout.layoutConfig.yourLayout?.someProperty || defaultValue;
```

#### 2. "React does not recognize prop" 경고

```typescript
// ❌ 문제: 모든 props를 DOM에 전달
<div {...props}>

// ✅ 해결: DOM props만 전달
const { layout, isDesignMode, renderer, ...domProps } = props;
<div {...domProps}>
```

#### 3. 레이아웃이 화면편집기에 나타나지 않음

1. **파일 저장 확인**: 모든 파일이 저장되었는지 확인
2. **자동 등록 확인**: `YourLayoutRenderer.registerSelf()` 호출 여부
3. **브라우저 새로고침**: 캐시 문제일 수 있음
4. **개발자 도구**: `window.__LAYOUT_REGISTRY__.list()` 로 등록 상태 확인

#### 4. 레이아웃 높이가 적용되지 않음

```typescript
// ❌ 문제: 인라인 스타일만 사용
<div style={{ height: "100%" }}>

// ✅ 해결: styled-jsx로 강제 적용
<div className="layout-container">
  <style jsx>{`
    .layout-container {
      height: 100% !important;
      min-height: 200px !important;
    }
  `}</style>
</div>
```

#### 5. Flexbox 방향 설정이 적용되지 않음

```typescript
// ❌ 문제: display: block이 flex를 오버라이드
<div style={{ display: "flex", flexDirection: "row" }}>

// ✅ 해결: !important로 강제 적용
<style jsx>{`
  .flexbox-container {
    display: flex !important;
    flex-direction: ${direction === "row" ? "row" : "column"} !important;
  }
`}</style>
```

#### 6. 카드 레이아웃에서 데이터가 표시되지 않음

1. **테이블 선택 확인**: 화면에서 테이블이 선택되었는지 확인
2. **컬럼 매핑 설정**: 상세설정에서 최소한 타이틀 컬럼은 설정
3. **체크박스 상태**: "타이틀 표시", "서브타이틀 표시" 등이 체크되었는지 확인
4. **API 호출 확인**: 브라우저 개발자 도구에서 API 호출 성공 여부 확인

#### 7. React Key Prop 경고

```typescript
// ❌ 문제: 고유하지 않은 key
{items.map((item, index) => (
  <div key={item.id}> // item.id가 undefined일 수 있음

// ✅ 해결: 안전한 key 생성
{items.map((item, index) => (
  <div key={item.objid || item.id || item.company_code || `item-${index}`}>
```

#### 8. 라벨이 컬럼명으로 표시되는 문제

```typescript
// ❌ 문제: 컬럼명 직접 사용
<span>{columnName}:</span>

// ✅ 해결: 라벨 우선 표시
const getColumnLabel = (columnName: string) => {
  const column = tableColumns.find(col => col.columnName === columnName);
  return column?.columnLabel || columnName;
};

<span>{getColumnLabel(columnName)}:</span>
```

#### 9. 레이아웃 드롭 시 오류 발생 문제 (9월 11일 해결됨)

```typescript
// ❌ 문제: 복잡한 존별 드롭 로직으로 인한 오류
- Runtime TypeError: Cannot read properties of undefined (reading 'width')
- 다중선택 기능 중단
- 존별 드롭 이벤트 충돌

// ✅ 해결: 드롭 시스템 완전 단순화
- 모든 존별 드롭 로직 제거
- 일반 캔버스 드롭만 사용
- 레이아웃은 시각적 가이드 역할만
- z-index 기반 레이어 분리 (레이아웃=1, 컴포넌트=2+)
```

##### 드롭 시스템 단순화 후 장점

- ✅ **안정성**: 복잡한 이벤트 체인 제거로 오류 가능성 감소
- ✅ **일관성**: 모든 영역에서 동일한 드롭 동작
- ✅ **성능**: 불필요한 prop 전달 및 매핑 로직 제거
- ✅ **유지보수**: 단순한 구조로 디버깅 및 수정 용이

##### 새로운 레이아웃 개발 시 주의사항

```typescript
// ✅ 올바른 레이아웃 구현
export const YourLayoutLayout: React.FC<YourLayoutProps> = ({ layout, isDesignMode, ...props }) => {
  // 🚫 존별 드롭 이벤트 구현 금지
  // onDrop, onDragOver 등 드롭 관련 이벤트 추가하지 않음

  return (
    <div className="your-layout">
      {layout.zones.map((zone) => (
        <div
          key={zone.id}
          className="zone-area"
          // 🚫 드롭 이벤트 추가 금지
          // onDrop={...} ❌
          // onDragOver={...} ❌
        >
          {/* 존 내용 */}
        </div>
      ))}

      <style jsx>{`
        .your-layout {
          /* z-index는 1로 고정 (레이아웃 레이어) */
          z-index: 1;
          height: 100% !important;
        }
      `}</style>
    </div>
  );
};
```

### 디버깅 도구

#### 브라우저 개발자 도구

```javascript
// 등록된 레이아웃 목록 확인
window.__LAYOUT_REGISTRY__.list();

// 특정 레이아웃 정보 확인
window.__LAYOUT_REGISTRY__.get("your-layout");

// 레지스트리 통계
window.__LAYOUT_REGISTRY__.stats();
```

---

## 📖 예시: 완전한 레이아웃 생성

### 1. CLI로 생성

```bash
node scripts/create-layout.js pricing-table --category=content --zones=4 --description="가격표 레이아웃" --author="개발팀"
```

### 2. 생성 결과

```
✅ 레이아웃 생성 완료!
📁 이름: pricingTable
🔖 ID: pricing-table
📂 카테고리: content
🎯 존 개수: 4
```

### 3. 커스터마이징

```typescript
// PricingTableLayout.tsx
export const PricingTableLayout: React.FC<PricingTableLayoutProps> = ({
  layout,
  isDesignMode,
  renderer,
}) => {
  const pricingTableStyle: React.CSSProperties = {
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(250px, 1fr))",
    gap: "24px",
    padding: "32px",
    backgroundColor: "#f8f9fa",
  };

  return (
    <div style={pricingTableStyle}>
      {layout.zones.map((zone, index) => (
        <div
          key={zone.id}
          className={`pricing-card ${index === 1 ? 'featured' : ''}`}
          style={{
            backgroundColor: "white",
            borderRadius: "12px",
            padding: "24px",
            boxShadow: index === 1 ? "0 8px 32px rgba(0,0,0,0.1)" : "0 2px 8px rgba(0,0,0,0.1)",
            border: index === 1 ? "2px solid #3b82f6" : "1px solid #e5e7eb",
            transform: index === 1 ? "scale(1.05)" : "scale(1)",
          }}
        >
          {renderer.renderZone(zone, renderer.getZoneChildren(zone.id))}
        </div>
      ))}
    </div>
  );
};
```

### 4. 즉시 사용 가능

레이아웃이 자동으로 등록되어 화면편집기에서 바로 사용할 수 있습니다!

---

## 🎯 존 관리 시스템의 장점

### 1. 구조적 레이아웃 관리

- **논리적 그룹화**: 관련된 컴포넌트들을 존별로 그룹화
- **일관된 이동**: 레이아웃 이동 시 모든 하위 컴포넌트가 함께 이동
- **상대적 위치**: 존 내부에서의 상대적 위치 관계 유지

### 2. 직관적인 사용자 경험

- **드래그앤드롭**: 존 영역에 직접 드롭하여 배치
- **시각적 피드백**: 존 경계와 라벨로 명확한 구분
- **실시간 미리보기**: 드래그 중에도 함께 이동하는 모습 확인

### 3. 개발자 친화적

- **자동 관계 설정**: `parentId`와 `zoneId` 자동 할당
- **타입 안전성**: TypeScript로 완전한 타입 지원
- **확장 가능성**: 새로운 존 타입 쉽게 추가 가능

## 🔍 사용 예시

### 대시보드 레이아웃 예시

```bash
# 대시보드 레이아웃 생성
node scripts/create-layout.js dashboard-layout --category=dashboard --zones=4 --description="대시보드 레이아웃"
```

생성된 레이아웃에서:

1. **헤더 존**: 제목, 네비게이션 컴포넌트 배치
2. **사이드바 존**: 메뉴, 필터 컴포넌트 배치
3. **메인 존**: 차트, 테이블 컴포넌트 배치
4. **푸터 존**: 상태 정보, 액션 버튼 배치

### 폼 레이아웃 예시

```bash
# 폼 레이아웃 생성
node scripts/create-layout.js form-layout --category=form --zones=3 --description="폼 레이아웃"
```

생성된 레이아웃에서:

1. **입력 존**: 텍스트 필드, 선택박스 배치
2. **첨부 존**: 파일 업로드 컴포넌트 배치
3. **액션 존**: 저장, 취소 버튼 배치

## 🎯 마무리

새로운 CLI 방식과 존 관리 시스템, 그리고 데이터 기반 레이아웃으로 화면관리 시스템이 혁신적으로 개선되었습니다:

### 🚀 핵심 기능

1. **한 줄 명령어**로 모든 파일 자동 생성
2. **타입 안전성** 보장 (TypeScript 완전 지원)
3. **자동 등록**으로 즉시 사용 가능
4. **Hot Reload** 지원으로 빠른 개발
5. **존 관리 시스템**으로 구조적 레이아웃 관리
6. **데이터 기반 렌더링** (카드 레이아웃)
7. **동적 존 개수 설정** (Flexbox, Grid)
8. **높이 자동 적용** (styled-jsx + !important)

### 🎨 사용자 경험

- **직관적 드래그앤드롭**: 존에 직접 컴포넌트 배치
- **일관된 이동**: 레이아웃과 하위 컴포넌트가 함께 이동
- **시각적 피드백**: 명확한 존 경계와 라벨 표시
- **실시간 설정**: 체크박스로 즉시 표시 제어
- **라벨 우선 표시**: 컬럼명 대신 사용자 친화적 라벨

### 🔧 개발자 경험

- **자동화된 설정**: 복잡한 관계 설정이 자동으로 처리
- **확장 가능한 구조**: 새로운 레이아웃 타입 쉽게 추가
- **완전한 타입 지원**: TypeScript로 안전한 개발
- **문제 해결 가이드**: 자주 발생하는 문제들의 해결책 제공
- **성능 최적화**: React key, 메모이제이션 등 적용

### 🆕 최신 업데이트 (2025.09.11)

#### 카드 레이아웃 고도화

- ✅ **실제 데이터 연동**: 테이블 데이터를 실시간으로 카드에 표시
- ✅ **컬럼 매핑 시스템**: 타이틀, 서브타이틀, 설명 등 자유로운 매핑
- ✅ **동적 표시 컬럼**: 필요한 컬럼을 추가/제거하며 동적 관리
- ✅ **라벨 우선 표시**: 데이터베이스 컬럼명 대신 사용자 친화적 라벨
- ✅ **실시간 설정 반영**: 체크박스 토글로 즉시 카드 업데이트

#### 레이아웃 시스템 개선

- ✅ **높이 적용 문제 해결**: 모든 레이아웃에서 부모 높이 완벽 적용
- ✅ **Flexbox 방향 설정**: 수평/수직 방향 정상 작동
- ✅ **동적 존 개수**: Grid, Flexbox에서 존 개수 실시간 조정
- ✅ **시각적 피드백**: 모든 레이아웃에서 존 경계 명확히 표시
- ✅ **React 경고 해결**: Key prop, DOM prop 전달 등 모든 경고 해결

#### 🔧 드롭 시스템 대폭 단순화 (9월 11일 추가)

기존의 복잡한 존별 드롭 시스템을 완전히 제거하고 단순한 캔버스 드롭 방식으로 통일했습니다:

##### 변경 사항

- ✅ **복잡한 드롭 로직 제거**: `onZoneComponentDrop`, `handleZoneComponentDrop` 등 모든 존별 드롭 이벤트 제거
- ✅ **일반 캔버스 드롭만 사용**: 모든 드롭이 `handleComponentDrop`으로 통일
- ✅ **레이아웃은 시각적 가이드 역할**: 레이아웃 존은 배치 가이드라인 역할만 수행
- ✅ **z-index 기반 레이어링**: 레이아웃 z-index=1, 컴포넌트 z-index=2+로 설정
- ✅ **prop 전달 체인 단순화**: 불필요한 prop 매핑 및 전달 로직 제거

##### 새로운 동작 방식

**이전 (복잡한 방식)**:

```
컴포넌트 드래그 → 레이아웃 존 감지 → 존별 드롭 이벤트 → 복잡한 매핑 → 오류 발생
```

**현재 (단순한 방식)**:

```
컴포넌트 드래그 → 캔버스에 드롭 → 일반 handleComponentDrop만 실행 → 안정적 동작
```

##### 해결된 문제들

- ✅ **Runtime TypeError 해결**: `selectedComponent.size.width` undefined 오류 완전 해결
- ✅ **다중선택 복구**: 드래그로 다중선택 기능 정상화
- ✅ **안정적 드롭**: 레이아웃 위든 어디든 일관된 드롭 동작
- ✅ **코드 단순화**: 복잡한 존별 로직 제거로 유지보수성 향상

##### 기술적 변경점

1. **GridLayout, FlexboxLayout**: `onDragOver`, `onDrop` 이벤트 핸들러 제거
2. **ScreenDesigner**: `onZoneComponentDrop` prop 전달 제거
3. **DynamicComponentRenderer**: `onComponentDrop` 매핑 로직 제거
4. **DynamicLayoutRenderer**: 존별 prop 전달 제거
5. **RealtimePreviewDynamic**: z-index 기반 레이어링 적용

##### 개발자 가이드

새로운 시스템에서는:

- 🚫 **존별 드롭 로직 구현 금지**: 모든 드롭은 캔버스 레벨에서 처리
- ✅ **시각적 가이드만 제공**: 레이아웃은 배치 가이드라인 역할만
- ✅ **z-index로 레이어 관리**: 레이아웃=1, 컴포넌트=2+ 설정
- ✅ **단순한 이벤트 처리**: 복잡한 이벤트 체인 대신 직접적인 핸들링

#### 개발자 도구 강화

- ✅ **디버깅 로그**: 카드 설정 로드, 데이터 가져오기 등 상세 로깅
- ✅ **에러 핸들링**: API 함수명 오류, 데이터 타입 불일치 등 완벽 처리
- ✅ **타입 안전성**: 모든 컴포넌트와 설정에 완전한 TypeScript 지원

### 📈 지원하는 레이아웃 현황

1. **Grid Layout** - 격자 형태 기본 레이아웃
2. **Flexbox Layout** - 유연한 방향 설정 가능
3. **Split Layout** - 좌우/상하 분할
4. **Accordion Layout** - 접기/펼치기 네비게이션
5. **Card Layout** - 데이터 기반 카드 표시 ⭐
6. **Hero Section Layout** - 대형 헤더 섹션

### 🔮 향후 계획

#### 새로운 레이아웃 타입

- **Table Layout**: 데이터 테이블 전용 레이아웃
- **Form Layout**: 폼 입력에 최적화된 레이아웃
- **Dashboard Layout**: 위젯 배치에 특화된 레이아웃
- **Mobile Responsive**: 모바일 대응 반응형 레이아웃

#### 시스템 개선

- **레이아웃 테마 시스템**: 다크/라이트 모드 지원
- **레이아웃 스타일 프리셋**: 미리 정의된 스타일 템플릿
- **레이아웃 애니메이션**: 전환 효과 및 인터랙션 개선
- **성능 최적화**: 가상화 및 지연 로딩 적용

#### 개발자 도구

- **레이아웃 빌더 GUI**: 코드 없이 레이아웃 생성 도구
- **실시간 프리뷰**: 레이아웃 편집 중 실시간 미리보기
- **레이아웃 디버거**: 시각적 디버깅 도구
- **성능 모니터링**: 레이아웃 렌더링 성능 분석

### 🎯 중요한 변화: 단순화된 드롭 시스템

**2025년 9월 11일**부터 모든 레이아웃에서 **복잡한 존별 드롭 로직이 완전히 제거**되었습니다.

새로운 시스템의 핵심 원칙:

- 🎯 **레이아웃 = 시각적 가이드**: 배치 참고용으로만 사용
- 🎯 **캔버스 = 실제 배치**: 모든 컴포넌트는 캔버스에 자유롭게 배치
- 🎯 **z-index = 레이어 분리**: 레이아웃(1) 위에 컴포넌트(2+) 배치
- 🎯 **단순함 = 안정성**: 복잡한 로직 제거로 오류 최소화

이 변화로 인해:

- ✅ 모든 드롭 관련 오류 해결
- ✅ 다중선택 기능 정상화
- ✅ 레이아웃 개발이 더욱 단순해짐
- ✅ 시스템 전체 안정성 크게 향상

더 자세한 정보가 필요하면 각 레이아웃의 `README.md` 파일을 참고하거나, 브라우저 개발자 도구에서 `window.__LAYOUT_REGISTRY__.help()`를 실행해보세요! 🚀
