Skip to content
Draft
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
1 change: 1 addition & 0 deletions GapLog-Client
Submodule GapLog-Client added at c003b4
4 changes: 2 additions & 2 deletions src/components/bars/MyPageBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ function MyPageBar() {
<Wrapper>
<nav>
{/* 임시 url */}
<NavItem to="/mypage" exact>
<NavItem to="/mypage/main" exact>
개요
</NavItem>
<NavItem to="/mypage/post">게시글</NavItem>
<NavItem to="/mypage/scrab">스크랩</NavItem>
<NavItem to="/mypage/scrap">스크랩</NavItem>
<NavItem to="/mypage/comment">댓글</NavItem>
</nav>
</Wrapper>
Expand Down
7 changes: 5 additions & 2 deletions src/components/bars/TitleBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const MenuItem = styled.div`
`;

function TitleBar(props) {
const { user, isLoggedIn, setUser } = useUser();
const { user, isLoggedIn, setUser, setIsLoggedIn } = useUser();
const [isProfileMenuOpen, setIsProfileMenuOpen] = useState(false);
const [isDMModalOpen, setIsDMModalOpen] = useState(false);
const [isLoginModalOpen, setIsLoginModalOpen] = useState(false); // 로그인 모달 상태
Expand Down Expand Up @@ -114,7 +114,7 @@ function TitleBar(props) {

// 사용자 상태를 null로 설정
setUser(null);

setIsLoggedIn(false);
// 홈 페이지로 리디렉션
nav('/');
} catch (error) {
Expand All @@ -140,6 +140,9 @@ function TitleBar(props) {

{isProfileMenuOpen && (
<ProfileMenu>
<MenuItem onClick={() => nav('/mypage/main')}>
마이페이지
</MenuItem>
<MenuItem onClick={handleLogout}>로그아웃</MenuItem>
<MenuItem onClick={() => nav('/settings')}>설정</MenuItem>
</ProfileMenu>
Expand Down
36 changes: 35 additions & 1 deletion src/components/comment/CommentItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,35 @@ const HideButton = styled.button`
`;

function CommentItem({ comment, hasReplies, onToggleHide }) {
const [isLiked, setIsLiked] = useState(comment.isLiked);

const toggleLike = async () => {
try {
const accessToken = localStorage.getItem('accessToken');
const response = await fetch(
`http://3.37.43.129/api/comments/${comment.id}/like`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
},
}
);

if (!response.ok) {
throw new Error('Failed to toggle like');
}

const data = await response.json(); // API로부터 반환된 데이터

// 상태 업데이트
setIsLiked(data.isLiked); // boolean 값 업데이트
} catch (error) {
console.error(error);
}
};

return (
<Container>
<ProfileImg>
Expand All @@ -87,7 +116,12 @@ function CommentItem({ comment, hasReplies, onToggleHide }) {
<MainText>{comment.content}</MainText>
<IconWrapper>
<FiMessageCircle size="24" />
<FiHeart size="24" />
<div
onClick={toggleLike}
style={{ cursor: 'pointer', color: isLiked ? '#ff4081' : '#767676' }}
>
<FiHeart size="24" />
</div>
{hasReplies && (
<HideButton onClick={onToggleHide}>
{comment.isHidden ? '댓글 보기' : '댓글 숨기기'}
Expand Down
32 changes: 27 additions & 5 deletions src/components/user/FollowItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,39 @@ const UserBio = styled.div`
margin-right: 830px;
`;

function FollowItem() {
function FollowItem({ props }) {
const { followeeId } = props;
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchUser = async () => {
const response = await fetch(
`http://3.37.43.129/api/users/${followeeId}`
);
if (response.ok) {
const data = await response.json();
setUser(data);
}
setLoading(false);
};

fetchUser();
}, [followeeId]);

if (loading) return <div>Loading...</div>;
if (!user) return null;

return (
<Container>
<ProfileImg>
<img alt="profile" />
<img src={user.profileImage} alt="profile" />
</ProfileImg>
<UserInfo>
<UserNickname>나는다연</UserNickname>
<UserId>@hongdari</UserId>
<UserNickname>{user.nickName}</UserNickname>
<UserId>{user.userId}</UserId>
</UserInfo>
<UserBio>안녕하시소</UserBio>
<UserBio>{user.introduce}</UserBio>
<Button title="팔로우" className="green" />
</Container>
);
Expand Down
57 changes: 56 additions & 1 deletion src/components/user/FollowerList.jsx
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
//mypage에서 보여질 user의 follower list 컴포넌트
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import FollowItem from './FollowItem';

// Post Item을 그리드 형식으로 출력
const Container = styled.div`
display: flex;
justify-content: center;
`;

const Wrapper = styled.div`
display: grid;
grid-template-rows: repeat(auto-fill, minmax(60px, 1fr)); // 세로로 나열
gap: 16px;
justify-items: center;
height: auto; // 콘텐츠에 맞게 높이 자동 조정
`;

function FollowerList({ props }) {
const { userId } = props;
const [follower, setFollower] = useState([]);

useEffect(() => {
const fetchFollower = async () => {
try {
const response = await fetch(
`http://3.37.43.129/api/user/${userId}/followers`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
}
);
const data = await response.json();
setFollower(data);
} catch (error) {
console.error('Error fetching follower list:', error);
}
};

fetchFollower();
}, []);

return (
<Container>
<Wrapper>
{follower.map((user) => (
<FollowItem key={user.id} userId={follower.followerId} />
))}
</Wrapper>
</Container>
);
}

export default FollowerList;
55 changes: 55 additions & 0 deletions src/components/user/FollowingList.jsx
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
//mypage에서 보여질 user의 following list 컴포넌트
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import FollowItem from './FollowItem';

const Container = styled.div`
display: flex;
justify-content: center;
`;

const Wrapper = styled.div`
display: grid;
grid-template-rows: repeat(auto-fill, minmax(60px, 1fr));
gap: 16px;
justify-items: center;
height: auto;
`;

function FollowingList({ props }) {
const { userId } = props;
const [following, setFollowing] = useState([]);

useEffect(() => {
const fetchFollowing = async () => {
try {
const response = await fetch(
`http://3.37.43.129/api/user/${userId}/followees`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
}
);
const data = await response.json();
setFollowing(data);
} catch (error) {
console.error('Error fetching following list:', error);
}
};

fetchFollowing();
}, []);

return (
<Container>
<Wrapper>
{following.map((user) => (
<FollowItem key={user.id} userId={following.followeeId} />
))}
</Wrapper>
</Container>
);
}

export default FollowingList;
4 changes: 3 additions & 1 deletion src/components/user/Wandubat.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,14 @@ function Wandubat(props) {
useEffect(() => {
const fetchWandu = async () => {
try {
const accessToken = localStorage.getItem('accessToken');
const response = await fetch(
`http://3.37.43.129/api/user/${userId}/seriousness/seriousness-field`,
`http://3.37.43.129/api/user/seriousness/seriousness-field`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
},
}
);
Expand Down
55 changes: 38 additions & 17 deletions src/pages/FollowListPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import TitleBar from '../components/bars/TitleBar';
import FollowItem from '../components/user/FollowItem';
import FollowingList from '../components/user/FollowingList';
import FollowerList from '../components/user/FollowerList';

const Container = styled.div`
width: calc(100% - 32px);
Expand Down Expand Up @@ -56,22 +57,42 @@ const TitleWrapper = styled.div`
}
`;

function FollowListPage() {
return (
<Container>
<TitleBar />
<UserWrapper>
<ProfileImg>
<img alt="profile" />
</ProfileImg>
<UserId>jinji123의 팔로워</UserId>
</UserWrapper>
<TitleWrapper>
<TitleWrapper className="count">20명</TitleWrapper>의 팔로워
</TitleWrapper>
<FollowItem></FollowItem>
</Container>
);
function FollowListPage({ props }) {
const { userId, title } = props;

if (title == 'following') {
return (
<Container>
<TitleBar />
<UserWrapper>
<ProfileImg>
<img alt="profile" />
</ProfileImg>
<UserId>jinji123의 팔로워</UserId>
</UserWrapper>
<TitleWrapper>
<TitleWrapper className="count">20명</TitleWrapper>의 팔로워
</TitleWrapper>
<FollowingList userId={userId} />
</Container>
);
} else {
return (
<Container>
<TitleBar />
<UserWrapper>
<ProfileImg>
<img alt="profile" />
</ProfileImg>
<UserId>jinji123의 팔로워</UserId>
</UserWrapper>
<TitleWrapper>
<TitleWrapper className="count">20명</TitleWrapper>의 팔로워
</TitleWrapper>
<FollowerList userId={userId} />
</Container>
);
}
}

export default FollowListPage;
21 changes: 19 additions & 2 deletions src/pages/LoginAlertPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,31 @@ const LoginAlertPage = ({ isOpen, onClose }) => {
}

const data = await response.json();
console.log(data);
const token = data.accessToken;

// JWT 토큰을 로컬 스토리지에 저장
localStorage.setItem('accessToken', token);
setIsLoggedIn(true);

const userResponse = await fetch('http://3.37.43.129/api/user', {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`, // access token을 Authorization 헤더에 추가
},
});

if (!userResponse.ok) {
throw new Error('Failed to retrieve user information');
}

const userData = await userResponse.json();
console.log(userData);

// 사용자 정보를 상태에 저장
setUser(userData);
setIsLoggedIn(true);
// 사용자 대시보드로 리디렉션
navigate('/mypage');
navigate('/');
} catch (error) {
setError(error.message);
}
Expand Down
Loading