Skip to content

Commit

Permalink
#109 feat: 내 친구 목록, 전체 친구 목록 및 검색 api 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
MyungJiwoo committed Nov 13, 2024
1 parent 57086f6 commit a7c9a21
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 24 deletions.
44 changes: 44 additions & 0 deletions src/api/ConnectionApi.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { axiosInstance } from '../utils/apiConfig';
import { FollowersListData } from '../types/ConnectionType';

// * 내 친구 목록 get
export const getFollowersList = async (
page: number,
size: number
): Promise<FollowersListData | null> => {
try {
const response = await axiosInstance.get(`/member/follow?page=${page}&size=${size}`, {
params: {
page: page,
size: size,
},
});
console.log('내 친구 목록', response.data);
return response.data.data;
} catch (error) {
console.error('Error fetching data:', error);
return null;
}
};

// * 전체 친구 목록 get + 검색
export const getSearchFriendsList = async (
keyword: string,
page: number,
size: number
): Promise<FollowersListData | null> => {
try {
const response = await axiosInstance.get(
`/member/follow/search/all?keyword=${keyword}&page=${page}&size=${size}`
);
console.log('검색 친구 목록', response.data);

return {
followInfoResDto: response.data.data.memberInfoForFollowResDtos, // 원하는 필드 이름으로 매핑
pageInfoResDto: response.data.data.pageInfoResDto,
};
} catch (error) {
console.error('Error fetching data:', error);
return null;
}
};
13 changes: 9 additions & 4 deletions src/components/Connection/Connection.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { FollowInfo } from '../../types/ConnectionType';
import * as S from './ConnectionStyled';

const Connection = () => {
interface ConnectionProps {
follower: FollowInfo;
}

const Connection = ({ follower }: ConnectionProps) => {
return (
<S.ConnectionLayout>
<S.ProfileImageWrapper></S.ProfileImageWrapper>
<S.ProfileImageWrapper src={follower.profileImage} />
<S.ConnectionUserWrapper>
<p className="name">본명</p>
<p className="nickName">닉네임#고유번호 | 이메일</p>
<p className="name">{follower.name}</p>
<p className="nickName">{follower.nickname}</p>
</S.ConnectionUserWrapper>
<S.FriendRequestButtonWrapper>
<p>친구 신청</p>
Expand Down
4 changes: 3 additions & 1 deletion src/components/Connection/ConnectionStyled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ export const ConnectionLayout = styled.div`
}
`;

export const ProfileImageWrapper = styled.div`
export const ProfileImageWrapper = styled.img`
width: 4rem;
height: 4rem;
min-width: 4rem;
border-radius: 50%;
border: 1px solid ${theme.color.stroke2};
color: ${theme.color.text};
Expand All @@ -47,6 +48,7 @@ export const FriendRequestButtonWrapper = styled.div`
font-size: ${theme.font.size.caption};
border: 1px solid ${theme.color.stroke2};
color: ${theme.color.gray};
white-space: nowrap;
&:hover {
background-color: ${theme.color.stroke2};
Expand Down
19 changes: 19 additions & 0 deletions src/hooks/useFollowersList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useQuery } from '@tanstack/react-query';
import { FollowersListData } from '../types/ConnectionType';
import { getFollowersList, getSearchFriendsList } from '../api/ConnectionApi';

export const useFollowersList = (page: number, size: number) => {
return useQuery<FollowersListData | null>({
queryKey: ['followersList', page, size],
queryFn: () => getFollowersList(page, size),
staleTime: 1000 * 60 * 5,
});
};

export const useSearchFriendsList = (keyword: string, page: number, size: number) => {
return useQuery<FollowersListData | null>({
queryKey: ['followersList', keyword, page, size],
queryFn: () => getSearchFriendsList(keyword, page, size),
staleTime: 1000 * 60 * 5,
});
};
39 changes: 30 additions & 9 deletions src/pages/ConnectionsPage/ConnectionsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,20 @@ import leftarrow from '../../img/leftarrow.png';
import Connection from '../../components/Connection/Connection';
import Pagination from '../../components/CustomPagination';
import { useNavigate } from 'react-router-dom';
import { useFollowersList } from '../../hooks/useFollowersList';
import { useState } from 'react';

const ConnectionsPage = () => {
const navigate = useNavigate();
const [currentPage, setCurrentPage] = useState<number>(0);

const { data: followersList } = useFollowersList(currentPage, 8);
console.log(followersList);

// * 페이지네이션 페이지 변경 감지 함수
const handleChangePage = (event: React.ChangeEvent<unknown>, value: number) => {
setCurrentPage(value - 1);
};

return (
<>
Expand All @@ -31,17 +42,27 @@ const ConnectionsPage = () => {
</S.HeaderLayout>

<S.ConnectionsWrapper>
<Connection />
<Connection />
<Connection />
<Connection />
{followersList?.followInfoResDto.map((follower, index) => (
<Connection key={index} follower={follower} />
))}
</S.ConnectionsWrapper>
</S.MainDashBoardContainer>

{/* 페이지네이션 */}
{/* <S.PaginationWrapper>
<Pagination count={pageInfo?.totalPages} page={page} onChange={handleChangePage} />
</S.PaginationWrapper> */}
{followersList?.followInfoResDto.length == 0 && (
<S.NoResultWrapper>
<p>친구가 없습니다.</p>
</S.NoResultWrapper>
)}

{followersList?.followInfoResDto.length !== 0 && (
<S.PaginationWrapper>
<Pagination
count={followersList?.pageInfoResDto.totalPages ?? 1}
page={currentPage + 1}
onChange={handleChangePage}
/>
</S.PaginationWrapper>
)}
</S.MainDashBoardContainer>
</S.MainDashBoardLayout>
</>
);
Expand Down
19 changes: 19 additions & 0 deletions src/pages/ConnectionsPage/ConnectionsPageStyled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,22 @@ export const ConnectionsWrapper = styled.div`
flex-basis: calc(100% / 2 - 5rem); /* 빈 공간을 채워서 왼쪽 정렬처럼 보이게 함 */
}
`;

export const NoResultWrapper = styled.div`
width: 100%;
margin-top: 1rem;
display: flex;
justify-content: center;
p {
width: fit-content;
color: ${theme.color.gray};
font-size: ${theme.font.size.caption};
}
`;

export const PaginationWrapper = styled.div`
width: 100%;
margin-top: 1rem;
display: flex;
justify-content: center;
`;
42 changes: 32 additions & 10 deletions src/pages/ConnectionsSearchPage/ConnectionsSearchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,25 @@ import Pagination from '../../components/CustomPagination';
import { useNavigate } from 'react-router-dom';
import { useState } from 'react';
import SearchIcon from './SearchIcon';
import { useSearchFriendsList } from '../../hooks/useFollowersList';
import { useDebounce } from '../../hooks/useDebounce';

const ConnectionsPage = () => {
const navigate = useNavigate();
const [keyword, setKeyword] = useState<string>('');
const [currentPage, setCurrentPage] = useState<number>(0);
const debouncedKeyword = useDebounce(keyword, 300); // debounce된 키워드로 검색

const { data: followersList } = useSearchFriendsList(debouncedKeyword, currentPage, 8);

// * 페이지네이션 페이지 변경 감지 함수
const handleChangePage = (event: React.ChangeEvent<unknown>, value: number) => {
setCurrentPage(value - 1);
};

const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
setKeyword(e.target.value);
setCurrentPage(0);
};

return (
Expand Down Expand Up @@ -42,7 +54,7 @@ const ConnectionsPage = () => {
<SearchIcon />

<S.InputWrapper
placeholder="이메일 / 닉네임#고유번호로 검색하기"
placeholder="이메일로 검색하기"
type="text"
value={keyword}
name="keyword"
Expand All @@ -55,17 +67,27 @@ const ConnectionsPage = () => {
<p>검색 결과</p>
</S.SectionTitleWrapper>
<S.ConnectionsWrapper>
<Connection />
<Connection />
<Connection />
<Connection />
{followersList?.followInfoResDto.map((follower, index) => (
<Connection key={index} follower={follower} />
))}
</S.ConnectionsWrapper>
</S.MainDashBoardContainer>

{/* 페이지네이션 */}
{/* <S.PaginationWrapper>
<Pagination count={pageInfo?.totalPages} page={page} onChange={handleChangePage} />
</S.PaginationWrapper> */}
{followersList?.followInfoResDto.length == 0 && (
<S.NoResultWrapper>
<p>검색 결과가 없습니다.</p>
</S.NoResultWrapper>
)}

{followersList?.followInfoResDto.length !== 0 && (
<S.PaginationWrapper>
<Pagination
count={followersList?.pageInfoResDto.totalPages ?? 1}
page={currentPage + 1}
onChange={handleChangePage}
/>
</S.PaginationWrapper>
)}
</S.MainDashBoardContainer>
</S.MainDashBoardLayout>
</>
);
Expand Down
19 changes: 19 additions & 0 deletions src/pages/ConnectionsSearchPage/ConnectionsSearchPageStyled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ export const ConnectionsWrapper = styled.div`
}
`;

export const NoResultWrapper = styled.div`
width: 100%;
margin-top: 1rem;
display: flex;
justify-content: center;
p {
width: fit-content;
color: ${theme.color.gray};
font-size: ${theme.font.size.caption};
}
`;

export const SearchLayout = styled.div`
width: 100%;
margin-top: 3rem;
Expand Down Expand Up @@ -118,3 +130,10 @@ export const Button = styled.button`
background-color: ${theme.color.gray};
}
`;

export const PaginationWrapper = styled.div`
width: 100%;
margin-top: 1rem;
display: flex;
justify-content: center;
`;
18 changes: 18 additions & 0 deletions src/types/ConnectionType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export type FollowInfo = {
memberId?: number;
nickname?: string;
name?: string;
profileImage?: string;
isFollow?: boolean;
};

export type PageInfo = {
currentPage: number;
totalPages: number;
totalItems: number;
};

export type FollowersListData = {
followInfoResDto: FollowInfo[];
pageInfoResDto: PageInfo;
};

0 comments on commit a7c9a21

Please sign in to comment.