Skip to content

Commit 9d36502

Browse files
authored
Merge pull request #91 from codeit9-temporary/feature/Link-페이지
Feat: 페이지네이션 merge 이후 Link 페이지 개선, useViewport useFetchLinks 훅 추가
2 parents caab5db + 8230c3f commit 9d36502

20 files changed

+273
-117
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { FolderData } from "@/types/folderTypes";
2+
import useModalStore from "@/store/useModalStore";
3+
import useRerenderFolderList from "@/hooks/useRerenderFolderList";
4+
5+
interface AddFolderButtonProps {
6+
setFolderList: React.Dispatch<React.SetStateAction<FolderData[]>>;
7+
}
8+
9+
export const AddFolderButton = ({ setFolderList }: AddFolderButtonProps) => {
10+
const { isOpen, openModal } = useModalStore();
11+
12+
useRerenderFolderList(isOpen, setFolderList);
13+
14+
return (
15+
<button
16+
className="w-[79px] h-[19px] text-purple100"
17+
onClick={() => openModal("AddFolderModal")}
18+
>
19+
폴더 추가 +
20+
</button>
21+
);
22+
};
23+
export default AddFolderButton;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { FolderData } from "@/types/folderTypes";
2+
import Image from "next/image";
3+
import useModalStore from "@/store/useModalStore";
4+
import useRerenderFolderList from "../../hooks/useRerenderFolderList";
5+
6+
interface FolderActionsMenuProps {
7+
setFolderList: React.Dispatch<React.SetStateAction<FolderData[]>>;
8+
}
9+
10+
const FolderActionsMenu = ({ setFolderList }: FolderActionsMenuProps) => {
11+
const { isOpen, openModal } = useModalStore();
12+
13+
const handleModalOpen = (text: string) => {
14+
switch (text) {
15+
case "공유":
16+
openModal("SNSModal");
17+
break;
18+
case "이름 변경":
19+
openModal("EditModal");
20+
break;
21+
case "삭제":
22+
openModal("DeleteFolderModal");
23+
break;
24+
default:
25+
break;
26+
}
27+
};
28+
29+
useRerenderFolderList(isOpen, setFolderList);
30+
31+
return (
32+
<div className="w-[192px] h-[18px] flex justify-between gap-[12px] text-gray400">
33+
{[
34+
{ src: "/icons/share.svg", alt: "공유", text: "공유" },
35+
{ src: "/icons/pen.svg", alt: "이름 변경", text: "이름 변경" },
36+
{ src: "/icons/delete.svg", alt: "삭제", text: "삭제" },
37+
].map(({ src, alt, text }) => (
38+
<button
39+
key={text}
40+
className="flex items-center gap-[4px] text-sm"
41+
onClick={() => handleModalOpen(text)}
42+
>
43+
<Image width={18} height={18} src={src} alt={alt} />
44+
<span>{text}</span>
45+
</button>
46+
))}
47+
</div>
48+
);
49+
};
50+
51+
export default FolderActionsMenu;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const FolderTag = ({ folderList }: FolderListData) => {
1111
const handleSubmit = (id: number | string) => {
1212
router.push({
1313
pathname: router.pathname,
14-
query: { ...router.query, folder: id },
14+
query: id ? { folder: id } : {},
1515
});
1616
};
1717

components/Link/ActionButtons.tsx

Lines changed: 0 additions & 18 deletions
This file was deleted.

components/Link/AddLinkInput.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
import { ChangeEvent, KeyboardEvent, useState } from "react";
1+
import { ChangeEvent, KeyboardEvent, useEffect, useState } from "react";
22
import { FolderListData } from "@/types/folderTypes";
3+
import { Modal } from "../modal/modalManager/ModalManager";
34
import Image from "next/image";
45
import SubmitButton from "../SubMitButton";
6+
import useModalStore from "@/store/useModalStore";
57

68
const AddLinkInput = ({ folderList }: FolderListData) => {
9+
const { isOpen, openModal } = useModalStore();
710
const [link, setLink] = useState("");
811

912
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
1013
setLink(e.target.value);
1114
};
1215

1316
const handleClick = () => {
14-
// Addmodal 띄우면서 link 전달
17+
openModal("AddModal", { list: folderList, link: link });
18+
setLink("");
1519
};
1620

1721
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
@@ -34,6 +38,7 @@ const AddLinkInput = ({ folderList }: FolderListData) => {
3438
<div onClick={handleClick}>
3539
<SubmitButton className="w-[80px] h-[37px]">추가하기</SubmitButton>
3640
</div>
41+
{isOpen && <Modal />}
3742
</div>
3843
);
3944
};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
22
import { useRouter } from "next/router";
33
import timeAgo from "@/util/timAgo";
44
import Image from "next/image";
5-
import Dropdown from "./Dropdown";
5+
import Dropdown from "../Dropdown";
66
import useModalStore from "@/store/useModalStore";
77

88
interface LinkCardProps {

components/Pagination.tsx

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
import Image from "next/image";
22
import Link from "next/link";
3+
import { useRouter } from "next/router";
34
import { useEffect, useState } from "react";
45

56
interface PaginationProps {
6-
page: number;
7-
pageSize: number;
87
totalCount: number;
98
}
109

11-
const Pagination: React.FC<PaginationProps> = ({
12-
page,
13-
pageSize,
14-
totalCount,
15-
}) => {
10+
const Pagination: React.FC<PaginationProps> = ({ totalCount }) => {
11+
const router = useRouter();
1612
const LiStyle = "relative w-12 h-12 rounded-lg bg-gray900";
1713
const buttonStyle = "flex justify-center items-center h-full text-black400";
14+
const { page, pageSize } = router.query;
1815

19-
const totalPages = Math.ceil(totalCount / pageSize);
16+
const currentPage = Number(page);
17+
const currentPageSize = Number(pageSize);
18+
const totalPages = Math.ceil(totalCount / currentPageSize);
2019
const [maxPagesToShow, setMaxPagesToShow] = useState(2);
2120

2221
// 화면 크기 변화에 따라 pageSize와 maxPagesToShow를 설정
@@ -45,12 +44,12 @@ const Pagination: React.FC<PaginationProps> = ({
4544
} else {
4645
// 첫 페이지와 마지막 페이지는 항상 표시
4746
pages.push(1);
48-
let start = Math.max(2, page - 1);
49-
let end = Math.min(totalPages - 1, page + 1);
47+
let start = Math.max(2, currentPage - 1);
48+
let end = Math.min(totalPages - 1, currentPage + 1);
5049

51-
if (page > 3) pages.push("...");
50+
if (currentPage > 3) pages.push("...");
5251
for (let i = start; i <= end; i++) pages.push(i);
53-
if (page < totalPages - 2) pages.push("...");
52+
if (currentPage < totalPages - 2) pages.push("...");
5453
pages.push(totalPages);
5554
}
5655

@@ -61,12 +60,12 @@ const Pagination: React.FC<PaginationProps> = ({
6160
<ul className="flex justify-center gap-[10px] my-10">
6261
<li className={LiStyle}>
6362
<Link
64-
href={`/link?page=${page - 1}&pageSize=${pageSize}`}
65-
className={`${buttonStyle} ${page > 1 ? "text-black500" : "pointer-events-none"}`}
63+
href={`/link?page=${currentPage - 1}&pageSize=${currentPageSize}`}
64+
className={`${buttonStyle} ${currentPage > 1 ? "text-black500" : "pointer-events-none"}`}
6665
>
6766
<Image
6867
src={
69-
page > 1
68+
currentPage > 1
7069
? "/icons/pagination-left-active.png"
7170
: "/icons/pagination-left.png"
7271
}
@@ -83,7 +82,7 @@ const Pagination: React.FC<PaginationProps> = ({
8382
<li key={index} className={LiStyle}>
8483
<Link
8584
href={`/link?page=${pageNum}&pageSize=${pageSize}`}
86-
className={`${buttonStyle} ${pageNum === page ? "text-black500" : "text-black400"}`}
85+
className={`${buttonStyle} ${pageNum === currentPage ? "text-black500" : "text-black400"}`}
8786
>
8887
{pageNum}
8988
</Link>
@@ -100,12 +99,12 @@ const Pagination: React.FC<PaginationProps> = ({
10099

101100
<li className={LiStyle}>
102101
<Link
103-
href={`/link?page=${page + 1}&pageSize=${pageSize}`}
104-
className={`${buttonStyle} ${page < totalPages ? "text-black500" : "pointer-events-none"}`}
102+
href={`/link?page=${currentPage + 1}&pageSize=${pageSize}`}
103+
className={`${buttonStyle} ${currentPage < totalPages ? "text-black500" : "pointer-events-none"}`}
105104
>
106105
<Image
107106
src={
108-
page < totalPages
107+
currentPage < totalPages
109108
? "/icons/pagination-right-active.png"
110109
: "/icons/pagination-right.png"
111110
}

components/Search/SearchInput.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const SearchInput = () => {
1616
pathname: router.pathname,
1717
query: { ...router.query, search: value },
1818
});
19+
setValue("");
1920
};
2021

2122
return (
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
interface SearchResultMessageProps {
2+
message: string | string[];
3+
}
4+
5+
const SearchResultMessage = ({ message }: SearchResultMessageProps) => {
6+
return (
7+
<div className="text-[32px] text-gray400 mt-[40px]">
8+
<span className="text-black300">&quot;{message}&quot;</span>으로 검색한
9+
결과입니다.
10+
</div>
11+
);
12+
};
13+
14+
export default SearchResultMessage;

hooks/useFetchLinks.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useEffect } from "react";
2+
import { proxy } from "@/lib/api/axiosInstanceApi";
3+
import { LinkData } from "@/types/linkTypes";
4+
import useViewport from "./useViewport";
5+
6+
// 링크페이지의 query가 바뀌면 새로운 리스트로 업데이트 해주는 훅
7+
const useFetchLinks = (
8+
query: {
9+
page?: number;
10+
search?: string;
11+
},
12+
setLinkCardList: (list: LinkData[]) => void
13+
) => {
14+
const { isTablet } = useViewport();
15+
16+
useEffect(() => {
17+
const fetchLinks = async () => {
18+
const res = await proxy.get("/api/links", {
19+
params: {
20+
page: query.page,
21+
pageSize: isTablet ? 6 : 10,
22+
search: query.search,
23+
},
24+
});
25+
setLinkCardList(res.data.list);
26+
};
27+
28+
if (query) fetchLinks();
29+
}, [query, setLinkCardList, isTablet]);
30+
};
31+
32+
export default useFetchLinks;

0 commit comments

Comments
 (0)