Skip to content

Commit e66a6e9

Browse files
authored
Merge pull request #210 from DeepDirect/fix/DP-437/team-applicants
[Fix] 팀 관리 페이지 참여 희망자 섹션 수정
2 parents 23cff0e + 0a835aa commit e66a6e9

File tree

3 files changed

+178
-17
lines changed

3 files changed

+178
-17
lines changed

src/features/Team/components/ApplicantsGrid/ApplicantsGrid.module.scss

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,72 @@
3636
text-align: center;
3737
color: $gray-3;
3838
}
39+
40+
.pagination {
41+
display: flex;
42+
align-items: center;
43+
justify-content: center;
44+
gap: 8px;
45+
margin-top: 16px;
46+
padding: 16px 0;
47+
}
48+
49+
.pagination__button {
50+
display: flex;
51+
align-items: center;
52+
justify-content: center;
53+
width: 32px;
54+
height: 32px;
55+
border: 1px solid $gray-2;
56+
border-radius: 4px;
57+
color: $gray-1;
58+
background-color: $white-3;
59+
transition: all 0.2s ease;
60+
cursor: pointer;
61+
62+
&:hover:not(&__disabled) {
63+
border-color: $gray-3;
64+
background-color: $gray-4;
65+
}
66+
67+
&__disabled {
68+
color: $gray-1;
69+
background-color: $gray-4;
70+
cursor: not-allowed;
71+
}
72+
}
73+
74+
.pagination__pages {
75+
display: flex;
76+
gap: 4px;
77+
}
78+
79+
.pagination__page {
80+
display: flex;
81+
align-items: center;
82+
justify-content: center;
83+
min-width: 32px;
84+
height: 32px;
85+
padding: 0 8px;
86+
border: 1px solid $gray-2;
87+
border-radius: 4px;
88+
font-size: $fs-xxsmall;
89+
font-weight: $fw-medium;
90+
color: $gray-1;
91+
background-color: $white-3;
92+
transition: all 0.2s ease;
93+
cursor: pointer;
94+
95+
&:hover:not(&__active) {
96+
border-color: $gray-3;
97+
background-color: $gray-4;
98+
}
99+
100+
&__active {
101+
border: 1px solid $blue-1;
102+
border-color: $gray-1;
103+
color: $gray-1;
104+
background-color: $gray-4;
105+
cursor: default;
106+
}
107+
}

src/features/Team/components/ApplicantsGrid/ApplicantsGrid.tsx

Lines changed: 104 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { CaretLeftIcon, CaretRightIcon } from '@phosphor-icons/react';
2+
13
import ApplicantRow from '@/features/Team/components/ApplicantsGrid/ApplicantRow/ApplicantRow';
24
import { 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

1518
const 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

src/pages/team/TeamSettingPage/TeamSettingPage.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ const TeamSettingPage = () => {
4343
const [selectedMember, setSelectedMember] = useState<MemberType | null>(null);
4444
const [selectedMemberScores, setSelectedMemberScores] = useState<EvaluationScore[]>([]); // 선택된 멤버의 평가 점수
4545

46+
// 참여 희망자 페이지네이션 상태 관리
47+
const [currentPage, setCurrentPage] = useState(0);
48+
4649
const teamId = id ? parseInt(id, 10) : null;
4750

4851
// 팀 정보 가져오기
@@ -375,6 +378,8 @@ const TeamSettingPage = () => {
375378
teamId={teamId}
376379
amILeader={teamData.data.isLeader}
377380
teamStatus={teamData.data.teamStatus}
381+
page={currentPage}
382+
onPageChange={setCurrentPage}
378383
/>
379384
</MainSection>
380385

0 commit comments

Comments
 (0)