- Backend: FastAPI + MongoDB + Redis (카테고리, 할일 CRUD, 파일 첨부, 검색, 대시보드) - Frontend: Next.js 15 + Tailwind + React Query + Zustand - 통합 TodoModal: 생성/수정 모달 통합, 탭 구조 (기본/태그와 첨부) - 간트차트: 카테고리별 할일 타임라인 시각화 - TodoCard: 제목/카테고리/우선순위/태그/첨부 한줄 표시 - Docker Compose 배포 (Frontend:3010, Backend:8010, MongoDB:27021, Redis:6391) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
313 lines
9.9 KiB
Markdown
313 lines
9.9 KiB
Markdown
# todos2 — 화면설계서
|
||
|
||
> 자동 생성: `pptx_to_md.py` | 원본: `SCREEN_DESIGN.pptx`
|
||
> 생성 시각: 2026-02-10 07:12
|
||
> **이 파일을 직접 수정하지 마세요. PPTX를 수정 후 스크립트를 재실행하세요.**
|
||
|
||
## 페이지 목록
|
||
|
||
| ID | 페이지명 | 경로 | 설명 |
|
||
|-----|---------|------|------|
|
||
| P-001 | 대시보드 | `/` | 메인 페이지. 통계 카드, 차트, 마감 임박 목록 |
|
||
| P-002 | 할일 목록 | `/todos` | 할일 CRUD, 필터링, 정렬, 일괄 작업 |
|
||
| P-003 | 할일 상세/편집 | `/todos/[id]` | 할일 상세 보기 및 수정 폼 |
|
||
| P-004 | 카테고리 관리 | `/categories` | 카테고리 CRUD, 색상 지정 |
|
||
| P-005 | 검색 결과 | `/search` | 제목/내용/태그 기반 검색 결과 |
|
||
|
||
---
|
||
|
||
## P-001: 대시보드 (`/`)
|
||
|
||
### 레이아웃
|
||
|
||
[로고 todos2] | [검색바 _______________] | [알림]
|
||
● 대시보드
|
||
할일 목록
|
||
카테고리 관리
|
||
카테고리
|
||
업무 (12)
|
||
개인 (8)
|
||
학습 (5)
|
||
인기 태그
|
||
#긴급
|
||
#회의
|
||
#프로젝트
|
||
전체 할일50
|
||
완료30
|
||
미완료20
|
||
완료율60%
|
||
[카테고리별 분포 - 도넛 차트]업무 40% | 개인 30%학습 20% | 기타 10%
|
||
[우선순위별 현황 - 막대 차트]high: 10 | medium: 25 | low: 15
|
||
[마감 임박 할일]1. API 문서 작성 (D-1)2. 디자인 리뷰 (D-2)3. 테스트 코드 (D-3)
|
||
|
||
| 컴포넌트 | 기능 | 상태 |
|
||
| --- | --- | --- |
|
||
| StatsCards | 전체/완료/미완료/완료율 카드 | loading, data, empty |
|
||
| CategoryChart | 카테고리별 도넛 차트 | loading, data, empty |
|
||
| PriorityChart | 우선순위별 막대 차트 | loading, data, empty |
|
||
| UpcomingDeadlines | 마감 임박 할일 Top 5 | loading, data, empty |
|
||
| Sidebar | 카테고리/태그 네비게이션 | default |
|
||
|
||
### 컴포넌트
|
||
|
||
| 컴포넌트 | Props | 상태 |
|
||
|---------|-------|------|
|
||
| `StatsCards` | stats | loading, empty, data |
|
||
| `CategoryChart` | categoryData | loading, empty, data |
|
||
| `PriorityChart` | priorityData | loading, empty, data |
|
||
| `UpcomingDeadlines` | deadlines, onItemClick | loading, empty, data |
|
||
| `Sidebar` | categories, tags, activePath | default |
|
||
|
||
### 인터랙션
|
||
|
||
| 트리거 | 동작 | 결과 |
|
||
|--------|------|------|
|
||
| 마감 임박 항목 클릭 | `router.push(/todos/{id})` | 해당 할일 상세 페이지로 이동 |
|
||
| 사이드바 카테고리 클릭 | `router.push(/todos?category_id={id})` | 해당 카테고리의 할일 목록으로 이동 |
|
||
| 사이드바 태그 클릭 | `router.push(/todos?tag={name})` | 해당 태그의 할일 목록으로 이동 |
|
||
|
||
### 반응형: sm, md, lg
|
||
|
||
---
|
||
|
||
## P-002: 할일 목록 (`/todos`)
|
||
|
||
### 레이아웃
|
||
|
||
[로고 todos2] | [검색바 _______________] | [알림]
|
||
대시보드
|
||
● 할일 목록
|
||
카테고리 관리
|
||
필터:
|
||
상태 ▾
|
||
우선순위 ▾
|
||
정렬 ▾
|
||
+ 새 할일
|
||
3개 선택됨
|
||
일괄 완료
|
||
카테고리 변경
|
||
일괄 삭제
|
||
☐
|
||
API 문서 작성
|
||
업무
|
||
#긴급
|
||
D-1
|
||
[수정] [삭제]
|
||
☑
|
||
회의록 정리
|
||
업무
|
||
#회의
|
||
D-5
|
||
[수정] [삭제]
|
||
☐
|
||
Next.js 학습
|
||
학습
|
||
#학습
|
||
D-7
|
||
[수정] [삭제]
|
||
☑
|
||
장보기 목록 작성
|
||
개인
|
||
#생활
|
||
-
|
||
[수정] [삭제]
|
||
< 1 2 3 4 5 >
|
||
|
||
| 컴포넌트 | 기능 | 상태 |
|
||
| --- | --- | --- |
|
||
| TodoFilter | 상태/우선순위/정렬 필터 | default, applied |
|
||
| TodoList | 할일 카드 리스트 | loading, empty, error, data |
|
||
| TodoCard | 개별 할일 행 | default, completed, overdue |
|
||
| BatchActions | 일괄 작업 바 | hidden, visible |
|
||
| TodoForm (Modal) | 할일 생성/수정 모달 | create, edit |
|
||
| Pagination | 페이지 네비게이션 | default |
|
||
|
||
### 컴포넌트
|
||
|
||
| 컴포넌트 | Props | 상태 |
|
||
|---------|-------|------|
|
||
| `TodoFilter` | filters, onFilterChange | default, applied |
|
||
| `TodoList` | todos, selectedIds, onToggle, onSelect, onEdit, onDelete | loading, empty, error, data |
|
||
| `TodoCard` | todo, isSelected, onToggle, onSelect, onEdit, onDelete | default, completed, overdue |
|
||
| `BatchActions` | selectedIds, categories, onBatchComplete, onBatchDelete, onBatchMove | hidden, visible |
|
||
| `TodoForm` | mode, todo, categories, tags, onSubmit, onClose | create, edit |
|
||
| `Pagination` | currentPage, totalPages, onPageChange | default |
|
||
|
||
### 인터랙션
|
||
|
||
| 트리거 | 동작 | 결과 |
|
||
|--------|------|------|
|
||
| "+ 새 할일" 버튼 클릭 | `openTodoForm(mode='create')` | 할일 생성 모달 열림 |
|
||
| 체크박스 클릭 | `toggleTodo(id)` | 완료 상태 토글 |
|
||
| 행 선택 체크박스 | `toggleSelect(id)` | 일괄 작업 대상에 추가/제거 |
|
||
| 필터 변경 | `applyFilter(filters)` | 목록 재조회 |
|
||
| "일괄 완료" 클릭 | `batchComplete(selectedIds)` | 선택된 할일 일괄 완료 |
|
||
| "일괄 삭제" 클릭 | `batchDelete(selectedIds)` | 확인 후 일괄 삭제 |
|
||
| "카테고리 변경" 클릭 | `batchMoveCategory(selectedIds, categoryId)` | 카테고리 선택 후 변경 |
|
||
| 태그 뱃지 클릭 | `applyFilter({tag: tagName})` | 해당 태그로 필터링 |
|
||
|
||
### 반응형: sm, md, lg
|
||
|
||
---
|
||
|
||
## P-003: 할일 상세/편집 (`/todos/[id]`)
|
||
|
||
### 레이아웃
|
||
|
||
[로고 todos2] | [검색바] | [알림]
|
||
(Sidebar)
|
||
할일 목록 > API 문서 작성
|
||
제목 *
|
||
API 문서 작성
|
||
내용
|
||
Swagger UI 기반 API 문서를 작성하고 엔드포인트별 요청/응답 예시를 추가한다.
|
||
카테고리
|
||
업무 ▾
|
||
우선순위
|
||
높음 ▾
|
||
마감일
|
||
2026-02-11 📅
|
||
태그
|
||
#긴급 ×
|
||
#문서 ×
|
||
태그 입력 (자동완성)...
|
||
취소
|
||
저장
|
||
|
||
| 컴포넌트 | 기능 | 상태 |
|
||
| --- | --- | --- |
|
||
| TodoDetailForm | 할일 상세 폼 | loading, view, edit, saving |
|
||
| CategorySelect | 카테고리 드롭다운 | default |
|
||
| PrioritySelect | 우선순위 드롭다운 (색상) | default |
|
||
| DatePicker | 달력 마감일 선택 | default, open |
|
||
| TagInput | 태그 입력 + 자동완성 + 뱃지 | default, suggesting |
|
||
|
||
### 컴포넌트
|
||
|
||
| 컴포넌트 | Props | 상태 |
|
||
|---------|-------|------|
|
||
| `TodoDetailForm` | todo, categories, tags, onSave, onCancel, onDelete | loading, view, edit, saving |
|
||
| `CategorySelect` | categories, selectedId, onChange | default |
|
||
| `PrioritySelect` | selectedPriority, onChange | default |
|
||
| `DatePicker` | selectedDate, onChange | default, open |
|
||
| `TagInput` | tags, suggestions, onAdd, onRemove | default, suggesting |
|
||
|
||
### 인터랙션
|
||
|
||
| 트리거 | 동작 | 결과 |
|
||
|--------|------|------|
|
||
| "저장" 버튼 클릭 | `updateTodo(id, formData)` | 할일 업데이트 후 성공 토스트 |
|
||
| "취소" 버튼 클릭 | `router.back()` | 이전 페이지로 이동 |
|
||
| 태그 입력 키워드 타이핑 | `fetchTagSuggestions(keyword)` | 자동완성 드롭다운 표시 |
|
||
| 태그 뱃지 × 클릭 | `removeTag(tagName)` | 태그 제거 |
|
||
| 달력 아이콘 클릭 | `openDatePicker()` | 달력 팝업 표시 |
|
||
|
||
### 반응형: sm, md, lg
|
||
|
||
---
|
||
|
||
## P-004: 카테고리 관리 (`/categories`)
|
||
|
||
### 레이아웃
|
||
|
||
[로고 todos2] | [검색바] | [알림]
|
||
대시보드
|
||
할일 목록
|
||
● 카테고리 관리
|
||
카테고리 관리
|
||
+ 새 카테고리
|
||
업무
|
||
12개 할일
|
||
[색상] [수정] [삭제]
|
||
개인
|
||
8개 할일
|
||
[색상] [수정] [삭제]
|
||
학습
|
||
5개 할일
|
||
[색상] [수정] [삭제]
|
||
건강
|
||
3개 할일
|
||
[색상] [수정] [삭제]
|
||
새 카테고리 이름...
|
||
추가
|
||
|
||
| 컴포넌트 | 기능 | 상태 |
|
||
| --- | --- | --- |
|
||
| CategoryList | 카테고리 목록 | loading, empty, data |
|
||
| CategoryItem | 개별 카테고리 행 | default, editing |
|
||
| CategoryForm | 카테고리 생성/수정 인라인 폼 | create, edit |
|
||
| ColorPicker | 카테고리 색상 선택기 | default, open |
|
||
|
||
### 컴포넌트
|
||
|
||
| 컴포넌트 | Props | 상태 |
|
||
|---------|-------|------|
|
||
| `CategoryList` | categories, onEdit, onDelete | loading, empty, data |
|
||
| `CategoryItem` | category, onEdit, onDelete | default, editing |
|
||
| `CategoryForm` | mode, category, onSubmit, onCancel | create, edit |
|
||
| `ColorPicker` | selectedColor, onChange | default, open |
|
||
|
||
### 인터랙션
|
||
|
||
| 트리거 | 동작 | 결과 |
|
||
|--------|------|------|
|
||
| "+ 새 카테고리" 버튼 클릭 | `showCategoryForm(mode='create')` | 인라인 생성 폼 표시 |
|
||
| "추가" 버튼 클릭 | `createCategory({name, color})` | 카테고리 생성 후 목록 갱신 |
|
||
| "수정" 클릭 | `showCategoryForm(mode='edit', category)` | 해당 행이 수정 폼으로 전환 |
|
||
| "삭제" 클릭 | `deleteCategory(id)` | 확인 다이얼로그 후 삭제 |
|
||
| 색상 변경 클릭 | `openColorPicker(category)` | 색상 선택기 팝업 |
|
||
|
||
### 반응형: sm, md, lg
|
||
|
||
---
|
||
|
||
## P-005: 검색 결과 (`/search`)
|
||
|
||
### 레이아웃
|
||
|
||
todos2
|
||
API 문서 [×]
|
||
[알림]
|
||
(Sidebar)
|
||
"API 문서" 검색 결과 (3건)
|
||
API 문서 작성
|
||
Swagger UI 기반 API 문서를 작성하고...
|
||
업무
|
||
D-1
|
||
API 문서 리뷰
|
||
팀원들과 API 문서 리뷰 미팅을...
|
||
업무
|
||
D-5
|
||
REST API 문서화 학습
|
||
OpenAPI 스펙과 자동화 도구를...
|
||
학습
|
||
D-14
|
||
* 결과 없을 때: "검색 결과가 없습니다. 다른 키워드로 검색해보세요."
|
||
|
||
| 컴포넌트 | 기능 | 상태 |
|
||
| --- | --- | --- |
|
||
| SearchBar | 헤더 내 검색 입력 + 클리어 | default, active, has_query |
|
||
| SearchResults | 검색 결과 리스트 | loading, empty, data |
|
||
| SearchResultItem | 개별 결과 (제목 하이라이트, 설명) | default |
|
||
| Pagination | 결과 페이지네이션 | default |
|
||
|
||
### 컴포넌트
|
||
|
||
| 컴포넌트 | Props | 상태 |
|
||
|---------|-------|------|
|
||
| `SearchBar` | query, onSearch, onClear | default, active, has_query |
|
||
| `SearchResults` | results, query, total, onItemClick | loading, empty, data |
|
||
| `SearchResultItem` | result, query, onClick | default |
|
||
| `Pagination` | currentPage, totalPages, onPageChange | default |
|
||
|
||
### 인터랙션
|
||
|
||
| 트리거 | 동작 | 결과 |
|
||
|--------|------|------|
|
||
| 검색바에 키워드 입력 후 Enter | `search(query)` | 검색 API 호출 후 결과 표시 |
|
||
| 검색바 × 버튼 클릭 | `clearSearch()` | 검색어 클리어, 이전 페이지로 이동 |
|
||
| 검색 결과 항목 클릭 | `router.push(/todos/{id})` | 해당 할일 상세 페이지로 이동 |
|
||
| 페이지 번호 클릭 | `search(query, page)` | 해당 페이지의 검색 결과 |
|
||
|
||
### 반응형: sm, md, lg
|