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

[Feat/#126] post auth check #127

Merged
merged 14 commits into from
Jan 17, 2024
7 changes: 5 additions & 2 deletions src/assets/svgs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { default as DefaultProfileIc } from './defaultProfileIc.svg?react';
export { default as DetailCommentMeatBallIc } from './detailCommentMeatBallIc.svg?react';
export { default as EditorTextColorIcnBlackSvg } from './editorTextcolorIcnBlack.svg?react';

export { default as HeaderLogoSvg } from './headerLogoSvg.svg?react';
export { default as MainGroupRoutingBtn } from './mainGroupRoutingBtn.svg?react';
export { default as MainGroupRoutingBtnHover } from './mainGroupRoutingBtnHover.svg?react';
Expand Down Expand Up @@ -52,7 +53,9 @@ export { default as EditorDropIcnActiveIc } from './editorDropIcnActive.svg?reac
export { default as EditorDropIcnActiveOpenIc } from './editorDropIcnActiveopen.svg?react';
export { default as GroupThumnailImgIc } from './groupThumnailImg.svg?react';

export {
default as EditorThuminputIcnActiveIc,
default as EditorThuminputIcnHoverIc,
} from './editorThuminputIcnHover.svg?react';
export { default as EditorThuminputIcnUnactiveIc } from './editorThuminputIcnUnactive.svg?react';
export { default as EditorThuminputIcnHoverIc } from './editorThuminputIcnHover.svg?react';
export { default as EditorThuminputIcnActiveIc } from './editorThuminputIcnHover.svg?react';
export { default as GroupCardThumnailImgIc } from './groupCardThumnailImg.svg';
2 changes: 1 addition & 1 deletion src/pages/groupFeed/carousel/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import styled from '@emotion/styled';
import { Dispatch, SetStateAction } from 'react';
import Slider from 'react-slick';

import CarouselContainer from './CarouselContainer';
import './slick-theme.css';
import './slick.css';
import CarouselContainer from './CarouselContainer';

import { useTopicList } from '../hooks/queries';

Expand Down
8 changes: 4 additions & 4 deletions src/pages/groupFeed/hooks/queries.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useQuery } from '@tanstack/react-query';

import {
fetchGroupFeedAuth,
fetchCuriousPost,
fetchTopicList,
fetchTodayTopic,
fetchGroupInfo,
fetchCuriousWriters,
fetchGroupFeedAuth,
fetchGroupInfo,
fetchTodayTopic,
fetchTopicList,
} from '../apis/fetchGroupFeed';

export const QUERY_KEY_GROUPFEED = {
Expand Down
16 changes: 11 additions & 5 deletions src/pages/postDetail/PostDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useNavigate, useParams } from 'react-router-dom';

import Comment from './components/Comment';
import CuriousBtn from './components/CuriousBtn';
import { useGetPostDetail } from './hooks/queries';
import { useCheckPostAuth, useGetPostDetail } from './hooks/queries';

import MakeGroupBtn from '../groupFeed/components/MakeGroupBtn';
import MyGroupBtn from '../groupFeed/components/MyGroupBtn';
Expand All @@ -19,6 +19,7 @@ const PostDetail = () => {
const { postId } = useParams();

const { data, isError, isLoading } = useGetPostDetail(postId || '');
const { data: postAuth } = useCheckPostAuth(postId || '');

const postData = data?.data;
if (isError) {
Expand All @@ -27,6 +28,7 @@ const PostDetail = () => {
if (isLoading) {
<div>Loading~</div>;
}

// 리팩토링 전 코드
// useEffect(() => {
// if (typeof postId === 'string') {
Expand Down Expand Up @@ -59,10 +61,12 @@ const PostDetail = () => {
<TitleText>{postData?.title}</TitleText>
<DateText>{postData?.createdAt}</DateText>
</InfoTextBox>
<ButtonWrapper>
<Button typeName={'deleteTempType'}>글 삭제하기</Button>
<Button typeName={'submitEditType'}>글 수정하기</Button>
</ButtonWrapper>
{postAuth?.data?.data.canEdit && (
<ButtonWrapper>
<Button typeName={'deleteTempType'}>글 삭제하기</Button>
<Button typeName={'submitEditType'}>글 수정하기</Button>
</ButtonWrapper>
)}
</PostDetailContainer>
<PostWrapper>
<TopicWrapper>
Expand Down Expand Up @@ -144,6 +148,7 @@ const InfoTextBox = styled.div`
display: flex;
flex-direction: column;
gap: 1.1rem;
width: 60rem;
`;

const TitleText = styled.h1`
Expand All @@ -160,6 +165,7 @@ const ButtonWrapper = styled.div`
display: flex;
gap: 1.2rem;
align-items: flex-start;
width: 21rem;
`;

const TopicWrapper = styled.div`
Expand Down
24 changes: 24 additions & 0 deletions src/pages/postDetail/apis/checkPostAuth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { client } from '../../../utils/apis/axios';

interface CheckPostAuth {
status: number;
message: string;
data: {
canEdit: boolean;
};
}
const checkPostAuth = (postId: string) => {
const token = localStorage.getItem('accessToken');
try {
const data = client.get<CheckPostAuth>(`/api/post/${postId}/authenticate`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return data;
} catch (err) {
console.log(err);
}
};

export default checkPostAuth;
4 changes: 2 additions & 2 deletions src/pages/postDetail/apis/createPostCurious.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { client } from '../../../utils/apis/axios';

interface PostCuriousResponseType {
status: string;
status: number;
message: string;
data: {
isCurious: boolean;
Expand All @@ -12,7 +12,7 @@ const createPostCurious = async (postId: string) => {
try {
const token = localStorage.getItem('accessToken');
const { data } = await client.post<PostCuriousResponseType>(
`api/post/${postId}/curious`,
`/api/post/${postId}/curious`,
{},
{
headers: {
Expand Down
24 changes: 24 additions & 0 deletions src/pages/postDetail/apis/deleteCurious.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { client } from '../../../utils/apis/axios';

interface DeleteResponseType {
status: number;
message: string;
data: {
isCurious: boolean;
};
}
const deleteCurious = async (postId: string) => {
const token = localStorage.getItem('accessToken');
try {
const data = client.delete<DeleteResponseType>(`/api/post/${postId}/curious`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return data;
} catch (err) {
console.log(err);
}
};

export default deleteCurious;
20 changes: 16 additions & 4 deletions src/pages/postDetail/components/CuriousBtn.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';

import { useGetCuriousInfo, usePostCurious } from '../hooks/queries';
import { useDeleteCurious, useGetCuriousInfo, usePostCurious } from '../hooks/queries';

import { DetailPurpleFavoriteIc, DetailWhiteFavoriteIc } from './../../../assets/svgs';

const CuriousBtn = () => {
const [isClick, setIsClick] = useState(false);
const { postId } = useParams();
const { data } = useGetCuriousInfo(postId || '');

const { mutate: postCurious } = usePostCurious(postId || '');
const { mutate: deleteCurious } = useDeleteCurious(postId || ' ');
const isCurious = data?.data?.isCurious;
const [isClick, setIsClick] = useState(!!isCurious);

const handleBtnClick = () => {
if (isClick) {
deleteCurious();
} else {
postCurious();
}
setIsClick((prev) => !prev);
postCurious();
};

useEffect(() => {
setIsClick(!!data?.data?.isCurious);
}, [data?.data?.isCurious]);
return (
<>
<CuriousBtnWrapper onClick={handleBtnClick} $isClick={isClick}>
Expand Down
32 changes: 28 additions & 4 deletions src/pages/postDetail/hooks/queries.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//한 파일에서 사용하는 쿼리키를 모아두고 쿼리를 선언해주세요

import { useMutation, useQuery } from '@tanstack/react-query';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';

import checkPostAuth from '../apis/checkPostAuth';
import createPostCurious from '../apis/createPostCurious';
import deleteCurious from '../apis/deleteCurious';
import fetchCuriousInfo from '../apis/fetchCuriousInfo';
import fetchPostDetail from '../apis/fetchPostDetail';

//쿼리키를 이렇게 두는 이유는 겹치지 않기위해 + 객체로 생성하여 자동완성 하기 위해
export const QUERY_KEY_POST_DETAIL = {
getPostDetail: 'getPostDetail',
Expand All @@ -22,7 +23,7 @@ export const QUERY_KEY_POST_DETAIL = {
// 글정보 조회 get api
export const useGetPostDetail = (postId: string) => {
const data = useQuery({
queryKey: [QUERY_KEY_POST_DETAIL.getPostDetail],
queryKey: [QUERY_KEY_POST_DETAIL.getPostDetail, postId],
queryFn: () => fetchPostDetail(postId),
});

Expand All @@ -40,12 +41,35 @@ export const useGetCuriousInfo = (postId: string) => {

//궁금해요 생성 api
export const usePostCurious = (postId: string) => {
const queryClient = useQueryClient();
const data = useMutation({
mutationKey: [QUERY_KEY_POST_DETAIL.postCurious],
mutationFn: () => createPostCurious(postId),
onSuccess: () => {
console.log('post curious Success');
queryClient.invalidateQueries({ queryKey: [QUERY_KEY_POST_DETAIL.getCurious, postId] });
},
});
return data;
};

//궁금해요 삭제 api
export const useDeleteCurious = (postId: string) => {
const queryClient = useQueryClient();
const data = useMutation({
mutationKey: [QUERY_KEY_POST_DETAIL.deleteCurious, postId],
mutationFn: () => deleteCurious(postId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEY_POST_DETAIL.getCurious, postId] });
},
});
return data;
};

//글 삭제/수정 권한 확인
export const useCheckPostAuth = (postId: string) => {
const data = useQuery({
queryKey: [QUERY_KEY_POST_DETAIL.getAuthorization, postId],
queryFn: () => checkPostAuth(postId),
});
return data;
};