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]feat: follow 기능구현 중 #254

Merged
merged 1 commit into from
Sep 14, 2023
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
69 changes: 69 additions & 0 deletions client/src/components/Follow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { styled } from 'styled-components';
import { Icon } from '@iconify/react';
import { useState } from 'react';
import PropTypes from 'prop-types';

const FollowIconBox = styled.span`
background-color: white;
border-radius: 50%;
width: 40px;
height: 40px;
position: absolute;
bottom: 0;
right: 0;
cursor: pointer;

.follow-btn {
width: 40px;
height: 40px;
border: 0;
border-radius: 50%;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
}

.follow-icon {
width: 30px;
height: 30px;
color: red;
}
`;

const Follow = ({ handleFollowChange, handleUnFollowChange }) => {
const [selectedFollow, setSelectedFollow] = useState(false);

const handleFollowClick = () => {
setSelectedFollow(true);
};

const handleUnfollowClick = () => {
setSelectedFollow(false);
};

return (
<>
{!selectedFollow ? (
<FollowIconBox onClick={handleFollowClick}>
<button className="follow-btn" onClick={handleFollowChange}>
<Icon icon="mdi:heart-plus" className="follow-icon" />
</button>
</FollowIconBox>
) : (
<FollowIconBox onClick={handleUnfollowClick}>
<button className="follow-btn" onClick={handleUnFollowChange}>
<Icon icon="mdi:heart-minus" className="follow-icon" />
</button>
</FollowIconBox>
)}
</>
);
};

Follow.propTypes = {
handleFollowChange: PropTypes.func.isRequired,
handleUnFollowChange: PropTypes.func.isRequired,
};

export default Follow;
71 changes: 58 additions & 13 deletions client/src/components/Profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useState, useEffect } from 'react';
import axios from 'axios';
import Button from './Button';
import Modal from './Modal';
import Follow from './Follow';

const ProfileContainer = styled.div`
width: 76vw;
Expand Down Expand Up @@ -155,14 +156,17 @@ const BtnBox = styled.div`

const Profile = ({ user, setUser }) => {
const { email, gender, introduce, nickname, follower, following } = user;
const isLogin = useSelector((state) => state.auth.isLogin);

const [isIntroEditing, setIsIntroEditing] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [isImages, setisImages] = useState([]);
// const [isFollowing, setIsFollowing] = useState(0);

/* 함수에서 공통으로 사용할 데이터 */
const token = localStorage.getItem('jwtToken');
const myId = JSON.parse(useSelector((state) => state.user.myId));
const isLogin = useSelector((state) => state.auth.isLogin);
const toMemberId = useSelector((state) => state.user.memberId);

const patchData = {
introduce,
Expand Down Expand Up @@ -197,8 +201,6 @@ const Profile = ({ user, setUser }) => {
if (token) {
try {
const imageUrl = e.target.currentSrc; // 클릭한 이미지의 URL 가져오기

// 서버에 이미지 업로드 요청을 보냅니다.
const response = await axios.patch(
`http://3.39.76.109:8080/members/${myId}`,
{ imageUrl }, // 이미지 URL을 보냅니다.
Expand All @@ -208,14 +210,8 @@ const Profile = ({ user, setUser }) => {
},
},
);

// 서버에서 업로드된 이미지의 URL을 받아옵니다.
const newImageUrl = response.data.imageUrl;

// 이미지 URL을 state에 업데이트합니다.
setUser({ ...user, imageUrl: newImageUrl }); // imageUrl 업데이트

// 모달을 닫습니다.
closeModal();

console.log('프로필 이미지 업로드 성공');
Expand Down Expand Up @@ -260,6 +256,53 @@ const Profile = ({ user, setUser }) => {
}
};

/* 팔로잉, 언팔로잉 */
const followData = {
following,
follower,
};

const handleFollowChange = async () => {
if (token) {
try {
const response = await axios.post(
`http://3.39.76.109:8080/follows/${toMemberId}`,
followData,
{
headers: {
Authorization: token,
},
},
);
console.log('POST 요청 성공!', response.data);
} catch (error) {
console.log('PATCH 요청 실패!', error);
}
} else {
console.error('토큰이 없으므로 PATCH 요청을 보낼 수 없습니다.');
}
};

const handleUnFollowChange = async () => {
if (token) {
try {
const response = await axios.delete(
`http://3.39.76.109:8080/follows/${toMemberId}`,
{
headers: {
Authorization: token,
},
},
);
console.log('DELETE 요청 성공!', response.data);
} catch (error) {
console.log('PATCH 요청 실패!', error);
}
} else {
console.error('토큰이 없으므로 PATCH 요청을 보낼 수 없습니다.');
}
};

return (
<ProfileContainer>
{isLogin ? (
Expand All @@ -268,7 +311,12 @@ const Profile = ({ user, setUser }) => {
<EditIconBox onClick={openModal}>
<Icon className="edit-icon" icon="uil:edit" color="#9669f7" />
</EditIconBox>
) : null}
) : (
<Follow
handleFollowChange={handleFollowChange}
handleUnFollowChange={handleUnFollowChange}
/>
)}

{user.imageUrl ? (
<img
Expand All @@ -282,9 +330,6 @@ const Profile = ({ user, setUser }) => {
</AvatarContainer>
) : (
<AvatarContainer>
<EditIconBox onClick={openModal}>
<Icon className="edit-icon" icon="uil:edit" color="#9669f7" />
</EditIconBox>
<Icon icon="mingcute:ghost-line" className="avatar-img" />
</AvatarContainer>
)}
Expand Down
1 change: 0 additions & 1 deletion client/src/pages/MyPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ const MyPage = () => {
applicants: myInfo.applicants,
boardLikes: myInfo.boardLikes,
};
console.log(userData);
setUser(userData);
} catch (error) {
console.error(error);
Expand Down
2 changes: 1 addition & 1 deletion client/src/redux/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { combineReducers } from 'redux';
const initialState = {
isLogin: false,
token: null,
userId: 0,
memberId: 0,
myId: 0,
isNew: false,
};
Expand Down