Skip to content
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
3 changes: 1 addition & 2 deletions src/apis/post/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ export interface GetPostListData {
meta: PaginationMeta;
}
export interface UserPostSummary {
userId: number;
postId: number;
id: number;
createdAt: Date;
imageUrl: string;
postLikesCount: number;
Expand Down
4 changes: 2 additions & 2 deletions src/components/PostItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ const PostItem: React.FC<PostItemProps> = ({ post, isMyPost = true }) => {
const imageUrl = post.imageUrl;

const handleClick = () => {
const path = isMyPost ? `/my-post/${post.postId}` : `/post/${post.postId}`;
const path = isMyPost ? `/my-post/${post.id}` : `/post/${post.id}`;
navigate(path);
};

return (
<PostItemContainer onClick={handleClick}>
<PostImageContainer>
<PostImage src={imageUrl} alt={`post-${post.postId}`} />
<PostImage src={imageUrl} alt={`post-${post.id}`} />
{post.isRepresentative && <PinSvg src={PinIcon} />}
<LikesOverlay>
<Icon src={HeartSvg} alt="heart icon" />
Expand Down
287 changes: 141 additions & 146 deletions src/pages/MyPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import {
ProfileContainer,
Header,
StatsContainer,
Stat,
StatNumber,
StatLabel,
PostsContainer,
AddButton,
NoPostWrapper,
} from "./styles";
ProfileContainer,
Header,
StatsContainer,
Stat,
StatNumber,
StatLabel,
PostsContainer,
AddButton,
NoPostWrapper,
} from './styles';
import { OODDFrame } from '../../components/Frame/Frame';
import NavbarProfile from '../../components/NavbarProfile';
import NavBar from '../../components/NavBar';
import ButtonSecondary from "./ButtonSecondary";
import ButtonSecondary from './ButtonSecondary';
import PostItem from '../../components/PostItem';
import imageBasic from '../../assets/default/defaultProfile.svg';
import Loading from '../../components/Loading';
Expand All @@ -28,153 +28,148 @@ import photo from '../../assets/default/photo.svg';
import UserProfile from '../../components/UserProfile';
import { StyledText } from '../../components/Text/StyledText';

import { getUserPostListApi } from "../../apis/post";
import { UserPostSummary } from "../../apis/post/dto";
import { getUserInfoApi } from "../../apis/user";
import { UserInfoData } from "../../apis/user/dto";
import { getUserPostListApi } from '../../apis/post';
import { UserPostSummary } from '../../apis/post/dto';
import { getUserInfoApi } from '../../apis/user';
import { UserInfoData } from '../../apis/user/dto';

const MyPage: React.FC = () => {
const [isLoading, setIsLoading] = useState(true);
const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false);
const [posts, setPosts] = useState<UserPostSummary[]>([]);
const [totalPosts, setTotalPosts] = useState(0);
const [userInfo, setUserInfo] = useState<UserInfoData | null>(null);
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(true);
const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false);
const [posts, setPosts] = useState<UserPostSummary[]>([]);
const [totalPosts, setTotalPosts] = useState(0);
const [userInfo, setUserInfo] = useState<UserInfoData | null>(null);
const navigate = useNavigate();

const bottomSheetMenuProps: BottomSheetMenuProps = {
items: [
{
text: '인스타 피드 가져오기',
action: () => {
setIsBottomSheetOpen(false);
navigate('/insta-connect');
},
icon: insta,
},
{
text: '사진 올리기',
action: () => {
setIsBottomSheetOpen(false);
navigate('/image-select');
},
icon: photo,
},
],
marginBottom: '50px',
};
const bottomSheetMenuProps: BottomSheetMenuProps = {
items: [
{
text: '인스타 피드 가져오기',
action: () => {
setIsBottomSheetOpen(false);
navigate('/insta-connect');
},
icon: insta,
},
{
text: '사진 올리기',
action: () => {
setIsBottomSheetOpen(false);
navigate('/image-select');
},
icon: photo,
},
],
marginBottom: '50px',
};

const bottomSheetProps: BottomSheetProps<BottomSheetMenuProps> = {
isOpenBottomSheet: isBottomSheetOpen,
isHandlerVisible: true,
Component: BottomSheetMenu,
componentProps: bottomSheetMenuProps,
onCloseBottomSheet: () => {
setIsBottomSheetOpen(false);
},
};
const bottomSheetProps: BottomSheetProps<BottomSheetMenuProps> = {
isOpenBottomSheet: isBottomSheetOpen,
isHandlerVisible: true,
Component: BottomSheetMenu,
componentProps: bottomSheetMenuProps,
onCloseBottomSheet: () => {
setIsBottomSheetOpen(false);
},
};

const handleOpenSheet = () => {
setIsBottomSheetOpen(true);
};
const handleOpenSheet = () => {
setIsBottomSheetOpen(true);
};

// 사용자 정보 조회 API
const fetchUserInfo = async () => {
try {
const storedUserId = Number(localStorage.getItem('my_id'));
if (!storedUserId) {
console.error('User ID not found in localStorage');
return;
}
// 사용자 정보 조회 API
const fetchUserInfo = async () => {
try {
const storedUserId = Number(localStorage.getItem('my_id'));
if (!storedUserId) {
console.error('User ID not found in localStorage');
return;
}

const response = await getUserInfoApi(Number(storedUserId));
setUserInfo(response.data);
} catch (error) {
console.error('Error fetching user info:', error);
}
};

// 게시물 리스트 조회 API
const fetchPostList = async () => {
try {
const storedUserId = Number(localStorage.getItem('my_id'));
if (!storedUserId) {
console.error('User ID not found in localStorage');
return;
}
const response = await getUserInfoApi(Number(storedUserId));
setUserInfo(response.data);
} catch (error) {
console.error('Error fetching user info:', error);
}
};

const response = await getUserPostListApi(1, 10, Number(storedUserId));
const { post, totalPostsCount } = response.data;
// 게시물 리스트 조회 API
const fetchPostList = async () => {
try {
const storedUserId = Number(localStorage.getItem('my_id'));
if (!storedUserId) {
console.error('User ID not found in localStorage');
return;
}

setPosts(post); // 게시물 목록 상태 업데이트 (UserPostSummary 사용!)
setTotalPosts(totalPostsCount); // 총 게시물 수 상태 업데이트
} catch (error) {
console.error('Error fetching user post list:', error);
} finally {
setIsLoading(false); // 로딩 상태 종료
}
};
const response = await getUserPostListApi(1, 10, Number(storedUserId));
const { post, totalPostsCount } = response.data;

useEffect(() => {
fetchPostList();
fetchUserInfo();
}, []);
setPosts(post); // 게시물 목록 상태 업데이트 (UserPostSummary 사용!)
setTotalPosts(totalPostsCount); // 총 게시물 수 상태 업데이트
} catch (error) {
console.error('Error fetching user post list:', error);
} finally {
setIsLoading(false); // 로딩 상태 종료
}
};

if (isLoading) {
return <Loading />;
}
useEffect(() => {
fetchPostList();
fetchUserInfo();
}, []);

return (
<OODDFrame>
<ProfileContainer>
<AddButton onClick={handleOpenSheet}>
<img src={button_plus} alt="Add" />
</AddButton>
<BottomSheet {...bottomSheetProps} />
<NavbarProfile />
<Header>
<UserProfile
userImg={userInfo?.profilePictureUrl || imageBasic}
nickname={userInfo?.nickname || '알수없음'}
bio={userInfo?.bio || '소개글이 없습니다.'}
/>
</Header>
<ButtonSecondary />
<StatsContainer>
<Stat>
<StatLabel>OOTD</StatLabel>
<StatNumber>{totalPosts || 0}</StatNumber>
</Stat>
<Stat>
<StatLabel>코멘트</StatLabel>
<StatNumber>
{posts.reduce((sum, post) => sum + (post.postCommentsCount || 0), 0)}
</StatNumber>
</Stat>
<Stat>
<StatLabel>좋아요</StatLabel>
<StatNumber>
{posts.reduce((sum, post) => sum + (post.postLikesCount || 0), 0)}
</StatNumber>
</Stat>
</StatsContainer>
<PostsContainer>
{posts.length > 0 ? (
posts
.sort((a, b) => Number(b.isRepresentative) - Number(a.isRepresentative))
.map((post) => <PostItem key={post.postId} post={post} />)
) : (
<NoPostWrapper>
<StyledText $textTheme={{ style: 'headline1-medium' }} color="#8e8e93">
게시물이 없어요.
</StyledText>
</NoPostWrapper>

)}
</PostsContainer>
<NavBar />
</ProfileContainer>
</OODDFrame>
);
if (isLoading) {
return <Loading />;
}

return (
<OODDFrame>
<ProfileContainer>
<AddButton onClick={handleOpenSheet}>
<img src={button_plus} alt="Add" />
</AddButton>
<BottomSheet {...bottomSheetProps} />
<NavbarProfile />
<Header>
<UserProfile
userImg={userInfo?.profilePictureUrl || imageBasic}
nickname={userInfo?.nickname || '알수없음'}
bio={userInfo?.bio || '소개글이 없습니다.'}
/>
</Header>
<ButtonSecondary />
<StatsContainer>
<Stat>
<StatLabel>OOTD</StatLabel>
<StatNumber>{totalPosts || 0}</StatNumber>
</Stat>
<Stat>
<StatLabel>코멘트</StatLabel>
<StatNumber>{posts.reduce((sum, post) => sum + (post.postCommentsCount || 0), 0)}</StatNumber>
</Stat>
<Stat>
<StatLabel>좋아요</StatLabel>
<StatNumber>{posts.reduce((sum, post) => sum + (post.postLikesCount || 0), 0)}</StatNumber>
</Stat>
</StatsContainer>
<PostsContainer>
{posts.length > 0 ? (
posts
.sort((a, b) => Number(b.isRepresentative) - Number(a.isRepresentative))
.map((post) => <PostItem key={post.id} post={post} />)
) : (
<NoPostWrapper>
<StyledText $textTheme={{ style: 'headline1-medium' }} color="#8e8e93">
게시물이 없어요.
</StyledText>
</NoPostWrapper>
)}
</PostsContainer>
<NavBar />
</ProfileContainer>
</OODDFrame>
);
};

export default MyPage;
4 changes: 2 additions & 2 deletions src/pages/ProfileViewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@ const ProfileViewer: React.FC = () => {
</CounterContainer>
<PostListContainer>
{representativePosts.map((post) => (
<PostItem key={post.postId} post={post} isMyPost={false} />
<PostItem key={post.id} post={post} isMyPost={false} />
))}
{otherPosts.map((post) => (
<PostItem key={post.postId} post={post} isMyPost={false} />
<PostItem key={post.id} post={post} isMyPost={false} />
))}
</PostListContainer>
<OptionsBottomSheet {...optionsBottomSheetProps} />
Expand Down