-
Notifications
You must be signed in to change notification settings - Fork 6
Feat : 페이지네이션 작업 #76
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
Feat : 페이지네이션 작업 #76
Changes from 3 commits
6625a42
0790162
8528309
c8ed658
0d1fa32
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| import Image from "next/image"; | ||
| import Link from "next/link"; | ||
| import { useEffect, useState } from "react"; | ||
|
|
||
| interface PaginationProps { | ||
| page: number; | ||
| pageSize: number; | ||
| totalCount: number; | ||
| } | ||
|
|
||
| const Pagination: React.FC<PaginationProps> = ({ | ||
| page, | ||
| pageSize, | ||
| totalCount, | ||
| }) => { | ||
| const LiStyle = "relative w-12 h-12 rounded-lg bg-gray900"; | ||
| const buttonStyle = "flex justify-center items-center h-full text-black400"; | ||
|
|
||
| const totalPages = Math.ceil(totalCount / pageSize); | ||
| const [maxPagesToShow, setMaxPagesToShow] = useState(2); | ||
|
|
||
| // 화면 크기 변화에 따라 pageSize와 maxPagesToShow를 설정 | ||
| useEffect(() => { | ||
| const handleResize = () => { | ||
| const width = window.innerWidth; | ||
| setMaxPagesToShow(width > 1024 ? 5 : 3); | ||
| }; | ||
|
|
||
| // 초기 설정 및 리사이즈 이벤트 리스너 추가 | ||
| handleResize(); | ||
| window.addEventListener("resize", handleResize); | ||
|
|
||
| return () => { | ||
| window.removeEventListener("resize", handleResize); | ||
| }; | ||
| }, []); | ||
|
|
||
| // 페이지 리스트 생성 함수 | ||
| const getPageNumbers = () => { | ||
| const pages = []; | ||
|
|
||
| if (totalPages <= maxPagesToShow) { | ||
| // 전체 페이지 수가 표시 가능한 페이지 수 이하인 경우 모든 페이지 표시 | ||
| for (let i = 1; i <= totalPages; i++) pages.push(i); | ||
| } else { | ||
| // 첫 페이지와 마지막 페이지는 항상 표시 | ||
| pages.push(1); | ||
| let start = Math.max(2, page - 1); | ||
| let end = Math.min(totalPages - 1, page + 1); | ||
|
|
||
| if (page > 3) pages.push("..."); | ||
| for (let i = start; i <= end; i++) pages.push(i); | ||
| if (page < totalPages - 2) pages.push("..."); | ||
| pages.push(totalPages); | ||
| } | ||
|
|
||
| return pages; | ||
| }; | ||
|
|
||
| return ( | ||
| <ul className="flex justify-center gap-[10px] my-10"> | ||
| <li className={LiStyle}> | ||
| <Link | ||
| href={`/link?page=${page - 1}&pageSize=${pageSize}`} | ||
| className={`${buttonStyle} ${page > 1 ? "text-black500" : "pointer-events-none"}`} | ||
| > | ||
| <Image | ||
| src={ | ||
| page > 1 | ||
| ? "/icons/pagination-left-active.png" | ||
| : "/icons/pagination-left.png" | ||
| } | ||
| height={24} | ||
| width={24} | ||
| alt="prev" | ||
| /> | ||
| </Link> | ||
| </li> | ||
|
|
||
| {/* 페이지 번호와 생략 표시 */} | ||
| {getPageNumbers().map((pageNum, index) => | ||
| typeof pageNum === "number" ? ( | ||
| <li key={index} className={LiStyle}> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. key에 index말고 다른게 딱히 생각나지는 않네요 😥 |
||
| <Link | ||
| href={`/link?page=${pageNum}&pageSize=${pageSize}`} | ||
| className={`${buttonStyle} ${pageNum === page ? "text-black500" : "text-black400"}`} | ||
| > | ||
| {pageNum} | ||
| </Link> | ||
| </li> | ||
| ) : ( | ||
| <li | ||
| key={index} | ||
| className={`${LiStyle} flex items-center justify-center text-black400`} | ||
| > | ||
| ... | ||
| </li> | ||
| ) | ||
| )} | ||
|
|
||
| <li className={LiStyle}> | ||
| <Link | ||
| href={`/link?page=${page + 1}&pageSize=${pageSize}`} | ||
| className={`${buttonStyle} ${page < totalPages ? "text-black500" : "pointer-events-none"}`} | ||
| > | ||
| <Image | ||
| src={ | ||
| page < totalPages | ||
| ? "/icons/pagination-right-active.png" | ||
| : "/icons/pagination-right.png" | ||
| } | ||
| width={24} | ||
| height={24} | ||
| alt="next" | ||
| /> | ||
| </Link> | ||
| </li> | ||
| </ul> | ||
| ); | ||
| }; | ||
|
|
||
| export default Pagination; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,11 +8,16 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { | |
|
|
||
| switch (req.method) { | ||
| case "GET": | ||
| const { page = "1", pageSize = "10" } = req.query; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. const page = parseInt((query.page as string) || "1", 10); page, pageSize가 number 타입으로 넘어오는데 값이 없을 때는 string 타입으로 들어가게 되는데 문제가 없을까요 ?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 쿼리 파라미터는 문자열로 받아오기 때문에 number 로 지정하면 오류가 생기더라구요! |
||
|
|
||
| // 유저의 전체 링크 조회 | ||
| try { | ||
| const response = await axiosInstance.get("/links", { | ||
| headers: { Authorization: `Bearer ${accessToken}` }, | ||
| }); | ||
| const response = await axiosInstance.get( | ||
| `/links?page=${page}&pageSize=${pageSize}`, | ||
| { | ||
| headers: { Authorization: `Bearer ${accessToken}` }, | ||
| } | ||
| ); | ||
| return res.status(201).json(response.data); | ||
| } catch (err) { | ||
| console.error(err); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
뭔가 햇더니 "1 2 3 ..... end" "1 2 3 4 5 .... end" 이냐의 분기점이군요👍