# 관리자 페이지 스타일 가이드 적용 예시

## 개요

사용자 관리 페이지를 예시로 shadcn/ui 스타일 가이드에 맞춰 재작성했습니다.
이 예시를 기준으로 다른 관리자 페이지들도 일관된 스타일로 통일할 수 있습니다.

## 적용된 주요 원칙

### 1. Color System (색상 시스템)

**CSS Variables 사용 (하드코딩된 색상 금지)**
```tsx
// ❌ 잘못된 예시
<div className="bg-gray-50 text-gray-900">

// ✅ 올바른 예시
<div className="bg-background text-foreground">
<div className="bg-card text-card-foreground">
<div className="bg-muted text-muted-foreground">
<div className="text-primary">
<div className="text-destructive">
```

**적용 사례:**
- 페이지 배경: `bg-background`
- 카드 배경: `bg-card`
- 보조 텍스트: `text-muted-foreground`
- 주요 액션: `text-primary`, `border-primary`
- 에러 메시지: `text-destructive`, `bg-destructive/10`

### 2. Typography (타이포그래피)

**일관된 폰트 크기와 가중치**
```tsx
// 페이지 제목
<h1 className="text-3xl font-bold tracking-tight">사용자 관리</h1>

// 섹션 제목
<h4 className="text-sm font-semibold">고급 검색 옵션</h4>

// 본문 텍스트
<p className="text-sm text-muted-foreground">설명 텍스트</p>

// 라벨
<label className="text-sm font-medium">필드 라벨</label>

// 보조 텍스트
<p className="text-xs text-muted-foreground">도움말</p>
```

### 3. Spacing System (간격)

**일관된 간격 사용 (4px 기준)**
```tsx
// 컴포넌트 간 간격
<div className="space-y-6">          // 24px (페이지 레벨)
<div className="space-y-4">          // 16px (섹션 레벨)
<div className="space-y-2">          // 8px (필드 레벨)

// 패딩
<div className="p-6">                // 24px (카드)
<div className="p-4">                // 16px (내부 섹션)

// 갭
<div className="gap-4">              // 16px (flex/grid)
<div className="gap-2">              // 8px (버튼 그룹)
```

### 4. Border & Radius (테두리 및 둥근 모서리)

**표준 radius 사용**
```tsx
// 카드/패널
<div className="rounded-lg border bg-card">

// 입력 필드
<Input className="rounded-md">

// 버튼
<Button className="rounded-md">
```

### 5. Button Variants (버튼 스타일)

**표준 variants 사용**
```tsx
// Primary 액션
<Button variant="default" size="default" className="h-10 gap-2 text-sm font-medium">
  <Plus className="h-4 w-4" />
  사용자 등록
</Button>

// Secondary 액션
<Button variant="outline" size="default" className="h-10 gap-2 text-sm font-medium">
  고급 검색
</Button>

// Ghost 버튼 (아이콘 전용)
<Button variant="ghost" size="icon" className="h-8 w-8">
  <Key className="h-4 w-4" />
</Button>
```

**크기 표준:**
- `h-10`: 기본 버튼 (40px)
- `h-9`: 작은 버튼 (36px)
- `h-8`: 아이콘 버튼 (32px)

### 6. Input States (입력 필드 상태)

**표준 Input 스타일**
```tsx
// 기본
<Input className="h-10 text-sm" />

// 포커스 (자동 적용)
// focus:ring-2 focus:ring-ring

// 로딩/액티브
<Input className="h-10 text-sm border-primary ring-2 ring-primary/20" />

// 비활성화
<Input disabled className="cursor-not-allowed bg-muted text-muted-foreground" />
```

### 7. Form Structure (폼 구조)

**표준 필드 구조**
```tsx
<div className="space-y-2">
  <label htmlFor="field-id" className="text-sm font-medium">
    필드 라벨
  </label>
  <Input
    id="field-id"
    placeholder="힌트 텍스트"
    className="h-10 text-sm"
  />
  <p className="text-xs text-muted-foreground">
    도움말 텍스트
  </p>
</div>
```

### 8. Table Structure (테이블 구조)

**표준 테이블 스타일**
```tsx
<div className="rounded-lg border bg-card shadow-sm">
  <Table>
    <TableHeader>
      <TableRow className="border-b bg-muted/50 hover:bg-muted/50">
        <TableHead className="h-12 text-sm font-semibold">
          컬럼명
        </TableHead>
      </TableRow>
    </TableHeader>
    <TableBody>
      <TableRow className="border-b transition-colors hover:bg-muted/50">
        <TableCell className="h-16 text-sm">
          데이터
        </TableCell>
      </TableRow>
    </TableBody>
  </Table>
</div>
```

**높이 표준:**
- 헤더: `h-12` (48px)
- 데이터 행: `h-16` (64px)

### 9. Loading States (로딩 상태)

**Skeleton UI**
```tsx
<div className="h-4 animate-pulse rounded bg-muted"></div>
```

### 10. Empty States (빈 상태)

**표준 Empty State**
```tsx
<TableCell colSpan={columns} className="h-32 text-center">
  <div className="flex flex-col items-center justify-center gap-2 text-muted-foreground">
    <p className="text-sm">등록된 데이터가 없습니다.</p>
  </div>
</TableCell>
```

### 11. Error States (에러 상태)

**표준 에러 메시지**
```tsx
<div className="rounded-lg border border-destructive/50 bg-destructive/10 p-4">
  <div className="flex items-center justify-between">
    <p className="text-sm font-semibold text-destructive">오류가 발생했습니다</p>
    <button
      onClick={clearError}
      className="text-destructive transition-colors hover:text-destructive/80"
      aria-label="에러 메시지 닫기"
    >
      ✕
    </button>
  </div>
  <p className="mt-1.5 text-sm text-destructive/80">{errorMessage}</p>
</div>
```

### 12. Responsive Design (반응형)

**모바일 우선 접근**
```tsx
// 레이아웃
<div className="flex flex-col gap-4 sm:flex-row sm:items-center">

// 그리드
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">

// 텍스트
<h1 className="text-2xl sm:text-3xl font-bold">

// 간격
<div className="p-4 sm:p-6">
```

### 13. Accessibility (접근성)

**필수 적용 사항**
```tsx
// Label과 Input 연결
<label htmlFor="user-id" className="text-sm font-medium">
  사용자 ID
</label>
<Input id="user-id" />

// 버튼에 aria-label
<Button aria-label="에러 메시지 닫기">
  ✕
</Button>

// Switch에 aria-label
<Switch
  checked={isActive}
  onCheckedChange={handleChange}
  aria-label="사용자 상태 토글"
/>
```

## 페이지 구조 템플릿

### Page Component
```tsx
export default function AdminPage() {
  return (
    <div className="flex min-h-screen flex-col bg-background">
      <div className="container mx-auto space-y-6 p-6">
        {/* 페이지 헤더 */}
        <div className="space-y-2 border-b pb-4">
          <h1 className="text-3xl font-bold tracking-tight">페이지 제목</h1>
          <p className="text-sm text-muted-foreground">페이지 설명</p>
        </div>

        {/* 메인 컨텐츠 */}
        <MainComponent />
      </div>
    </div>
  );
}
```

### Toolbar Component
```tsx
export function Toolbar() {
  return (
    <div className="space-y-4">
      {/* 검색 영역 */}
      <div className="rounded-lg border bg-card p-4">
        <div className="mb-4 flex flex-col gap-4 sm:flex-row sm:items-center">
          {/* 검색 입력 */}
          <div className="flex-1">
            <div className="relative">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input placeholder="검색..." className="h-10 pl-10 text-sm" />
            </div>
          </div>
          
          {/* 버튼 */}
          <Button variant="outline" className="h-10 gap-2 text-sm font-medium">
            고급 검색
          </Button>
        </div>
      </div>

      {/* 액션 버튼 영역 */}
      <div className="flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center">
        <div className="text-sm text-muted-foreground">
          총 <span className="font-semibold text-foreground">{count.toLocaleString()}</span> 건
        </div>
        
        <Button className="h-10 gap-2 text-sm font-medium">
          <Plus className="h-4 w-4" />
          등록
        </Button>
      </div>
    </div>
  );
}
```

## 적용해야 할 다른 관리자 페이지

### 우선순위 1 (핵심 페이지)
- [ ] 메뉴 관리 (`/admin/menu`)
- [ ] 공통코드 관리 (`/admin/commonCode`)
- [ ] 회사 관리 (`/admin/company`)
- [ ] 테이블 관리 (`/admin/tableMng`)

### 우선순위 2 (자주 사용하는 페이지)
- [ ] 외부 연결 관리 (`/admin/external-connections`)
- [ ] 외부 호출 설정 (`/admin/external-call-configs`)
- [ ] 배치 관리 (`/admin/batch-management`)
- [ ] 레이아웃 관리 (`/admin/layouts`)

### 우선순위 3 (기타 관리 페이지)
- [ ] 템플릿 관리 (`/admin/templates`)
- [ ] 표준 관리 (`/admin/standards`)
- [ ] 다국어 관리 (`/admin/i18n`)
- [ ] 수집 관리 (`/admin/collection-management`)

## 체크리스트

각 페이지 작업 시 다음을 확인하세요:

### 레이아웃
- [ ] `bg-background` 사용 (하드코딩된 색상 없음)
- [ ] `container mx-auto space-y-6 p-6` 구조
- [ ] 페이지 헤더에 `border-b pb-4`

### 색상
- [ ] CSS Variables만 사용 (`bg-card`, `text-muted-foreground` 등)
- [ ] `bg-gray-*`, `text-gray-*` 등 하드코딩 제거

### 타이포그래피
- [ ] 페이지 제목: `text-3xl font-bold tracking-tight`
- [ ] 섹션 제목: `text-sm font-semibold`
- [ ] 본문: `text-sm`
- [ ] 보조 텍스트: `text-xs text-muted-foreground`

### 간격
- [ ] 페이지 레벨: `space-y-6`
- [ ] 섹션 레벨: `space-y-4`
- [ ] 필드 레벨: `space-y-2`
- [ ] 카드 패딩: `p-4` 또는 `p-6`

### 버튼
- [ ] 표준 variants 사용 (`default`, `outline`, `ghost`)
- [ ] 표준 크기: `h-10` (기본), `h-9` (작음), `h-8` (아이콘)
- [ ] 텍스트: `text-sm font-medium`
- [ ] 아이콘 + 텍스트: `gap-2`

### 입력 필드
- [ ] 높이: `h-10`
- [ ] 텍스트: `text-sm`
- [ ] Label과 Input `htmlFor`/`id` 연결
- [ ] `space-y-2` 구조

### 테이블
- [ ] `rounded-lg border bg-card shadow-sm`
- [ ] 헤더: `h-12 text-sm font-semibold bg-muted/50`
- [ ] 데이터 행: `h-16 text-sm`
- [ ] Hover: `hover:bg-muted/50`

### 반응형
- [ ] 모바일 우선 디자인
- [ ] `sm:`, `md:`, `lg:` 브레이크포인트 사용
- [ ] `flex-col sm:flex-row` 패턴

### 접근성
- [ ] Label `htmlFor` 속성
- [ ] Input `id` 속성
- [ ] 버튼 `aria-label`
- [ ] Switch `aria-label`

## 마이그레이션 절차

1. **페이지 컴포넌트 수정** (`page.tsx`)
   - 레이아웃 구조 변경
   - 색상 CSS Variables로 변경
   - 페이지 헤더 표준화

2. **Toolbar 컴포넌트 수정**
   - 검색 영역 스타일 통일
   - 버튼 스타일 표준화
   - 반응형 레이아웃 적용

3. **Table 컴포넌트 수정**
   - 테이블 컨테이너 스타일 통일
   - 헤더/데이터 행 높이 표준화
   - 로딩/Empty State 표준화

4. **Form 컴포넌트 수정** (있는 경우)
   - 필드 구조 표준화
   - 라벨과 입력 필드 연결
   - 에러 메시지 스타일 통일

5. **Modal 컴포넌트 수정** (있는 경우)
   - Dialog 표준 패턴 적용
   - 반응형 크기 (`max-w-[95vw] sm:max-w-[500px]`)
   - 버튼 스타일 표준화

6. **린트 에러 확인**
   ```bash
   # 수정한 파일들 확인
   npm run lint
   ```

7. **테스트**
   - 기능 동작 확인
   - 반응형 확인 (모바일/태블릿/데스크톱)
   - 다크모드 확인 (있는 경우)

## 참고 파일

### 완성된 예시
- `frontend/app/(main)/admin/userMng/page.tsx`
- `frontend/components/admin/UserToolbar.tsx`
- `frontend/components/admin/UserTable.tsx`
- `frontend/components/admin/UserManagement.tsx`

### 스타일 가이드
- `.cursorrules` - 전체 스타일 규칙
- Section 1-21: 각 스타일 요소별 상세 가이드

