605 lines
16 KiB
Markdown
605 lines
16 KiB
Markdown
|
|
# ERP 시스템 UI/UX 디자인 가이드
|
||
|
|
|
||
|
|
## 📋 문서 목적
|
||
|
|
이 문서는 ERP 시스템의 새로운 페이지나 컴포넌트를 개발할 때 참고할 수 있는 **디자인 시스템 기준안**입니다.
|
||
|
|
일관된 사용자 경험을 위해 모든 개발자는 이 가이드를 따라 개발해주세요.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎨 디자인 시스템 개요
|
||
|
|
|
||
|
|
### 디자인 철학
|
||
|
|
- **일관성**: 모든 페이지에서 동일한 패턴 사용
|
||
|
|
- **명확성**: 직관적이고 이해하기 쉬운 UI
|
||
|
|
- **접근성**: 모든 사용자가 쉽게 사용할 수 있도록
|
||
|
|
- **반응성**: 다양한 화면 크기에 대응
|
||
|
|
|
||
|
|
### 기술 스택
|
||
|
|
- **CSS Framework**: Tailwind CSS
|
||
|
|
- **UI Library**: shadcn/ui
|
||
|
|
- **Icons**: Lucide React
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📐 페이지 기본 구조
|
||
|
|
|
||
|
|
### 1. 표준 페이지 레이아웃
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
export default function YourPage() {
|
||
|
|
return (
|
||
|
|
<div className="min-h-screen bg-gray-50">
|
||
|
|
<div className="w-full max-w-none px-4 py-8 space-y-8">
|
||
|
|
{/* 페이지 제목 */}
|
||
|
|
<div className="flex items-center justify-between bg-white rounded-lg shadow-sm border p-6">
|
||
|
|
<div>
|
||
|
|
<h1 className="text-3xl font-bold text-gray-900">페이지 제목</h1>
|
||
|
|
<p className="mt-2 text-gray-600">페이지 설명</p>
|
||
|
|
</div>
|
||
|
|
<div className="flex gap-2">
|
||
|
|
{/* 버튼들 */}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 메인 컨텐츠 */}
|
||
|
|
<Card className="shadow-sm">
|
||
|
|
<CardContent className="p-6">
|
||
|
|
{/* 내용 */}
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 구조 설명
|
||
|
|
|
||
|
|
#### 최상위 래퍼
|
||
|
|
```tsx
|
||
|
|
<div className="min-h-screen bg-gray-50">
|
||
|
|
```
|
||
|
|
- `min-h-screen`: 최소 높이를 화면 전체로
|
||
|
|
- `bg-gray-50`: 연한 회색 배경 (전체 페이지 기본 배경)
|
||
|
|
|
||
|
|
#### 컨테이너
|
||
|
|
```tsx
|
||
|
|
<div className="w-full max-w-none px-4 py-8 space-y-8">
|
||
|
|
```
|
||
|
|
- `w-full max-w-none`: 전체 너비 사용
|
||
|
|
- `px-4`: 좌우 패딩 1rem (16px)
|
||
|
|
- `py-8`: 상하 패딩 2rem (32px)
|
||
|
|
- `space-y-8`: 하위 요소 간 수직 간격 2rem
|
||
|
|
|
||
|
|
#### 헤더 카드
|
||
|
|
```tsx
|
||
|
|
<div className="flex items-center justify-between bg-white rounded-lg shadow-sm border p-6">
|
||
|
|
<div>
|
||
|
|
<h1 className="text-3xl font-bold text-gray-900">제목</h1>
|
||
|
|
<p className="mt-2 text-gray-600">설명</p>
|
||
|
|
</div>
|
||
|
|
<div className="flex gap-2">
|
||
|
|
{/* 버튼들 */}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 컴포넌트 디자인 기준
|
||
|
|
|
||
|
|
### 1. 버튼
|
||
|
|
|
||
|
|
#### 주요 버튼 (Primary)
|
||
|
|
```tsx
|
||
|
|
<Button className="bg-orange-500 hover:bg-orange-600">
|
||
|
|
<Plus className="w-4 h-4 mr-2" />
|
||
|
|
버튼 텍스트
|
||
|
|
</Button>
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 보조 버튼 (Secondary)
|
||
|
|
```tsx
|
||
|
|
<Button variant="outline" size="sm">
|
||
|
|
<RefreshCw className="w-4 h-4 mr-2" />
|
||
|
|
새로고침
|
||
|
|
</Button>
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 위험 버튼 (Danger)
|
||
|
|
```tsx
|
||
|
|
<Button
|
||
|
|
variant="ghost"
|
||
|
|
className="text-red-500 hover:text-red-600"
|
||
|
|
>
|
||
|
|
<Trash2 className="w-4 h-4" />
|
||
|
|
삭제
|
||
|
|
</Button>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. 카드 (Card)
|
||
|
|
|
||
|
|
#### 기본 카드
|
||
|
|
```tsx
|
||
|
|
<Card className="shadow-sm">
|
||
|
|
<CardHeader>
|
||
|
|
<CardTitle>카드 제목</CardTitle>
|
||
|
|
</CardHeader>
|
||
|
|
<CardContent className="p-6">
|
||
|
|
{/* 내용 */}
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 강조 카드
|
||
|
|
```tsx
|
||
|
|
<Card className="bg-gradient-to-r from-orange-50 to-amber-50 border-orange-200 shadow-sm">
|
||
|
|
<CardHeader>
|
||
|
|
<CardTitle className="flex items-center">
|
||
|
|
<Icon className="w-5 h-5 mr-2 text-orange-500" />
|
||
|
|
제목
|
||
|
|
</CardTitle>
|
||
|
|
</CardHeader>
|
||
|
|
<CardContent>
|
||
|
|
<p className="text-gray-700">내용</p>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. 테이블
|
||
|
|
|
||
|
|
#### 기본 테이블 구조
|
||
|
|
```tsx
|
||
|
|
<Card className="shadow-sm">
|
||
|
|
<CardContent className="p-6">
|
||
|
|
<table className="w-full">
|
||
|
|
<thead>
|
||
|
|
<tr className="border-b border-gray-200/40 bg-gradient-to-r from-slate-50/90 to-gray-50/70">
|
||
|
|
<th className="h-12 px-6 py-4 text-left text-sm font-semibold text-gray-700">
|
||
|
|
컬럼명
|
||
|
|
</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
<tr className="h-12 border-b border-gray-100/60 hover:bg-gradient-to-r hover:from-orange-50/80 hover:to-orange-100/60">
|
||
|
|
<td className="px-6 py-4 text-sm text-gray-600">
|
||
|
|
데이터
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. 폼 (Form)
|
||
|
|
|
||
|
|
#### 입력 필드
|
||
|
|
```tsx
|
||
|
|
<div className="space-y-2">
|
||
|
|
<label className="block text-sm font-medium text-gray-700">
|
||
|
|
라벨
|
||
|
|
</label>
|
||
|
|
<input
|
||
|
|
type="text"
|
||
|
|
className="w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-orange-500 transition-all duration-200"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 셀렉트
|
||
|
|
```tsx
|
||
|
|
<Select>
|
||
|
|
<SelectTrigger className="w-48">
|
||
|
|
<SelectValue placeholder="선택하세요" />
|
||
|
|
</SelectTrigger>
|
||
|
|
<SelectContent>
|
||
|
|
<SelectItem value="1">옵션 1</SelectItem>
|
||
|
|
<SelectItem value="2">옵션 2</SelectItem>
|
||
|
|
</SelectContent>
|
||
|
|
</Select>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. 빈 상태 (Empty State)
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<Card className="text-center py-16 bg-white shadow-sm">
|
||
|
|
<CardContent className="pt-6">
|
||
|
|
<Icon className="w-16 h-16 mx-auto mb-4 text-gray-300" />
|
||
|
|
<p className="text-gray-500 mb-4">데이터가 없습니다</p>
|
||
|
|
<Button className="bg-orange-500 hover:bg-orange-600">
|
||
|
|
<Plus className="w-4 h-4 mr-2" />
|
||
|
|
추가하기
|
||
|
|
</Button>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6. 로딩 상태
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<Card className="shadow-sm">
|
||
|
|
<CardContent className="flex justify-center items-center py-16">
|
||
|
|
<Loader2 className="w-8 h-8 animate-spin text-orange-500" />
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎨 색상 시스템
|
||
|
|
|
||
|
|
### 주 색상 (Primary)
|
||
|
|
```css
|
||
|
|
orange-50 #fff7ed /* 매우 연한 배경 */
|
||
|
|
orange-100 #ffedd5 /* 연한 배경 */
|
||
|
|
orange-500 #f97316 /* 주요 버튼, 강조 */
|
||
|
|
orange-600 #ea580c /* 버튼 호버 */
|
||
|
|
```
|
||
|
|
|
||
|
|
### 회색 (Gray)
|
||
|
|
```css
|
||
|
|
gray-50 #f9fafb /* 페이지 배경 */
|
||
|
|
gray-100 #f3f4f6 /* 카드 내부 구분 */
|
||
|
|
gray-200 #e5e7eb /* 테두리 */
|
||
|
|
gray-300 #d1d5db /* 입력 필드 테두리 */
|
||
|
|
gray-500 #6b7280 /* 보조 텍스트 */
|
||
|
|
gray-600 #4b5563 /* 일반 텍스트 */
|
||
|
|
gray-700 #374151 /* 라벨, 헤더 */
|
||
|
|
gray-800 #1f2937 /* 제목 */
|
||
|
|
gray-900 #111827 /* 주요 제목 */
|
||
|
|
```
|
||
|
|
|
||
|
|
### 상태 색상
|
||
|
|
```css
|
||
|
|
/* 성공 */
|
||
|
|
green-100 #dcfce7
|
||
|
|
green-500 #22c55e
|
||
|
|
green-700 #15803d
|
||
|
|
|
||
|
|
/* 경고 */
|
||
|
|
red-100 #fee2e2
|
||
|
|
red-500 #ef4444
|
||
|
|
red-600 #dc2626
|
||
|
|
|
||
|
|
/* 정보 */
|
||
|
|
blue-50 #eff6ff
|
||
|
|
blue-100 #dbeafe
|
||
|
|
blue-500 #3b82f6
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📏 간격 시스템
|
||
|
|
|
||
|
|
### Spacing Scale
|
||
|
|
```css
|
||
|
|
space-y-2 0.5rem (8px) /* 폼 요소 간 간격 */
|
||
|
|
space-y-4 1rem (16px) /* 섹션 내부 간격 */
|
||
|
|
space-y-6 1.5rem (24px) /* 카드 내부 큰 간격 */
|
||
|
|
space-y-8 2rem (32px) /* 페이지 주요 섹션 간격 */
|
||
|
|
|
||
|
|
gap-2 0.5rem (8px) /* 버튼 그룹 간격 */
|
||
|
|
gap-4 1rem (16px) /* 카드 그리드 간격 */
|
||
|
|
gap-6 1.5rem (24px) /* 큰 카드 그리드 간격 */
|
||
|
|
```
|
||
|
|
|
||
|
|
### Padding
|
||
|
|
```css
|
||
|
|
p-2 0.5rem (8px) /* 작은 요소 */
|
||
|
|
p-4 1rem (16px) /* 일반 요소 */
|
||
|
|
p-6 1.5rem (24px) /* 카드, 헤더 */
|
||
|
|
p-8 2rem (32px) /* 큰 영역 */
|
||
|
|
|
||
|
|
px-3 좌우 0.75rem /* 입력 필드 */
|
||
|
|
px-4 좌우 1rem /* 버튼 */
|
||
|
|
px-6 좌우 1.5rem /* 테이블 셀 */
|
||
|
|
|
||
|
|
py-2 상하 0.5rem /* 버튼 */
|
||
|
|
py-4 상하 1rem /* 입력 필드 */
|
||
|
|
py-8 상하 2rem /* 페이지 컨테이너 */
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📝 타이포그래피
|
||
|
|
|
||
|
|
### 제목 (Headings)
|
||
|
|
```css
|
||
|
|
/* 페이지 제목 */
|
||
|
|
text-3xl font-bold text-gray-900
|
||
|
|
/* 예: 30px, Bold, #111827 */
|
||
|
|
|
||
|
|
/* 섹션 제목 */
|
||
|
|
text-2xl font-bold text-gray-900
|
||
|
|
/* 예: 24px, Bold */
|
||
|
|
|
||
|
|
/* 카드 제목 */
|
||
|
|
text-lg font-semibold text-gray-800
|
||
|
|
/* 예: 18px, Semi-bold */
|
||
|
|
|
||
|
|
/* 작은 제목 */
|
||
|
|
text-base font-medium text-gray-700
|
||
|
|
/* 예: 16px, Medium */
|
||
|
|
```
|
||
|
|
|
||
|
|
### 본문 (Body Text)
|
||
|
|
```css
|
||
|
|
/* 일반 텍스트 */
|
||
|
|
text-sm text-gray-600
|
||
|
|
/* 14px, #4b5563 */
|
||
|
|
|
||
|
|
/* 보조 설명 */
|
||
|
|
text-sm text-gray-500
|
||
|
|
/* 14px, #6b7280 */
|
||
|
|
|
||
|
|
/* 라벨 */
|
||
|
|
text-sm font-medium text-gray-700
|
||
|
|
/* 14px, Medium */
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎭 인터랙션 패턴
|
||
|
|
|
||
|
|
### 호버 효과
|
||
|
|
```css
|
||
|
|
/* 버튼 호버 */
|
||
|
|
hover:bg-orange-600
|
||
|
|
hover:shadow-md
|
||
|
|
|
||
|
|
/* 카드 호버 */
|
||
|
|
hover:shadow-lg transition-shadow
|
||
|
|
|
||
|
|
/* 테이블 행 호버 */
|
||
|
|
hover:bg-gradient-to-r hover:from-orange-50/80 hover:to-orange-100/60
|
||
|
|
```
|
||
|
|
|
||
|
|
### 포커스 효과
|
||
|
|
```css
|
||
|
|
/* 입력 필드 포커스 */
|
||
|
|
focus:outline-none
|
||
|
|
focus:ring-2
|
||
|
|
focus:ring-orange-500
|
||
|
|
focus:border-orange-500
|
||
|
|
```
|
||
|
|
|
||
|
|
### 전환 효과
|
||
|
|
```css
|
||
|
|
/* 일반 전환 */
|
||
|
|
transition-all duration-200
|
||
|
|
|
||
|
|
/* 그림자 전환 */
|
||
|
|
transition-shadow
|
||
|
|
|
||
|
|
/* 색상 전환 */
|
||
|
|
transition-colors duration-200
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔲 그리드 시스템
|
||
|
|
|
||
|
|
### 반응형 그리드
|
||
|
|
```tsx
|
||
|
|
{/* 1열 → 2열 → 3열 */}
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||
|
|
{/* 카드들 */}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 1열 → 2열 */}
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
|
|
{/* 항목들 */}
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 브레이크포인트
|
||
|
|
```css
|
||
|
|
sm: 640px @media (min-width: 640px)
|
||
|
|
md: 768px @media (min-width: 768px)
|
||
|
|
lg: 1024px @media (min-width: 1024px)
|
||
|
|
xl: 1280px @media (min-width: 1280px)
|
||
|
|
2xl: 1536px @media (min-width: 1536px)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 실전 예제
|
||
|
|
|
||
|
|
### 예제 1: 관리 페이지 (데이터 있음)
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
export default function ManagementPage() {
|
||
|
|
const [data, setData] = useState([]);
|
||
|
|
const [loading, setLoading] = useState(false);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="min-h-screen bg-gray-50">
|
||
|
|
<div className="w-full max-w-none px-4 py-8 space-y-8">
|
||
|
|
{/* 헤더 */}
|
||
|
|
<div className="flex items-center justify-between bg-white rounded-lg shadow-sm border p-6">
|
||
|
|
<div>
|
||
|
|
<h1 className="text-3xl font-bold text-gray-900">데이터 관리</h1>
|
||
|
|
<p className="mt-2 text-gray-600">시스템 데이터를 관리합니다</p>
|
||
|
|
</div>
|
||
|
|
<div className="flex gap-2">
|
||
|
|
<Button variant="outline" size="sm" onClick={loadData}>
|
||
|
|
<RefreshCw className="w-4 h-4 mr-2" />
|
||
|
|
새로고침
|
||
|
|
</Button>
|
||
|
|
<Button className="bg-orange-500 hover:bg-orange-600">
|
||
|
|
<Plus className="w-4 h-4 mr-2" />
|
||
|
|
새로 추가
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 통계 카드 */}
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
|
||
|
|
<Card className="shadow-sm">
|
||
|
|
<CardContent className="p-6">
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<div>
|
||
|
|
<p className="text-sm text-gray-500">총 개수</p>
|
||
|
|
<p className="text-2xl font-bold text-gray-900">156</p>
|
||
|
|
</div>
|
||
|
|
<div className="bg-blue-100 p-3 rounded-lg">
|
||
|
|
<Database className="w-6 h-6 text-blue-500" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
{/* 나머지 통계 카드들... */}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 데이터 테이블 */}
|
||
|
|
<Card className="shadow-sm">
|
||
|
|
<CardContent className="p-6">
|
||
|
|
<table className="w-full">
|
||
|
|
<thead>
|
||
|
|
<tr className="border-b border-gray-200/40 bg-gradient-to-r from-slate-50/90 to-gray-50/70">
|
||
|
|
<th className="h-12 px-6 py-4 text-left text-sm font-semibold text-gray-700">
|
||
|
|
이름
|
||
|
|
</th>
|
||
|
|
<th className="h-12 px-6 py-4 text-left text-sm font-semibold text-gray-700">
|
||
|
|
상태
|
||
|
|
</th>
|
||
|
|
<th className="h-12 px-6 py-4 text-left text-sm font-semibold text-gray-700">
|
||
|
|
작업
|
||
|
|
</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
{data.map((item) => (
|
||
|
|
<tr
|
||
|
|
key={item.id}
|
||
|
|
className="h-12 border-b border-gray-100/60 hover:bg-gradient-to-r hover:from-orange-50/80 hover:to-orange-100/60"
|
||
|
|
>
|
||
|
|
<td className="px-6 py-4 text-sm text-gray-600">
|
||
|
|
{item.name}
|
||
|
|
</td>
|
||
|
|
<td className="px-6 py-4">
|
||
|
|
<span className="px-2 py-1 text-xs rounded bg-green-100 text-green-700">
|
||
|
|
활성
|
||
|
|
</span>
|
||
|
|
</td>
|
||
|
|
<td className="px-6 py-4">
|
||
|
|
<div className="flex gap-2">
|
||
|
|
<Button size="sm" variant="outline">
|
||
|
|
수정
|
||
|
|
</Button>
|
||
|
|
<Button size="sm" variant="ghost" className="text-red-500">
|
||
|
|
삭제
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
))}
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 예제 2: 빈 상태 페이지
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
export default function EmptyStatePage() {
|
||
|
|
return (
|
||
|
|
<div className="min-h-screen bg-gray-50">
|
||
|
|
<div className="w-full max-w-none px-4 py-8 space-y-8">
|
||
|
|
{/* 헤더 */}
|
||
|
|
<div className="flex items-center justify-between bg-white rounded-lg shadow-sm border p-6">
|
||
|
|
<div>
|
||
|
|
<h1 className="text-3xl font-bold text-gray-900">데이터 관리</h1>
|
||
|
|
<p className="mt-2 text-gray-600">시스템 데이터를 관리합니다</p>
|
||
|
|
</div>
|
||
|
|
<Button className="bg-orange-500 hover:bg-orange-600">
|
||
|
|
<Plus className="w-4 h-4 mr-2" />
|
||
|
|
새로 추가
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 빈 상태 */}
|
||
|
|
<Card className="text-center py-16 bg-white shadow-sm">
|
||
|
|
<CardContent className="pt-6">
|
||
|
|
<Database className="w-16 h-16 mx-auto mb-4 text-gray-300" />
|
||
|
|
<p className="text-gray-500 mb-4">아직 등록된 데이터가 없습니다</p>
|
||
|
|
<Button className="bg-orange-500 hover:bg-orange-600">
|
||
|
|
<Plus className="w-4 h-4 mr-2" />
|
||
|
|
첫 데이터 추가하기
|
||
|
|
</Button>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
|
||
|
|
{/* 안내 정보 */}
|
||
|
|
<Card className="bg-gradient-to-r from-orange-50 to-amber-50 border-orange-200 shadow-sm">
|
||
|
|
<CardHeader>
|
||
|
|
<CardTitle className="text-lg flex items-center">
|
||
|
|
<Info className="w-5 h-5 mr-2 text-orange-500" />
|
||
|
|
데이터 관리 안내
|
||
|
|
</CardTitle>
|
||
|
|
</CardHeader>
|
||
|
|
<CardContent>
|
||
|
|
<p className="text-gray-700 mb-4">
|
||
|
|
💡 데이터를 추가하여 시스템을 사용해보세요!
|
||
|
|
</p>
|
||
|
|
<ul className="space-y-2 text-sm text-gray-600">
|
||
|
|
<li className="flex items-start">
|
||
|
|
<span className="text-orange-500 mr-2">✓</span>
|
||
|
|
<span>기능 설명 1</span>
|
||
|
|
</li>
|
||
|
|
<li className="flex items-start">
|
||
|
|
<span className="text-orange-500 mr-2">✓</span>
|
||
|
|
<span>기능 설명 2</span>
|
||
|
|
</li>
|
||
|
|
</ul>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ✅ 체크리스트
|
||
|
|
|
||
|
|
### 새 페이지 만들 때
|
||
|
|
- [ ] `min-h-screen bg-gray-50` 래퍼 사용
|
||
|
|
- [ ] 헤더 카드 (`bg-white rounded-lg shadow-sm border p-6`) 포함
|
||
|
|
- [ ] 제목은 `text-3xl font-bold text-gray-900`
|
||
|
|
- [ ] 설명은 `mt-2 text-gray-600`
|
||
|
|
- [ ] 주요 버튼은 `bg-orange-500 hover:bg-orange-600`
|
||
|
|
- [ ] 카드는 `shadow-sm` 클래스 포함
|
||
|
|
- [ ] 간격은 `space-y-8` 사용
|
||
|
|
|
||
|
|
### 새 컴포넌트 만들 때
|
||
|
|
- [ ] 일관된 패딩 사용 (`p-4`, `p-6`)
|
||
|
|
- [ ] 호버 효과 추가
|
||
|
|
- [ ] 전환 애니메이션 적용 (`transition-all duration-200`)
|
||
|
|
- [ ] 적절한 아이콘 사용 (Lucide React)
|
||
|
|
- [ ] 반응형 디자인 고려 (`md:`, `lg:`)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📚 참고 자료
|
||
|
|
|
||
|
|
### Tailwind CSS 공식 문서
|
||
|
|
- https://tailwindcss.com/docs
|
||
|
|
|
||
|
|
### shadcn/ui 컴포넌트
|
||
|
|
- https://ui.shadcn.com/
|
||
|
|
|
||
|
|
### Lucide 아이콘
|
||
|
|
- https://lucide.dev/icons/
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**이 가이드를 따라 개발하면 일관되고 아름다운 UI를 만들 수 있습니다!** 🎨✨
|