# 기본 목록_데스크톱/태블릿/모바일 통합 템플릿

## 📋 개요

**ResponsiveListTemplate**은 MES SAM 시스템의 표준 목록 페이지 템플릿입니다. 데스크톱, 태블릿, 모바일 모든 화면에서 완벽하게 작동하며, 아토믹 디자인 시스템의 모든 계층 (Atoms → Molecules → Organisms → Templates)을 통합적으로 지원합니다.

## ✨ 주요 특징

### 1. **완전한 반응형**
- **데스크톱 (lg 이상)**: DataTable + 기본 탭
- **태블릿 (md-lg)**: DataTable 축소 + 기본 탭
- **모바일 (sm 이하)**: 커스텀 카드 + 버튼 형태 탭

### 2. **아토믹 디자인 시스템 완벽 지원**
```
📦 ResponsiveListTemplate (Templates)
├── PageLayout (Organisms)
│   └── maxWidth 설정
├── PageHeader (Organisms)
│   ├── title
│   ├── description
│   ├── icon
│   └── headerActions (Buttons)
├── StatCards (Organisms)
│   └── StatCardProps[] (통계 카드)
├── SearchFilter (Molecules)
│   ├── Input (Atoms)
│   └── extraFilters
├── Card (Atoms)
│   ├── CardHeader (Molecules)
│   └── CardContent (Molecules)
│       ├── Tabs (Molecules)
│       │   ├── TabsList (Desktop/Tablet)
│       │   ├── 커스텀 버튼 탭 (Mobile)
│       │   └── TabsContent
│       │       ├── DataTable (Organisms - Desktop/Tablet)
│       │       └── 모바일 카드 리스트 (Mobile)
```

### 3. **탭 기반 필터링**
- 6가지 색상 테마 (blue, purple, orange, cyan, green, gray)
- 탭별 카운트 표시
- 데스크톱: 기본 shadcn/ui Tabs 컴포넌트
- 모바일: 커스텀 버튼 형태 (색상 강조, 터치 친화적)

### 4. **통계 카드**
- 최대 4개의 통계 지표
- 아이콘, 트렌드, 변화율 표시
- 반응형 그리드 (1-2-4 컬럼)

### 5. **검색 및 필터**
- 실시간 검색
- 커스텀 필터 추가 가능 (extraFilters)
- 검색 플레이스홀더 커스터마이징

### 6. **모바일 카드 렌더러**
- `createMobileCardRenderer` 헬퍼 함수
- 번호, 제목, 부제목, 뱃지, 필드, 액션 버튼
- 완전 커스터마이징 가능

## 📦 설치 및 임포트

```tsx
import { 
  ResponsiveListTemplate, 
  TabConfig, 
  createMobileCardRenderer 
} from "./components/templates/ResponsiveListTemplate";
import { Column } from "./components/organisms/DataTable";
import { StatCardProps } from "./components/organisms/StatCards";
```

## 🎯 기본 사용법

### 1. 데이터 타입 정의

```tsx
interface Item {
  id: string;
  itemCode: string;
  itemName: string;
  itemType: "FG" | "PT" | "RM";
  unit: string;
  status: "active" | "inactive";
}
```

### 2. 통계 카드 설정

```tsx
const stats: StatCardProps[] = [
  {
    label: "전체 품목",
    value: "150",
    icon: Package,
    trend: { value: 12, isPositive: true },
  },
  {
    label: "제품",
    value: "50",
    icon: Box,
  },
];
```

### 3. 탭 구성

```tsx
const tabs: TabConfig[] = [
  { value: "all", label: "전체", count: 150, color: "blue" },
  { value: "active", label: "활성", count: 120, color: "green" },
  { value: "inactive", label: "비활성", count: 30, color: "gray" },
];
```

### 4. 데스크톱 테이블 컬럼

```tsx
const columns: Column<Item>[] = [
  {
    header: "No",
    accessor: "id",
    width: "60px",
    render: (value, row, index) => (
      <Badge variant="outline">{index + 1}</Badge>
    ),
  },
  {
    header: "품목코드",
    accessor: "itemCode",
    width: "150px",
  },
  {
    header: "품목명",
    accessor: "itemName",
  },
  {
    header: "품목유형",
    accessor: "itemType",
    render: (value) => {
      const typeMap = { FG: "제품", PT: "부품", RM: "원자재" };
      return <Badge>{typeMap[value]}</Badge>;
    },
  },
];
```

### 5. 모바일 카드 렌더러

```tsx
const renderMobileCard = createMobileCardRenderer<Item>({
  getTitle: (item) => item.itemName,
  getSubtitle: (item) => item.itemCode,
  getBadge: (item) => ({
    label: item.itemType === 'FG' ? '제품' : '부품',
    variant: 'default'
  }),
  getFields: (item) => [
    { label: "단위", value: item.unit, badge: true },
    { label: "상태", value: item.status === "active" ? "활성" : "비활성" },
  ],
  getActions: (item) => (
    <div className="flex gap-2">
      <Button size="sm">상세</Button>
      <Button size="sm">수정</Button>
    </div>
  ),
  getNumber: (item, index, total) => total - index, // 역순 번호
});
```

### 6. 템플릿 렌더링

```tsx
export function MyListPage() {
  const [currentTab, setCurrentTab] = useState("all");
  const [searchValue, setSearchValue] = useState("");

  return (
    <ResponsiveListTemplate
      title="품목관리"
      description="품목 목록을 관리합니다"
      icon={Package}
      headerActions={
        <Button>
          <Plus className="w-4 h-4 mr-2" />
          품목 등록
        </Button>
      }
      stats={stats}
      searchValue={searchValue}
      onSearchChange={setSearchValue}
      searchPlaceholder="품목코드, 품목명으로 검색..."
      tabs={tabs}
      currentTab={currentTab}
      onTabChange={setCurrentTab}
      data={filteredData}
      keyField="id"
      columns={columns}
      onRowClick={(row) => console.log("클릭:", row)}
      renderMobileCard={renderMobileCard}
      emptyMessage="검색 결과가 없습니다"
      maxWidth="full"
    />
  );
}
```

## 🎨 Props API

### ResponsiveListTemplateProps<T>

| Prop | 타입 | 필수 | 기본값 | 설명 |
|------|------|------|--------|------|
| `title` | `string` | ✅ | - | 페이지 제목 |
| `description` | `string` | ❌ | - | 페이지 설명 |
| `icon` | `LucideIcon` | ❌ | - | 페이지 아이콘 |
| `headerActions` | `ReactNode` | ❌ | - | 헤더 액션 버튼 |
| `stats` | `StatCardProps[]` | ❌ | - | 통계 카드 배열 |
| `searchValue` | `string` | ❌ | - | 검색어 |
| `onSearchChange` | `(value: string) => void` | ❌ | - | 검색어 변경 핸들러 |
| `searchPlaceholder` | `string` | ❌ | "검색..." | 검색 플레이스홀더 |
| `extraFilters` | `ReactNode` | ❌ | - | 추가 필터 UI |
| `tabs` | `TabConfig[]` | ✅ | - | 탭 구성 |
| `currentTab` | `string` | ✅ | - | 현재 선택된 탭 |
| `onTabChange` | `(value: string) => void` | ✅ | - | 탭 변경 핸들러 |
| `data` | `T[]` | ✅ | - | 데이터 배열 |
| `keyField` | `keyof T` | ✅ | - | 키 필드명 |
| `columns` | `Column<T>[]` | ✅ | - | 테이블 컬럼 정의 |
| `onRowClick` | `(row: T) => void` | ❌ | - | 행 클릭 핸들러 |
| `renderMobileCard` | `(item: T, index: number) => ReactNode` | ❌ | - | 모바일 카드 렌더러 |
| `selectable` | `boolean` | ❌ | `false` | 선택 기능 활성화 |
| `selectedIds` | `Set<string>` | ❌ | `new Set()` | 선택된 ID 목록 |
| `onToggleSelection` | `(id: string) => void` | ❌ | - | 선택 토글 핸들러 |
| `cardTitle` | `string \| (currentTab: string, count: number) => string` | ❌ | - | 카드 제목 |
| `emptyMessage` | `string` | ❌ | "데이터가 없습니다" | 빈 데이터 메시지 |
| `maxWidth` | `"sm" \| "md" \| "lg" \| "xl" \| "full"` | ❌ | `"full"` | 최대 너비 |

### TabConfig

| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `value` | `string` | ✅ | 탭 값 |
| `label` | `string` | ✅ | 탭 라벨 |
| `count` | `number` | ❌ | 항목 수 |
| `color` | `"blue" \| "purple" \| "orange" \| "cyan" \| "green" \| "gray"` | ❌ | 색상 테마 |

### createMobileCardRenderer Config

| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `getTitle` | `(item: T) => string` | ✅ | 카드 제목 |
| `getSubtitle` | `(item: T) => string` | ❌ | 카드 부제목 |
| `getBadge` | `(item: T) => { label: string; variant?: ... }` | ❌ | 뱃지 정보 |
| `getFields` | `(item: T) => MobileCardField[]` | ✅ | 필드 목록 |
| `getActions` | `(item: T) => ReactNode` | ❌ | 액션 버튼 |
| `selectable` | `boolean` | ❌ | 선택 가능 여부 |
| `selectedIds` | `Set<string>` | ❌ | 선택된 ID |
| `onToggleSelection` | `(id: string) => void` | ❌ | 선택 토글 |
| `getNumber` | `(item: T, index: number, total: number) => string \| number` | ❌ | 번호 표시 |

## 🎯 실제 사용 예제

### 품목관리 페이지

위치: `/components/templates/BasicListUnifiedExample.tsx`

### 견적관리 페이지

위치: `/components/QuoteManagement.tsx` (490줄로 단순화)

## 📱 반응형 브레이크포인트

| 화면 크기 | 브레이크포인트 | 탭 UI | 목록 UI |
|-----------|----------------|-------|---------|
| 모바일 | < 1024px (lg) | 커스텀 버튼 | 카드 리스트 |
| 태블릿 | ≥ 1024px (lg) | 기본 탭 | DataTable |
| 데스크톱 | ≥ 1024px (lg) | 기본 탭 | DataTable |

## 🔧 커스터마이징

### 1. 탭 색상 변경

```tsx
const tabs: TabConfig[] = [
  { value: "all", label: "전체", color: "blue" },    // 파란색
  { value: "new", label: "신규", color: "purple" },  // 보라색
  { value: "draft", label: "작성중", color: "orange" }, // 주황색
];
```

### 2. 통계 카드 트렌드 추가

```tsx
const stats: StatCardProps[] = [
  {
    label: "이번 달 매출",
    value: "₩1,250,000",
    icon: DollarSign,
    trend: { value: 15.3, isPositive: true }, // +15.3%
  },
];
```

### 3. 추가 필터 UI

```tsx
<ResponsiveListTemplate
  {...props}
  extraFilters={
    <>
      <Select>
        <SelectTrigger>
          <SelectValue placeholder="품목유형" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="FG">제품</SelectItem>
          <SelectItem value="PT">부품</SelectItem>
        </SelectContent>
      </Select>
      <Select>
        <SelectTrigger>
          <SelectValue placeholder="상태" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="active">활성</SelectItem>
          <SelectItem value="inactive">비활성</SelectItem>
        </SelectContent>
      </Select>
    </>
  }
/>
```

## ✅ 체크리스트

템플릿 사용 전 확인사항:

- [ ] 데이터 타입에 `id: string` 필드 포함
- [ ] 탭 구성 완료 (최소 1개)
- [ ] 데스크톱 컬럼 정의 완료
- [ ] 모바일 카드 렌더러 정의 완료
- [ ] 검색/필터 로직 구현
- [ ] 상태 관리 (currentTab, searchValue)

## 🎓 학습 자료

### 예제 페이지

- **기본 목록 통합 예제**: `기준정보 → 디자인시스템관리 → 기본 목록_데스크톱/태블릿/모바일 통합`
- **품목관리 예제**: `생산관리 → 품목관리`
- **견적관리 예제**: `판매관리 → 견적관리`

### 관련 컴포넌트

- PageLayout: `/components/organisms/PageLayout.tsx`
- PageHeader: `/components/organisms/PageHeader.tsx`
- StatCards: `/components/organisms/StatCards.tsx`
- SearchFilter: `/components/organisms/SearchFilter.tsx`
- DataTable: `/components/organisms/DataTable.tsx`

## 📞 지원

문제가 발생하거나 질문이 있으시면:
- 디자인시스템관리 페이지에서 템플릿 문서 확인
- 예제 코드 참조
- 개발팀에 문의

---

**버전**: 1.0.0  
**최종 업데이트**: 2025-01-20  
**작성자**: MES SAM 개발팀
