From 4b1e847e6e06a514f2d585a2cb6c33302db9d697 Mon Sep 17 00:00:00 2001 From: jaeyo03 Date: Fri, 7 Feb 2025 15:12:27 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix=20:=20=ED=8C=8C=EC=9D=BC=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/MyPage/components/aside/Aside.jsx | 2 +- .../components/userfollower/UserFollow.jsx | 147 ++++++++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 src/pages/MyPage/components/userfollower/UserFollow.jsx diff --git a/src/pages/MyPage/components/aside/Aside.jsx b/src/pages/MyPage/components/aside/Aside.jsx index 75de1b8..38c2bfb 100644 --- a/src/pages/MyPage/components/aside/Aside.jsx +++ b/src/pages/MyPage/components/aside/Aside.jsx @@ -10,8 +10,8 @@ import { useSelector } from 'react-redux'; import { useQuery } from '@tanstack/react-query'; import { useState } from 'react'; +import UserFollow from '../userfollower/UserFollow.jsx'; import { getUserApi } from '@/apis/userApi'; -import UserFollow from '../userfollower/UserFollow'; const Aside = () => { const { userId, userFullName } = useSelector(state => state.user); diff --git a/src/pages/MyPage/components/userfollower/UserFollow.jsx b/src/pages/MyPage/components/userfollower/UserFollow.jsx new file mode 100644 index 0000000..d514360 --- /dev/null +++ b/src/pages/MyPage/components/userfollower/UserFollow.jsx @@ -0,0 +1,147 @@ +import PropTypes from 'prop-types'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { useState } from 'react'; +import { followUser, unfollowUser } from '@/apis/followApi'; +import FollowingTab from './followingTab/FollowingTab'; +import FollowerTab from './followerTab/FollowerTab'; +import { getUserApi } from '@/apis/userApi'; + +const UserFollow = ({ isOpen, closeModal, userData, userName }) => { + const [tapMenu, setTapMenu] = useState('follower'); + const queryClient = useQueryClient(); + + const { data: followerData } = useQuery({ + queryKey: ['followers', userData?.followers], + queryFn: async () => { + if (!userData?.followers) return []; + return Promise.all( + userData.followers.map(async element => { + const followerUser = await getUserApi(element.follower); + + return { + _id: followerUser._id, + fullName: followerUser.fullName, + image: followerUser.image, + followerForFollower: false, + }; + }), + ); + }, + }); + + const { data: followingData } = useQuery({ + queryKey: ['followings', userData?.following], + queryFn: async () => { + if (!userData?.following) return []; + return Promise.all( + userData.following.map(async element => { + const followingUser = await getUserApi(element.user); + return { + id: followingUser._id, + image: followingUser.image, + fullName: followingUser.fullName, + following_ID: element._id, + user_ID: followingUser._id, + }; + }), + ); + }, + }); + + const { mutate: unfollowHandler } = useMutation({ + mutationFn: async userId => { + await unfollowUser(userId); + }, + onSuccess: () => { + queryClient.invalidateQueries(['followings', userData?.following]); + }, + onError: error => { + console.error('언팔로우 실패:', error); + alert('언팔로우 요청이 실패했습니다. 다시 시도해주세요.'); + }, + }); + + const unfollowUserHandler = userId => { + const isChecked = window.confirm('정말로 언팔하시겠습니까?'); + + if (isChecked) { + unfollowHandler(userId); + } + }; + + const { mutate: followHandler } = useMutation({ + mutationFn: async userId => { + await followUser(userId); + }, + onSuccess: () => { + queryClient.invalidateQueries(['followers', userData?.followers]); + }, + }); + + if (!isOpen) return null; + + return ( +
+
e.stopPropagation()} + > +
+ 닫기 아이콘 +
+
+

{userName}

+
+
setTapMenu('follower')} + > + 팔로워 {userData?.followers.length} +
+
setTapMenu('following')} + > + 팔로잉 {userData?.following.length} +
+
+ +
+ {tapMenu === 'follower' ? ( + + ) : ( + + )} +
+
+
+
+ ); +}; + +UserFollow.propTypes = { + isOpen: PropTypes.bool.isRequired, + closeModal: PropTypes.func.isRequired, + userData: PropTypes.shape({ + followers: PropTypes.array, + following: PropTypes.array, + }), + userName: PropTypes.string, +}; + +export default UserFollow; From f473d3168ec7b20927afb368b71643018b2bb680 Mon Sep 17 00:00:00 2001 From: jaeyo03 Date: Fri, 7 Feb 2025 15:12:36 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix=20:=20=EB=9D=BC=EC=9A=B0=ED=84=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/SearchPage/index.jsx | 115 +++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/src/pages/SearchPage/index.jsx b/src/pages/SearchPage/index.jsx index fe57871..b7a885a 100644 --- a/src/pages/SearchPage/index.jsx +++ b/src/pages/SearchPage/index.jsx @@ -158,64 +158,82 @@ const SearchPage = () => { setLayout(layouticon); }; - const handleCardClick = contentId => { - navigate(`/detail/${contentId}`); // 상세 페이지로 이동 - window.scrollTo(0, 0); - }; - const renderCard = item => { switch (layout) { case 'large-layout': return ( - handleCardClick(item.contentsid)} - title={item.title || '제목이 없습니다'} - city={item.region1cd?.label || '도시'} - street={ - item.region2cd?.label == 'region>' || item.region2cd?.label == undefined - ? '제주시내' - : item.region2cd?.label - } - description={item.introduction || '설명이 없습니다.'} - img={item.repPhoto?.photoid?.thumbnailpath || '/images/no_image.svg'} - contentid={item} - /> + ); case 'medium-layout': return ( - handleCardClick(item.contentsid)} - title={item.title || '제목이 없습니다'} - city={item.region1cd?.label || '도시'} - street={ - item.region2cd?.label == 'region>' || item.region2cd?.label == undefined - ? '제주시내' - : item.region2cd?.label - } - img={item.repPhoto?.photoid?.thumbnailpath || '/images/no_image.svg'} - category={item.contentscd?.value} - contentid={item} - /> + ); case 'small-layout': return ( - handleCardClick(item.contentsid)} - title={item.title || '제목이 없습니다'} - city={item.region1cd?.label || '도시'} - street={ - item.region2cd?.label == 'region>' || item.region2cd?.label == undefined - ? '제주시내' - : item.region2cd?.label - } - description={item.introduction || '설명이 없습니다.'} - img={item.repPhoto?.photoid?.thumbnailpath || '/images/no_image.svg'} - category={item.contentscd?.value} - contentid={item} - /> + ); default: return null; @@ -312,7 +330,6 @@ const SearchPage = () => {
{isLoading ? ( - // ) : (
From 9127b3629b5de8bea54058cb8b9fda4765e2d927 Mon Sep 17 00:00:00 2001 From: jaeyo03 Date: Fri, 7 Feb 2025 15:13:38 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Revert=20"fix=20:=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=84=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit f473d3168ec7b20927afb368b71643018b2bb680. --- src/pages/SearchPage/index.jsx | 115 ++++++++++++++------------------- 1 file changed, 49 insertions(+), 66 deletions(-) diff --git a/src/pages/SearchPage/index.jsx b/src/pages/SearchPage/index.jsx index b7a885a..fe57871 100644 --- a/src/pages/SearchPage/index.jsx +++ b/src/pages/SearchPage/index.jsx @@ -158,82 +158,64 @@ const SearchPage = () => { setLayout(layouticon); }; + const handleCardClick = contentId => { + navigate(`/detail/${contentId}`); // 상세 페이지로 이동 + window.scrollTo(0, 0); + }; + const renderCard = item => { switch (layout) { case 'large-layout': return ( - + handleCardClick(item.contentsid)} + title={item.title || '제목이 없습니다'} + city={item.region1cd?.label || '도시'} + street={ + item.region2cd?.label == 'region>' || item.region2cd?.label == undefined + ? '제주시내' + : item.region2cd?.label + } + description={item.introduction || '설명이 없습니다.'} + img={item.repPhoto?.photoid?.thumbnailpath || '/images/no_image.svg'} + contentid={item} + /> ); case 'medium-layout': return ( - + handleCardClick(item.contentsid)} + title={item.title || '제목이 없습니다'} + city={item.region1cd?.label || '도시'} + street={ + item.region2cd?.label == 'region>' || item.region2cd?.label == undefined + ? '제주시내' + : item.region2cd?.label + } + img={item.repPhoto?.photoid?.thumbnailpath || '/images/no_image.svg'} + category={item.contentscd?.value} + contentid={item} + /> ); case 'small-layout': return ( - + handleCardClick(item.contentsid)} + title={item.title || '제목이 없습니다'} + city={item.region1cd?.label || '도시'} + street={ + item.region2cd?.label == 'region>' || item.region2cd?.label == undefined + ? '제주시내' + : item.region2cd?.label + } + description={item.introduction || '설명이 없습니다.'} + img={item.repPhoto?.photoid?.thumbnailpath || '/images/no_image.svg'} + category={item.contentscd?.value} + contentid={item} + /> ); default: return null; @@ -330,6 +312,7 @@ const SearchPage = () => {
{isLoading ? ( + // ) : (