diff --git a/src/assets/svgs/index.tsx b/src/assets/svgs/index.tsx index 4f10b3df..c1e6592a 100644 --- a/src/assets/svgs/index.tsx +++ b/src/assets/svgs/index.tsx @@ -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'; @@ -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'; diff --git a/src/pages/groupFeed/carousel/Carousel.tsx b/src/pages/groupFeed/carousel/Carousel.tsx index b0e07e77..2b16ea10 100644 --- a/src/pages/groupFeed/carousel/Carousel.tsx +++ b/src/pages/groupFeed/carousel/Carousel.tsx @@ -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'; diff --git a/src/pages/groupFeed/hooks/queries.ts b/src/pages/groupFeed/hooks/queries.ts index d38851d7..1deab9f0 100644 --- a/src/pages/groupFeed/hooks/queries.ts +++ b/src/pages/groupFeed/hooks/queries.ts @@ -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 = { diff --git a/src/pages/postDetail/PostDetail.tsx b/src/pages/postDetail/PostDetail.tsx index d269928e..0a35eea4 100644 --- a/src/pages/postDetail/PostDetail.tsx +++ b/src/pages/postDetail/PostDetail.tsx @@ -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'; @@ -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) { @@ -27,6 +28,7 @@ const PostDetail = () => { if (isLoading) {
Loading~
; } + // 리팩토링 전 코드 // useEffect(() => { // if (typeof postId === 'string') { @@ -59,10 +61,12 @@ const PostDetail = () => { {postData?.title} {postData?.createdAt} - - - - + {postAuth?.data?.data.canEdit && ( + + + + + )} @@ -144,6 +148,7 @@ const InfoTextBox = styled.div` display: flex; flex-direction: column; gap: 1.1rem; + width: 60rem; `; const TitleText = styled.h1` @@ -160,6 +165,7 @@ const ButtonWrapper = styled.div` display: flex; gap: 1.2rem; align-items: flex-start; + width: 21rem; `; const TopicWrapper = styled.div` diff --git a/src/pages/postDetail/apis/checkPostAuth.ts b/src/pages/postDetail/apis/checkPostAuth.ts new file mode 100644 index 00000000..f75a51e2 --- /dev/null +++ b/src/pages/postDetail/apis/checkPostAuth.ts @@ -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(`/api/post/${postId}/authenticate`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + return data; + } catch (err) { + console.log(err); + } +}; + +export default checkPostAuth; diff --git a/src/pages/postDetail/apis/createPostCurious.ts b/src/pages/postDetail/apis/createPostCurious.ts index 3190cdf5..90601b87 100644 --- a/src/pages/postDetail/apis/createPostCurious.ts +++ b/src/pages/postDetail/apis/createPostCurious.ts @@ -1,7 +1,7 @@ import { client } from '../../../utils/apis/axios'; interface PostCuriousResponseType { - status: string; + status: number; message: string; data: { isCurious: boolean; @@ -12,7 +12,7 @@ const createPostCurious = async (postId: string) => { try { const token = localStorage.getItem('accessToken'); const { data } = await client.post( - `api/post/${postId}/curious`, + `/api/post/${postId}/curious`, {}, { headers: { diff --git a/src/pages/postDetail/apis/deleteCurious.ts b/src/pages/postDetail/apis/deleteCurious.ts new file mode 100644 index 00000000..e66da0ee --- /dev/null +++ b/src/pages/postDetail/apis/deleteCurious.ts @@ -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(`/api/post/${postId}/curious`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + return data; + } catch (err) { + console.log(err); + } +}; + +export default deleteCurious; diff --git a/src/pages/postDetail/components/CuriousBtn.tsx b/src/pages/postDetail/components/CuriousBtn.tsx index e7e5a864..141b20e9 100644 --- a/src/pages/postDetail/components/CuriousBtn.tsx +++ b/src/pages/postDetail/components/CuriousBtn.tsx @@ -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 ( <> diff --git a/src/pages/postDetail/hooks/queries.ts b/src/pages/postDetail/hooks/queries.ts index ca409185..7d5ac982 100644 --- a/src/pages/postDetail/hooks/queries.ts +++ b/src/pages/postDetail/hooks/queries.ts @@ -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', @@ -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), }); @@ -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; +};