@@ -2,6 +2,8 @@ import clsx from "clsx";
22import Image from "next/image" ;
33import Link from "next/link" ;
44import { useRouter } from "next/router" ;
5+ import { useState } from "react" ;
6+ import { PaginationButton } from "@/components/button/PaginationButton" ;
57
68interface Dashboard {
79 id : number ;
@@ -23,6 +25,22 @@ export default function SideMenu({ teamId, dashboardList }: SideMenuProps) {
2325 const { boardid } = router . query ;
2426 const boardId = parseInt ( boardid as string ) ;
2527
28+ const itemsPerPage = 18 ;
29+ const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
30+
31+ const totalPages = Math . ceil ( dashboardList . length / itemsPerPage ) ;
32+ const startIndex = ( currentPage - 1 ) * itemsPerPage ;
33+ const endIndex = startIndex + itemsPerPage ;
34+ const paginatedDashboards = dashboardList . slice ( startIndex , endIndex ) ;
35+
36+ const handlePrev = ( ) => {
37+ if ( currentPage > 1 ) setCurrentPage ( ( prev ) => prev - 1 ) ;
38+ } ;
39+
40+ const handleNext = ( ) => {
41+ if ( currentPage < totalPages ) setCurrentPage ( ( prev ) => prev + 1 ) ;
42+ } ;
43+
2644 return (
2745 < aside className = "h-screen overflow-y-auto border-r border-[var(--color-gray3)] px-3 py-5 lg:w-[300px] md:w-[160px] sm:w-[67px] transition-all duration-200 flex flex-col" >
2846 { /* 로고 */ }
@@ -52,67 +70,86 @@ export default function SideMenu({ teamId, dashboardList }: SideMenuProps) {
5270 </ Link >
5371 </ div >
5472
55- { /* 대시보드 타이틀 */ }
56- < nav >
57- < div className = "mb-4 flex items-center justify-between px-3 md:px-2" >
58- < span className = "hidden md:block font-12sb text-[var(--color-black)]" >
59- Dash Boards
60- </ span >
61- < button className = "ml-auto" >
62- < Image
63- src = "/svgs/icon-add-box.svg"
64- width = { 20 }
65- height = { 20 }
66- alt = "추가 아이콘"
67- unoptimized
68- />
69- </ button >
70- </ div >
73+ { /* 메뉴 전체 */ }
74+ < nav className = "flex flex-col flex-1 justify-between" >
75+ < div >
76+ { /* 대시보드 타이틀 */ }
77+ < div className = "mb-4 flex items-center justify-between px-3 md:px-2" >
78+ < span className = "hidden md:block font-12sb text-[var(--color-black)]" >
79+ Dash Boards
80+ </ span >
81+ < button className = "ml-auto" >
82+ < Image
83+ src = "/svgs/icon-add-box.svg"
84+ width = { 20 }
85+ height = { 20 }
86+ alt = "추가 아이콘"
87+ unoptimized
88+ />
89+ </ button >
90+ </ div >
7191
72- { /* 대시보드 목록 */ }
73- < ul className = "flex flex-col lg:items-start md:items-start sm:items-center sm:w-full" >
74- { dashboardList . map ( ( dashboard ) => (
75- < li
76- key = { dashboard . id }
77- className = { clsx (
78- "w-full flex justify-center sm:justify-center lg:justify-start md:justify-start p-3 font-18m text-[var(--color-black)] transition-colors duration-200" ,
79- dashboard . id === boardId &&
80- "bg-[var(--primary)] text-white rounded-lg"
81- ) }
82- >
83- < Link
84- href = { `/dashboard/${ dashboard . id } ` }
85- className = "flex items-center gap-3 sm:gap-2"
92+ { /* 대시보드 목록 */ }
93+ < ul className = "flex flex-col lg:items-start md:items-start sm:items-center sm:w-full" >
94+ { paginatedDashboards . map ( ( dashboard ) => (
95+ < li
96+ key = { dashboard . id }
97+ className = { clsx (
98+ "w-full flex justify-center sm:justify-center lg:justify-start md:justify-start p-3 font-18m text-[var(--color-black)] transition-colors duration-200" ,
99+ dashboard . id === boardId &&
100+ "bg-[var(--primary)] text-white rounded-lg"
101+ ) }
86102 >
87- < svg
88- xmlns = "http://www.w3.org/2000/svg"
89- width = "8"
90- height = "8"
91- viewBox = "0 0 8 8"
92- fill = { dashboard . color }
93- className = "shrink-0"
103+ < Link
104+ href = { `/dashboard/${ dashboard . id } ` }
105+ className = "flex items-center gap-3 sm:gap-2"
94106 >
95- < circle cx = "4" cy = "4" r = "4" />
96- </ svg >
97- < div className = "hidden md:flex items-center gap-2" >
98- < span className = "truncate font-18m md:text-base" >
99- { dashboard . title }
100- </ span >
101- { dashboard . createdByMe && (
102- < Image
103- src = "/svgs/crown.svg"
104- width = { 18 }
105- height = { 14 }
106- alt = "크라운 아이콘"
107- unoptimized
108- priority
109- />
110- ) }
111- </ div >
112- </ Link >
113- </ li >
114- ) ) }
115- </ ul >
107+ < svg
108+ xmlns = "http://www.w3.org/2000/svg"
109+ width = "8"
110+ height = "8"
111+ viewBox = "0 0 8 8"
112+ fill = { dashboard . color }
113+ className = "shrink-0"
114+ >
115+ < circle cx = "4" cy = "4" r = "4" />
116+ </ svg >
117+ < div className = "hidden md:flex items-center gap-2" >
118+ < span className = "truncate font-18m md:text-base" >
119+ { dashboard . title }
120+ </ span >
121+ { dashboard . createdByMe && (
122+ < Image
123+ src = "/svgs/crown.svg"
124+ width = { 18 }
125+ height = { 14 }
126+ alt = "크라운 아이콘"
127+ unoptimized
128+ priority
129+ />
130+ ) }
131+ </ div >
132+ </ Link >
133+ </ li >
134+ ) ) }
135+ </ ul >
136+ </ div >
137+
138+ { /* 페이지네이션 버튼 */ }
139+ { dashboardList . length > itemsPerPage && (
140+ < div className = "flex justify-start mt-4 px-3" >
141+ < PaginationButton
142+ direction = "left"
143+ disabled = { currentPage === 1 }
144+ onClick = { handlePrev }
145+ />
146+ < PaginationButton
147+ direction = "right"
148+ disabled = { currentPage === totalPages }
149+ onClick = { handleNext }
150+ />
151+ </ div >
152+ ) }
116153 </ nav >
117154 </ aside >
118155 ) ;
0 commit comments