Skip to content

Commit e26e96e

Browse files
authored
refactor(graduate): Admin 사이드 리펙토링 (#222)
2 parents a6cb400 + f2084d5 commit e26e96e

File tree

71 files changed

+337
-844
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+337
-844
lines changed

apps/graduate/src/feature/schedule/api/fetchAllSchedule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useQuery } from '@tanstack/react-query';
22

33
import { get } from '~/shared/api';
4-
import { END_POINT, QUERY_KEYS } from '~/shared/constants';
4+
import { END_POINT, KEYS } from '~/shared/constants';
55

66
import type { Schedule } from '../model/schedule';
77

@@ -14,7 +14,7 @@ const fetchAllSchedule = async (): Promise<Schedule[]> => {
1414

1515
export const useFetchAllSchedule = () => {
1616
return useQuery({
17-
queryKey: [QUERY_KEYS.SCHEDULE_ALL],
17+
queryKey: [...KEYS.SCHEDULE_ALL],
1818
queryFn: fetchAllSchedule,
1919
});
2020
};

apps/graduate/src/feature/studentDetail/hooks/useStudentDetail.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { getStudentDetail } from '../api';
66

77
export function useStudentDetail(studentId: number) {
88
return useQuery({
9-
queryKey: [KEYS.STUDENT_DETAIL, studentId],
9+
queryKey: [...KEYS.STUDENT_DETAIL, studentId],
1010
queryFn: async () => {
1111
const response = await getStudentDetail(studentId);
1212
return response.data;

apps/graduate/src/pages/admin/all/constants/allManagementTexts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { GraduationType } from '~/shared/api/student/fetchGraduationUsers';
1+
import { GraduationLabelType } from '~/shared/api';
22

33
import type { AllManagementRow } from '../types/allManagement';
44

@@ -32,7 +32,7 @@ export const TITLE_ALL_MANAGEMENT = '졸업 대상 전체 관리';
3232
export const LOADING_TEXT = '불러오는 중...';
3333

3434
export const TYPE_LABEL: Record<
35-
GraduationType,
35+
GraduationLabelType,
3636
AllManagementRow['graduationTypeLabel']
3737
> = {
3838
미정: TYPE_UNKNOWN,

apps/graduate/src/pages/admin/all/mock/allManagement.ts

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

apps/graduate/src/pages/admin/all/ui/AllManagementPage.tsx

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ import {
77
DELETE_CONFIRM_TITLE,
88
} from '~/shared/components/Toolbar/toolbarTexts';
99
import {
10+
useAdminDownload,
11+
useAdminPagination,
12+
useAdminSelection,
1013
useFetchGraduationUsers,
1114
useRemoveGraduationUsers,
1215
useToast,
1316
useScheduleList,
1417
} from '~/shared/hooks';
15-
import { downloadGraduationUsersExcel } from '~/shared/utils';
18+
import * as style from '~/shared/styles/adminPage.css';
1619

1720
import { allManagementColumns } from '../constants/allManagementColumns';
1821
import {
@@ -21,7 +24,6 @@ import {
2124
TYPE_LABEL,
2225
TYPE_UNKNOWN,
2326
} from '../constants/allManagementTexts';
24-
import * as style from '../styles/AllManagementPage.css.ts';
2527
import type { AllManagementRow } from '../types/allManagement';
2628
import { extractPeriodData, getStatusLabel } from '../utils';
2729
import UserDetailModal from './UserDetailModal.tsx';
@@ -30,12 +32,18 @@ export default function AllManagementPage() {
3032
const navigate = useNavigate();
3133
const searchParams = useSearch({ from: '/_afterLogin/all' });
3234
const [isModalOpen, setIsModalOpen] = useState(false);
33-
const [page, setPage] = useState(1);
34-
const [pageSize, setPageSize] = useState(10);
35-
const [query, setQuery] = useState('');
36-
const [selectedIds, setSelectedIds] = useState<number[]>([]);
37-
const { toast, confirm } = useToast();
3835
const [selectedStudentId, setSelectedStudentId] = useState<number>();
36+
const { toast, confirm } = useToast();
37+
38+
const {
39+
page,
40+
setPage,
41+
pageSize,
42+
query,
43+
handleQueryChange,
44+
handlePageSizeChange,
45+
resetToFirstPage,
46+
} = useAdminPagination();
3947

4048
useEffect(() => {
4149
if (searchParams?.graduationUserId) {
@@ -55,15 +63,6 @@ export default function AllManagementPage() {
5563
toast.error('스케줄 정보를 불러오는데 실패했습니다.');
5664
}
5765

58-
const resetSelection = () => {
59-
setSelectedIds([]);
60-
setPage(1);
61-
};
62-
63-
const { removeGraduationUsers } = useRemoveGraduationUsers({
64-
onSuccess: resetSelection,
65-
});
66-
6766
const { data, isLoading } = useFetchGraduationUsers({
6867
page: page - 1,
6968
size: pageSize,
@@ -87,6 +86,20 @@ export default function AllManagementPage() {
8786
})
8887
: [];
8988

89+
const { selectedIds, toggleAll, toggleOne, resetSelection } =
90+
useAdminSelection(rows);
91+
92+
const { handleDownload } = useAdminDownload();
93+
94+
const handleResetSelection = () => {
95+
resetSelection();
96+
resetToFirstPage();
97+
};
98+
99+
const { removeGraduationUsers } = useRemoveGraduationUsers({
100+
onSuccess: handleResetSelection,
101+
});
102+
90103
const handleDeleteSelected = () => {
91104
if (selectedIds.length === 0) return;
92105
confirm({
@@ -107,15 +120,6 @@ export default function AllManagementPage() {
107120
});
108121
};
109122

110-
const handleDownloadExcel = async () => {
111-
try {
112-
await downloadGraduationUsersExcel();
113-
} catch (error) {
114-
toast.error(
115-
error instanceof Error ? error.message : '다운로드에 실패했습니다.',
116-
);
117-
}
118-
};
119123
const onNameClick = (id: number) => {
120124
setSelectedStudentId(id);
121125
setIsModalOpen(true);
@@ -130,26 +134,6 @@ export default function AllManagementPage() {
130134

131135
const totalItems = data?.pageable.totalElements ?? 0;
132136

133-
const toggleAll = () => {
134-
const pageIds = rows.map(r => r.id);
135-
const allChecked =
136-
pageIds.length > 0 && pageIds.every(id => selectedIds.includes(id));
137-
setSelectedIds(prev =>
138-
allChecked
139-
? prev.filter(id => !pageIds.includes(id))
140-
: Array.from(new Set([...prev, ...pageIds])),
141-
);
142-
};
143-
144-
const toggleOne = (id: string | number) => {
145-
const numericId = Number(id);
146-
setSelectedIds(prev =>
147-
prev.includes(numericId)
148-
? prev.filter(x => x !== numericId)
149-
: [...prev, numericId],
150-
);
151-
};
152-
153137
return (
154138
<div className={style.root}>
155139
<div className={style.container}>
@@ -158,13 +142,10 @@ export default function AllManagementPage() {
158142
<Toolbar
159143
selectedCount={selectedIds.length}
160144
query={query}
161-
onQueryChange={v => {
162-
setQuery(v);
163-
setPage(1);
164-
}}
145+
onQueryChange={handleQueryChange}
165146
onApprove={() => {}}
166147
onDeleteSelected={handleDeleteSelected}
167-
onDownload={handleDownloadExcel}
148+
onDownload={handleDownload}
168149
disabledApprove={true}
169150
/>
170151

@@ -192,10 +173,7 @@ export default function AllManagementPage() {
192173
pageSize={pageSize}
193174
totalItems={totalItems}
194175
onGoto={setPage}
195-
onPageSizeChange={size => {
196-
setPageSize(size);
197-
setPage(1);
198-
}}
176+
onPageSizeChange={handlePageSizeChange}
199177
/>
200178
</div>
201179
</div>
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
1+
import { SCHEDULE } from '~/shared/constants';
2+
import { SubmissionTypeLabel } from '~/shared/types';
3+
4+
import { getSubmissionTypeLabel } from '../../schedule/constants';
15
import type { PeriodData } from '../types/allManagement';
26

37
import type { ScheduleItem } from '~/pages/admin/schedule/model';
48

5-
const SUBMISSION_TYPE = {
6-
CERTIFICATE: 'CERTIFICATE',
7-
MID_THESIS: 'MIDTHESIS',
8-
FINAL_THESIS: 'FINALTHESIS',
9-
} as const;
10-
119
export function extractPeriodData(
1210
schedules: ScheduleItem[] | undefined,
1311
): PeriodData {
1412
if (!schedules) return {};
1513

16-
const findPeriod = (type: string) => {
14+
const findPeriod = (type: SubmissionTypeLabel) => {
1715
const schedule = schedules.find(s => s.submissionType === type);
1816
return schedule ? `${schedule.startDate}~${schedule.endDate}` : undefined;
1917
};
2018

2119
return {
22-
certificate: findPeriod(SUBMISSION_TYPE.CERTIFICATE),
23-
midThesis: findPeriod(SUBMISSION_TYPE.MID_THESIS),
24-
finalThesis: findPeriod(SUBMISSION_TYPE.FINAL_THESIS),
20+
certificate: findPeriod(getSubmissionTypeLabel(SCHEDULE.CERTIFICATE)),
21+
midThesis: findPeriod(getSubmissionTypeLabel(SCHEDULE.MIDTHESIS)),
22+
finalThesis: findPeriod(getSubmissionTypeLabel(SCHEDULE.FINALTHESIS)),
2523
};
2624
}

apps/graduate/src/pages/admin/certification/styles/CertificationAdminPage.css.ts

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

0 commit comments

Comments
 (0)