Skip to content
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

[FE][Feature] RetroList API 연결 및 스타일 수정 #167

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/api/@types/@asConst.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
export const Order = {
RECENTLY: 'RECENTLY',
PREVIOUSLY: 'PREVIOUSLY',
NEWEST: 'NEWEST',
OLDEST: 'OLDEST',
} as const;

export const Status = {
ALL: 'ALL',
NOT_STARTED: 'NOT_STARTED',
IN_PROGRESS: 'IN_PROGRESS',
COMPLETED: 'COMPLETED',
Expand Down
36 changes: 31 additions & 5 deletions src/api/@types/Retrospectives.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TRetrospective, TStatus } from './@asConst';
import { TRetrospective, TStatus, TOrder } from './@asConst';

//onlyGet
export interface onlyGetRetrospectiveRequest {
Expand Down Expand Up @@ -26,21 +26,35 @@ export interface RetrospectiveData {
export interface GetRetrospectiveRequest {
page: number;
size: number;
order: keyof TStatus;
order: keyof TOrder;
status: keyof TStatus;
keyword: string;
isBookmarked: boolean;
}

export interface GetRetrospectiveResponseNodes {
// 추가
id: number;
title: string;
userId: number;
teamId: number | null;
templateId: number;
status: keyof TStatus;
isBookmarked: boolean;
thumbnail: string;
startDate: string;
createdDate: string;
updatedDate: string;
}

export interface GetRetrospectiveData {
code: number;
message: string;
data: {
totalCount: number;
nodes: Array<RetrospectiveResponse>;
nodes: Array<GetRetrospectiveResponseNodes>; //RetrospectiveResponse 에서 변경
};
}

//post
export interface PostRetrospectivesRequest {
title: string;
Expand Down Expand Up @@ -85,7 +99,7 @@ export interface RetrospectiveResponse {
id: number;
title: string;
userId: number;
teamId: number;
teamId: number | null;
templateId: number;
status: keyof TStatus;
isBookmarked: boolean;
Expand All @@ -96,10 +110,22 @@ export interface RetrospectiveResponse {
};
}

export interface PatchRetrospectiveRequest {
retrospectiveId: number;
// userId: number;
}

export interface PatchRetrospectiveResponse {
code: number;
message: string;
data: boolean;
}

export interface RetrospectivesClient {
onlyGet(request: onlyGetRetrospectiveRequest): Promise<onlyGetRetrospectiveResponse>;
create(request: PostRetrospectivesRequest): Promise<PostRetrospectivesResponse>;
get(request: GetRetrospectiveRequest): Promise<GetRetrospectiveData>;
delete(request: DeleteRetrospectiveRequest): Promise<void>;
put(request: PutRetrospectiveRequest): Promise<RetrospectiveResponse>;
patch(request: PatchRetrospectiveRequest): Promise<PatchRetrospectiveResponse>;
}
1 change: 0 additions & 1 deletion src/api/__mock__/retrospective.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export const MockRetrospective: RetrospectiveResponse = {
updatedDate: '2024-04-12T04:20:54.835Z',
},
};

export const MockOnlyGetRetrospective: onlyGetRetrospectiveResponse = {
code: 202,
message: 'string',
Expand Down
30 changes: 30 additions & 0 deletions src/api/retrospectivesApi/getRetrospective.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { GetRetrospectiveData, GetRetrospectiveRequest } from '@/api/@types/Retrospectives';
import axiosInstance from '@/api/axiosConfig';

export const queryGetRetrospective = async (requestData: GetRetrospectiveRequest): Promise<GetRetrospectiveData> => {
try {
const { page, size, order, status, keyword, isBookmarked } = requestData;
const params: { [key: string]: any } = {

Check warning on line 7 in src/api/retrospectivesApi/getRetrospective.tsx

View workflow job for this annotation

GitHub Actions / eslint test

Unexpected any. Specify a different type
page,
size,
order,
isBookmarked,
};
if (status !== 'ALL') {
params.status = status;
}
if (keyword !== '') {
params.keyword = keyword;
}

console.log(params);
const response = await axiosInstance.get<GetRetrospectiveData>('/retrospectives', {
params,
});
// console.log('회고 get 성공', response.data);
return response.data;
} catch (error) {
// console.log('회고 get 실패', error);
throw new Error('회고 get 실패');
}
};
17 changes: 17 additions & 0 deletions src/api/retrospectivesApi/patchRetrospective.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PatchRetrospectiveRequest, PatchRetrospectiveResponse } from '../@types/Retrospectives';
import axiosInstance from '@/api/axiosConfig';

export const patchRetrospective = async (
requestData: PatchRetrospectiveRequest,
): Promise<PatchRetrospectiveResponse> => {
try {
console.log(requestData.retrospectiveId, 'patch 요청');
const response = await axiosInstance.patch<PatchRetrospectiveResponse>(
`/retrospectives/${requestData.retrospectiveId}/bookmark`,
);
console.log('북마크 patch 성공', response.data);
return response.data;
} catch (error) {
throw new Error('북마크 patch 실패');
}
};
3 changes: 3 additions & 0 deletions src/api/services/Retrospectives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ export const RetrospectiveService: RetrospectivesClient = {
put: async ({ retrospectiveId }, ...request) => {
return await axiosInstance.put(`${ROUTE}/${retrospectiveId}`, request);
},
patch: async (retrospectiveId, ...request) => {
return await mswInstance.patch(`${ROUTE}/${retrospectiveId}/bookmark`, request);
},
};
7 changes: 6 additions & 1 deletion src/components/RetroList/BookmarkButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ import { useState } from 'react';
import BookmarkIcon from '@/assets/BookmarkIcon_Y.png';
import * as S from '@/styles/RetroList/BookmarkButton.styles';

const BookmarkButton: React.FC = () => {
interface BookmarkButtonProps {
handleBookmarkButton: (option: boolean) => void;
}

const BookmarkButton: React.FC<BookmarkButtonProps> = ({ handleBookmarkButton }) => {
const [isBookmarked, setIsBookmarked] = useState<boolean>(false);

const handleBookmark = () => {
setIsBookmarked(!isBookmarked);
handleBookmarkButton(!isBookmarked);
};

return (
Expand Down
89 changes: 77 additions & 12 deletions src/components/RetroList/ContentsList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useRecoilState } from 'recoil';
import { PatchRetrospectiveRequest } from '@/api/@types/Retrospectives';
import { patchRetrospective } from '@/api/retrospectivesApi/patchRetrospective';
import BookmarkIcon_N from '@/assets/BookmarkIcon_N.png';
import BookmarkIcon_Y from '@/assets/BookmarkIcon_Y.png';
import MoreIcon from '@/assets/MoreIcon.png';
Expand All @@ -9,6 +13,9 @@ import ProgressIng from '@/assets/Progress_Ing.png';
import TeamIcon from '@/assets/TeamIcon.png';
import Thumbnail from '@/assets/Thumbnail.png';
import Modal from '@/components/RetroList/Modal';
import UserNickname from '@/components/user/UserNickname';
import { useCustomToast } from '@/hooks/useCustomToast';
import { userNicknameState } from '@/recoil/user/userAtom';
import * as S from '@/styles/RetroList/ContentsList.styles';

interface Content {
Expand All @@ -29,10 +36,28 @@ interface ContentListProps {
data: Content[];
viewMode: string;
searchData: string;
setBookmarkUpdate: React.Dispatch<React.SetStateAction<boolean>>;
}

const ContentList: React.FC<ContentListProps> = ({ data, viewMode, searchData }) => {
const ContentList: React.FC<ContentListProps> = ({ data, viewMode, searchData, setBookmarkUpdate }) => {
// const [contentData, setContentData] = useState<Content[]>(data); 받아온데이터
const [userNickname, setUserNickname] = useRecoilState(userNicknameState);
const [openModalId, setOpenModalId] = useState<number | null>(null);
const toast = useCustomToast();

const handleBookmark = async (itemId: number) => {
try {
const requestData: PatchRetrospectiveRequest = {
retrospectiveId: itemId,
};
const response = await patchRetrospective(requestData);
console.log('북마크 patch 요청 완료', response);
setBookmarkUpdate(prev => !prev);
} catch (error) {
// console.error('북마크 patch 요청 실패:', error);
toast.error(error);
}
};

const openModalForItem = (itemId: number) => {
setOpenModalId(itemId);
Expand All @@ -43,6 +68,8 @@ const ContentList: React.FC<ContentListProps> = ({ data, viewMode, searchData })
};

const filteredData = data.filter(item => item.title.toLowerCase().includes(searchData.toLowerCase()));
console.log('filter', filteredData);
const navigate = useNavigate();

return (
<div>
Expand All @@ -57,16 +84,37 @@ const ContentList: React.FC<ContentListProps> = ({ data, viewMode, searchData })
<S.InfoBox>
<div style={{ display: 'flex', alignItems: 'center' }}>
<S.TeamIcon src={item.teamId ? TeamIcon : PersonalIcon} />
<S.RetroTitle>{item.title}</S.RetroTitle>
<S.RetroTitle onClick={() => navigate(`/section?retrospectiveId=${item.id}&teamId=${item.teamId}`)}>
{item.title}
</S.RetroTitle>
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<S.BookmarkIcon src={item.isBookmarked ? BookmarkIcon_Y : BookmarkIcon_N} /> {/* 북마크 patch */}
<S.MoreIcon src={MoreIcon} onClick={() => openModalForItem(item.id)} />
<S.BookmarkIcon
src={item.isBookmarked ? BookmarkIcon_Y : BookmarkIcon_N}
onClick={() => handleBookmark(item.id)}
/>
<S.MoreIcon
src={MoreIcon}
onClick={() => openModalForItem(item.id)}
// onClick={() => {
// if(유저아이디 !== item.id) { // 수정 권한 없을 때(생성자가 아닐 때)
// openModalForItem(item.id)
// } else {
// navigate(`/revise?retrospectiveId=${item.id}&teamId=${item.teamId}`);
// }
// }}
/>
</div>
<S.RetroUser>{item.userId}</S.RetroUser>
<S.RetroUser>
<UserNickname setUserNickname={setUserNickname} /> {/* 생성자 이름(유저 식별 필요) */}
{userNickname}
</S.RetroUser>
<div></div>
<S.RetroDate> {item.createdDate} 수정</S.RetroDate>
{/* 수정하면 수정 시각으로 변경*/}
<S.RetroDate>
{item.updatedDate && item.updatedDate !== item.startDate
? `${item.updatedDate} 수정`
: item.startDate}
</S.RetroDate>
<S.ProgressIcon
src={
item.status === 'NOT_STARTED'
Expand Down Expand Up @@ -96,15 +144,22 @@ const ContentList: React.FC<ContentListProps> = ({ data, viewMode, searchData })
<div>
{filteredData.map(item => (
<S.ItemBox key={item.id}>
<S.ListTitleBox> {item.title}</S.ListTitleBox>
<S.ListTitleBox onClick={() => navigate(`/section?retrospectiveId=${item.id}&teamId=${item.teamId}`)}>
{item.title}
</S.ListTitleBox>
<S.ListUserBox>
<text></text> {/* 생성자 이름 */}
<UserNickname setUserNickname={setUserNickname} /> {/* 생성자이름(유저 식별 필요) */}
{userNickname}
</S.ListUserBox>
<S.ListTimeBox>
{item.createdDate} {/* 수정하면 수정 시각으로 변경*/}
{item.updatedDate && item.updatedDate !== item.startDate ? `${item.updatedDate}` : item.startDate}
</S.ListTimeBox>
<S.ListBookmarkBox>
<S.Icon src={item.isBookmarked ? BookmarkIcon_Y : BookmarkIcon_N} />
<S.Icon
src={item.isBookmarked ? BookmarkIcon_Y : BookmarkIcon_N}
onClick={() => handleBookmark(item.id)}
/>
{/* 북마크 patch */}
</S.ListBookmarkBox>
<S.ListProgressBox>
<S.Icon
Expand All @@ -118,7 +173,17 @@ const ContentList: React.FC<ContentListProps> = ({ data, viewMode, searchData })
/>
</S.ListProgressBox>
<S.ListLinkBox>
<S.MoreIconListView src={MoreIcon} onClick={() => openModalForItem(item.id)} />
<S.MoreIconListView
src={MoreIcon}
onClick={() => openModalForItem(item.id)}
// onClick={() => {
// if(유저아이디 !== item.id) { // 수정 권한 없을 때(생성자가 아닐 때)
// openModalForItem(item.id)
// } else {
// navigate(`/revise?retrospectiveId=${item.id}&teamId=${item.teamId}`);
// }
// }}
/>
<Modal onClose={closeModalForItem} isOpen={openModalId === item.id} />
</S.ListLinkBox>
</S.ItemBox>
Expand Down
17 changes: 0 additions & 17 deletions src/components/RetroList/ControlBar.tsx

This file was deleted.

11 changes: 10 additions & 1 deletion src/components/RetroList/OrderButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import NewestIcon from '@/assets/Newest.png';
import OldestIcon from '@/assets/Oldest.png';
import * as S from '@/styles/RetroList/OrderButton.styles';

const OrderButton: React.FC = () => {
interface OrderButtonProps {
handleOrder: (option: 'NEWEST' | 'OLDEST') => void;
}

const OrderButton: React.FC<OrderButtonProps> = ({ handleOrder }) => {
const order = ['Newest', 'Oldest'];
const [isOpen, setIsOpen] = useState(false);
const [selectedOrder, setSelectedOrder] = useState(order[0]);
Expand All @@ -20,7 +24,12 @@ const OrderButton: React.FC = () => {
};

const handleOptionClick = (option: string) => {
const order: { [key: string]: string } = {
Newest: 'NEWEST',
Oldest: 'OLDEST',
};
setSelectedOrder(option);
handleOrder(order[option] as 'NEWEST' | 'OLDEST');
setIsOpen(false);
};

Expand Down
Loading
Loading