1+ import { CaretLeftIcon , CaretRightIcon } from '@phosphor-icons/react' ;
2+
13import ApplicantRow from '@/features/Team/components/ApplicantsGrid/ApplicantRow/ApplicantRow' ;
24import { useGetTeamApplicants } from '@/features/Team/hooks/useGetTeamApplicants' ;
35
@@ -10,15 +12,17 @@ interface ApplicantsGridProps {
1012 page ?: number ;
1113 size ?: number ;
1214 teamStatus ?: string ;
15+ onPageChange ?: ( page : number ) => void ;
1316}
1417
1518const ApplicantsGrid = ( {
1619 teamType,
1720 teamId,
1821 amILeader,
1922 page = 0 ,
20- size = 4 ,
23+ size = 5 ,
2124 teamStatus,
25+ onPageChange,
2226} : ApplicantsGridProps ) => {
2327 const { data, isLoading, isError, error } = useGetTeamApplicants ( {
2428 teamId,
@@ -40,23 +44,106 @@ const ApplicantsGrid = ({
4044 return < div className = { styles . empty } > 참여 희망자가 없습니다.</ div > ;
4145 }
4246
47+ // 페이지네이션 관련 함수
48+ const { pagination } = data . data ;
49+ const { currentPage, totalPages } = pagination ;
50+
51+ // 페이지 번호 배열
52+ const getVisiblePages = ( ) => {
53+ const maxVisible = 5 ;
54+ const half = Math . floor ( maxVisible / 2 ) ;
55+
56+ let start = Math . max ( 0 , currentPage - half ) ;
57+ const end = Math . min ( totalPages - 1 , start + maxVisible - 1 ) ;
58+
59+ if ( end - start < maxVisible - 1 ) {
60+ start = Math . max ( 0 , end - maxVisible + 1 ) ;
61+ }
62+
63+ return Array . from ( { length : end - start + 1 } , ( _ , i ) => start + i ) ;
64+ } ;
65+
66+ const visiblePages = getVisiblePages ( ) ;
67+
68+ const handlePrevious = ( ) => {
69+ if ( currentPage > 0 && onPageChange ) {
70+ onPageChange ( currentPage - 1 ) ;
71+ }
72+ } ;
73+
74+ const handleNext = ( ) => {
75+ if ( currentPage < totalPages - 1 && onPageChange ) {
76+ onPageChange ( currentPage + 1 ) ;
77+ }
78+ } ;
79+
80+ const handlePageClick = ( pageNum : number ) => {
81+ if ( onPageChange ) {
82+ onPageChange ( pageNum ) ;
83+ }
84+ } ;
85+
4386 return (
44- < div className = { `${ styles . applicantsGrid } ${ teamType === 'STUDY' ? styles . study : '' } ` } >
45- { teamType === 'PROJECT' && < div className = { styles . gridLabel } > 지원 포지션</ div > }
46- < div className = { styles . gridLabel } > 멤버</ div >
47- < div className = { styles . gridLabel } > 액션</ div >
48-
49- { data . data . items . map ( applicant => (
50- < ApplicantRow
51- teamType = { teamType }
52- key = { applicant . applicantId }
53- member = { applicant }
54- teamId = { teamId }
55- amILeader = { amILeader }
56- teamStatus = { teamStatus }
57- />
58- ) ) }
59- </ div >
87+ < >
88+ < div className = { `${ styles . applicantsGrid } ${ teamType === 'STUDY' ? styles . study : '' } ` } >
89+ { teamType === 'PROJECT' && < div className = { styles . gridLabel } > 지원 포지션</ div > }
90+ < div className = { styles . gridLabel } > 멤버</ div >
91+ < div className = { styles . gridLabel } > 액션</ div >
92+
93+ { data . data . items . map ( applicant => (
94+ < ApplicantRow
95+ teamType = { teamType }
96+ key = { applicant . applicantId }
97+ member = { applicant }
98+ teamId = { teamId }
99+ amILeader = { amILeader }
100+ teamStatus = { teamStatus }
101+ />
102+ ) ) }
103+ </ div >
104+
105+ { /* 페이지네이션 */ }
106+ { onPageChange && totalPages > 1 && (
107+ < div className = { styles . pagination } >
108+ { /* 이전 버튼 */ }
109+ < button
110+ className = { `${ styles . pagination__button } ${
111+ currentPage === 0 ? styles . pagination__button__disabled : ''
112+ } `}
113+ onClick = { handlePrevious }
114+ disabled = { currentPage === 0 }
115+ >
116+ < CaretLeftIcon size = { 16 } weight = "bold" />
117+ </ button >
118+
119+ { /* 페이지 번호 */ }
120+ < div className = { styles . pagination__pages } >
121+ { visiblePages . map ( pageNum => (
122+ < button
123+ key = { pageNum }
124+ className = { `${ styles . pagination__page } ${
125+ pageNum === currentPage ? styles . pagination__page__active : ''
126+ } `}
127+ onClick = { ( ) => handlePageClick ( pageNum ) }
128+ >
129+ { pageNum + 1 }
130+ </ button >
131+ ) ) }
132+ </ div >
133+
134+ { /* 다음 버튼 */ }
135+ < button
136+ className = { `${ styles . pagination__button } ${
137+ currentPage === totalPages - 1 ? styles . pagination__button__disabled : ''
138+ } `}
139+ onClick = { handleNext }
140+ disabled = { currentPage === totalPages - 1 }
141+ >
142+ < CaretRightIcon size = { 16 } weight = "bold" />
143+ </ button >
144+ </ div >
145+ ) }
146+ </ >
60147 ) ;
61148} ;
62149
0 commit comments