-
Notifications
You must be signed in to change notification settings - Fork 3
Fix/kanban api #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Fix/kanban api #70
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
e1e16a2
feat: 팀 페이지 구조 작성
Jieunsse bcd95fc
feat: 칸반 기능 구현
Jieunsse c1aa5fd
feat: 멤버 초대 카드 구현
Jieunsse 21dd60a
feat: 팀 컴포넌트 구현
Jieunsse 9177b5b
feat: 진행상황 요약 구현
Jieunsse 6f31e3f
chore: 누락된 인터페이스 추가
Jieunsse 9b77543
feat: 팀 페이지 도메인 컴포넌트 추가
Jieunsse 3c62642
feat: addteam 이미지 업로드 API 및 쿼리 추가
Jieunsse 0579f25
feat: 팀 그룹/할일목록 API 및 쿼리 추가
Jieunsse 9c4bbf6
feat: 칸반 아이템 인라인 수정 및 접기/펼치기 기능 구현
Jieunsse 8149b4a
feat: 멤버 케밥 메뉴 컴포넌트 추가 및 멤버 카드에 적용
Jieunsse 499830e
feat: 팀 생성 모달 컴포넌트 추가
Jieunsse 18f016f
refactor: 팀 사이드바의 팀 추가를 모달에서 링크로 변경
Jieunsse 6809394
chore: git ignore 수정
Jieunsse 8cd3a92
chore: 팀 생성 모달 관련 불필요한 파일 삭제
Jieunsse 6f11c8e
style: 버튼 텍스트 밑줄 삭제
Jieunsse 6b11e3d
refactor: 코드 리팩토링
Jieunsse 09fd056
refactor: 대시보드 리팩토링
Jieunsse 121e39d
refactor: kanbanBoard 비즈니스 로직을 훅으로 분리
Jieunsse 0bd5e01
refactor: 반응형 대응 및 목업 제거
Jieunsse 6da5cb8
refactor: 커스텀훅 분리, 실제 api 연결
Jieunsse 7e235ad
refactor: 사이드바 로그인 관련 작업 및 레이아웃 수정
Jieunsse f01cdde
Merge branch 'main' into fix/kanban-api
Jieunsse 9db3e7c
chore: 환경변수 예시 파일 추가
Jieunsse 287413b
chore: .dev-session.json을 gitignore에 추가
Jieunsse 20383b1
refactor: api 호출을 프록시 라우트 방식으로 변경
Jieunsse a10b8ec
fix: 팀 삭제 후 리다이렉트 및 유저 쿼리 무효화 수정
Jieunsse 54bb53f
fix: 사이드바 로그인 상태 전달 및 spacer 너비 스타일 수정
Jieunsse 381500d
fix: 사이드바 접힘 시 팀 목록 숨김 처리
Jieunsse 457dc7d
feat: 초대 링크 복사 시 토스트 메시지 표시
Jieunsse da9573d
style: [teamid] 레이아웃 크기 확대 및 사이드바 여백 추가
Jieunsse 7e9076a
feat: [teamid] 모바일/태블릿 햄버거 버튼으로 사이드바 드로어 열기 기능 추가
Jieunsse bbdcd7e
fix: 팀 생성 후 사이드바에 새 팀이 즉시 표시되지 않는 문제 수정
Jieunsse 95dabac
refactor: navigation 플래그 추가
Jieunsse 7fc7522
feat: useParam 통해서 리다이렉팅 대응
Jieunsse 753c194
refactor: route.ts delete 추가
Jieunsse 89f55d6
refactor: 팀 참가하기 토큰값 반영되도록 수정
Jieunsse 2d7510f
fix: 임포트 경로 에러 수정
Jieunsse 94f5b79
fix: useEffect 수정
Jieunsse 9ce359b
fix: useSearchParams Suspense 경계 추가로 빌드 에러 수정
Jieunsse File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| API_BASE_URL=https://fe-project-cowokers.vercel.app | ||
| API_TEAM_ID=20-1 | ||
| NEXT_PUBLIC_APP_URL=http://localhost:3000 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { requestJson, requestVoid } from '@/shared/apis/groups/http'; | ||
| import type { Group, Task, UpdateGroupBody } from './types'; | ||
|
|
||
| const GROUP_ERROR_MESSAGE = { | ||
| fetch: '그룹 정보 조회 실패', | ||
| update: '그룹 정보 수정 실패', | ||
| delete: '그룹 삭제 실패', | ||
| invitation: '초대 링크 조회 실패', | ||
| tasks: '그룹 작업 조회 실패', | ||
| } as const; | ||
|
|
||
| export function getGroup(groupId: number): Promise<Group> { | ||
| return requestJson<Group>(`/groups/${groupId}`, GROUP_ERROR_MESSAGE.fetch); | ||
| } | ||
|
|
||
| export function updateGroup(groupId: number, body: UpdateGroupBody): Promise<Group> { | ||
| return requestJson<Group>(`/groups/${groupId}`, GROUP_ERROR_MESSAGE.update, { | ||
| method: 'PATCH', | ||
| body: JSON.stringify(body), | ||
| }); | ||
| } | ||
|
|
||
| export function deleteGroup(groupId: number): Promise<void> { | ||
| return requestVoid(`/groups/${groupId}`, GROUP_ERROR_MESSAGE.delete, { | ||
| method: 'DELETE', | ||
| }); | ||
| } | ||
|
|
||
| // API 응답: 초대 토큰 문자열 (JWT) 그대로 반환 | ||
| export function getGroupInvitation(groupId: number): Promise<string> { | ||
| return requestJson<string>(`/groups/${groupId}/invitation`, GROUP_ERROR_MESSAGE.invitation); | ||
| } | ||
|
|
||
| export function getGroupTasks(groupId: number, date?: string): Promise<Task[]> { | ||
| const query = date ? `?date=${encodeURIComponent(date)}` : ''; | ||
| return requestJson<Task[]>(`/groups/${groupId}/tasks${query}`, GROUP_ERROR_MESSAGE.tasks); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { requestJson, requestVoid } from '@/shared/apis/groups/http'; | ||
| import type { TaskList } from './types'; | ||
|
|
||
| const TASK_LIST_ERROR_MESSAGE = { | ||
| create: '작업 목록 생성 실패', | ||
| fetch: '작업 목록 조회 실패', | ||
| delete: '작업 목록 삭제 실패', | ||
| } as const; | ||
|
|
||
| export function createTaskList(groupId: number, name: string): Promise<TaskList> { | ||
| return requestJson<TaskList>(`/groups/${groupId}/task-lists`, TASK_LIST_ERROR_MESSAGE.create, { | ||
| method: 'POST', | ||
| body: JSON.stringify({ name }), | ||
| }); | ||
| } | ||
|
|
||
| export function getTaskList(groupId: number, taskListId: number, date?: string): Promise<TaskList> { | ||
| const query = date ? `?date=${encodeURIComponent(date)}` : ''; | ||
| return requestJson<TaskList>( | ||
| `/groups/${groupId}/task-lists/${taskListId}${query}`, | ||
| TASK_LIST_ERROR_MESSAGE.fetch, | ||
| ); | ||
| } | ||
|
|
||
| export function deleteTaskList(groupId: number, taskListId: number): Promise<void> { | ||
| return requestVoid( | ||
| `/groups/${groupId}/task-lists/${taskListId}`, | ||
| TASK_LIST_ERROR_MESSAGE.delete, | ||
| { method: 'DELETE' }, | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| export type MemberRole = 'ADMIN' | 'MEMBER'; | ||
|
|
||
| export type FrequencyType = 'ONCE' | 'DAILY' | 'WEEKLY' | 'MONTHLY'; | ||
|
|
||
| export interface GroupMember { | ||
| userId: number; | ||
| groupId: number; | ||
| userName: string; | ||
| userEmail: string; | ||
| userImage: string; | ||
| role: MemberRole; | ||
| } | ||
|
|
||
| export interface TaskUser { | ||
| id: number; | ||
| nickname: string; | ||
| image: string | null; | ||
| } | ||
|
|
||
| export interface Task { | ||
| id: number; | ||
| name: string; | ||
| description: string | null; | ||
| date: string; | ||
| doneAt: string | null; | ||
| updatedAt: string; | ||
| frequency: FrequencyType; | ||
| recurringId: number; | ||
| deletedAt: string | null; | ||
| commentCount: number; | ||
| displayIndex: number; | ||
| writer: TaskUser | null; | ||
| doneBy: { user: TaskUser | null } | null; | ||
| } | ||
|
|
||
| export interface TaskList { | ||
| id: number; | ||
| name: string; | ||
| groupId: number; | ||
| displayIndex: number; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| tasks: Task[]; | ||
| } | ||
|
|
||
| export interface Group { | ||
| id: number; | ||
| teamId: string; | ||
| name: string; | ||
| image: string; | ||
| createdAt: string; | ||
| updatedAt: string; | ||
| members: GroupMember[]; | ||
| taskLists: Omit<TaskList, 'tasks'>[]; | ||
| } | ||
|
|
||
| export interface UpdateGroupBody { | ||
| name?: string; | ||
| image?: string | null; | ||
| } |
85 changes: 85 additions & 0 deletions
85
src/app/[teamid]/_domain/components/Kanban/KanbanBoard.module.css
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| .wrapper { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 20px; | ||
| } | ||
|
|
||
| .boardHeader { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| } | ||
|
|
||
| .boardTitle { | ||
| font-size: 16px; | ||
| font-weight: 600; | ||
| color: var(--color-text-primary); | ||
| margin: 0; | ||
| } | ||
|
|
||
| .boardCount { | ||
| color: var(--color-text-default); | ||
| font-weight: 400; | ||
| } | ||
|
|
||
| .board { | ||
| display: grid; | ||
| grid-template-columns: repeat(3, 1fr); | ||
| gap: 24px; | ||
| align-items: start; | ||
| } | ||
|
|
||
| /* 태블릿: 컬럼을 한 줄씩 세로로 쌓기 */ | ||
| @media (min-width: 768px) and (max-width: 1279px) { | ||
| .board { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 16px; | ||
| } | ||
| } | ||
|
|
||
| /* 모바일 */ | ||
| @media (max-width: 767px) { | ||
| .board { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 16px; | ||
| align-items: center; | ||
| max-width: 100%; | ||
| box-sizing: border-box; | ||
| overflow-x: hidden; | ||
| } | ||
| } | ||
|
|
||
| .addListButton { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| width: 100%; | ||
| max-width: 1140px; | ||
| padding: 14px 24px; | ||
| background: var(--color-background-primary); | ||
| border: 1px dashed var(--color-background-tertiary); | ||
| border-radius: 12px; | ||
| cursor: pointer; | ||
| font-size: 14px; | ||
| font-weight: 500; | ||
| color: var(--color-text-default); | ||
| font-family: inherit; | ||
| transition: | ||
| background 0.15s, | ||
| color 0.15s; | ||
| } | ||
|
|
||
| .addListButton:hover { | ||
| background: var(--color-brand-secondary); | ||
| color: var(--color-brand-primary); | ||
| border-color: var(--color-brand-primary); | ||
| } | ||
|
|
||
| .dragOverlay { | ||
| box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); | ||
| border-radius: 12px; | ||
| opacity: 0.92; | ||
| cursor: grabbing; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
requestJsonhelper callsresponse.json()internally. If the API returns a raw JWT string (as the comment on line 29 suggests), this will result in a syntax error during JSON parsing because a raw JWT is not a valid JSON value. If the response is indeed a raw string, you should use a helper that utilizesresponse.text()instead.