Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
APPROVE_OK_TEXT,
APPROVE_CANCEL_TEXT,
APPROVE_EMPTY,
APPROVE_FAILED,
APPROVE_NOTHING,
APPROVE_REASON_ALREADY_APPROVED,
APPROVE_REASON_FAILED,
Expand Down Expand Up @@ -166,8 +165,8 @@ export function useGraduationApproval<T>({
} else {
toast.warning(APPROVE_NOTHING);
}
} catch (error) {
toast.error(error instanceof Error ? error.message : APPROVE_FAILED);
} catch {
/* 실패 시 MutationCache 전역 토스트로 안내 */
}
},
});
Expand Down
12 changes: 3 additions & 9 deletions apps/graduate/src/admin/pages/all/model/useAllManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,7 @@ export const useAllManagement = () => {
}
}, [searchParams, navigate]);

const { data: schedules, error: scheduleError } = useScheduleList();

if (scheduleError) {
toast.error('스케줄 정보를 불러오는데 실패했습니다.');
}
const { data: schedules } = useScheduleList();

const { data, isLoading } = useFetchGraduationUsers({
page: page - 1,
Expand Down Expand Up @@ -104,10 +100,8 @@ export const useAllManagement = () => {
try {
await removeGraduationUsers(selectedIds);
toast.success('선택한 학생을 삭제했습니다.');
} catch (error) {
toast.error(
error instanceof Error ? error.message : '삭제에 실패했습니다.',
);
} catch {
/* 실패 시 MutationCache 전역 토스트 */
}
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ export function useFile(
}
},
enabled: enabled,
meta: { suppressErrorToast: true },
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ export default function FilePreviewPage() {
const handleApprove = async () => {
try {
await approveGraduationUsers([graduationUserId]);
} catch (error) {
toast.error('승인에 실패했습니다.');
} catch {
/* 실패 시 MutationCache 전역 토스트 */
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ export default function ScheduleDescription() {
setIsSaved(true);
toast.success('설명이 저장되었습니다!');
},
onError: () => {
toast.error('설명 저장에 실패했습니다.');
},
},
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ export default function ScheduleEditModal({
setIsModalOpen(false);
reset();
},
onError: () => {
toast.error('일정 수정에 실패했습니다.');
},
},
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ export function useSubmitGraduationUser({ onSuccess }: Options = {}) {

const singleMutation = useMutation({
mutationFn: submitGraduationUser,
meta: { suppressErrorToast: true },
onSuccess: () =>
queryClient.invalidateQueries({ queryKey: graduationUsersKeys.all }),
});

const batchMutation = useMutation({
mutationFn: submitGraduationUsersBatch,
meta: { suppressErrorToast: true },
onSuccess: () =>
queryClient.invalidateQueries({ queryKey: graduationUsersKeys.all }),
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Col, Divider, message, Modal, Row } from 'antd';
import { Col, Divider, Modal, Row } from 'antd';
import { useState } from 'react';

import { modalStyles } from '~/shared/config';
import { notifyError } from '~/shared/utils';

import { ModeCard } from './ModeCard';
import StudentAddMultiple from './StudentAddMultiple';
Expand All @@ -28,9 +29,7 @@ export default function StudentAddModal({ open, onClose }: Props) {
await submitSingle(payload);
onClose();
} catch (error) {
message.error(
error instanceof Error ? error.message : '학생 추가에 실패했습니다.',
);
notifyError(error, '학생 추가에 실패했습니다.');
}
};

Expand All @@ -41,9 +40,7 @@ export default function StudentAddModal({ open, onClose }: Props) {
await submitBatch(rows);
onClose();
} catch (error) {
message.error(
error instanceof Error ? error.message : '학생들 추가에 실패했습니다.',
);
notifyError(error, '학생들 추가에 실패했습니다.');
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import { useCallback } from 'react';

import { GraduationType } from '~/shared/constants';
import { useToast } from '~/shared/hooks';
import { notifyError } from '~/shared/utils';

import { excelDownload } from '../utils/excelDownload';

export function useAdminDownload(graduationType?: GraduationType) {
const { toast } = useToast();

const handleDownload = useCallback(async () => {
try {
await excelDownload(graduationType);
} catch (error) {
toast.error(
error instanceof Error ? error.message : '다운로드에 실패했습니다.',
);
notifyError(error, '다운로드에 실패했습니다.');
}
}, [graduationType, toast]);
}, [graduationType]);

return { handleDownload };
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const submitConfirmEmail = async (email: string) => {
export const useSubmitConfirmEmail = () => {
return useMutation({
mutationFn: submitConfirmEmail,
meta: { suppressErrorToast: true },
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: userKeys.graduationStatus() });
},
Expand Down
15 changes: 9 additions & 6 deletions apps/graduate/src/client/pages/apply/ui/ApplyConfirmPage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useNavigate } from '@tanstack/react-router';
import { message } from 'antd';
import { Check } from 'lucide-react';
import { useState } from 'react';

import { ROUTE } from '~/shared/constants';
import { notifyError, notifySuccess, notifyWarning } from '~/shared/utils';

import { useSubmitConfirmEmail } from '../api/submitConfirmEmail';
import * as styles from '../styles/ApplyConfirmPage.css';
Expand All @@ -16,22 +16,25 @@ export default function ApplyConfirmPage() {

const handleComplete = () => {
if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
message.error('올바른 이메일 형식을 입력해주세요.');
notifyWarning('올바른 이메일 형식을 입력해주세요.');
return;
}

if (email) {
submitConfirmEmail(email, {
onSuccess: () => {
message.success(`${email}로 알림 설정을 완료했습니다.`);
notifySuccess(`${email}로 알림 설정을 완료했습니다.`);
navigate({ to: ROUTE.HOME });
},
onError: () => {
message.error('이메일 등록에 실패했습니다. 다시 시도해주세요.');
onError: error => {
notifyError(
error,
'이메일 등록에 실패했습니다. 다시 시도해주세요.',
);
},
});
} else {
message.success('신청이 완료되었습니다.');
notifySuccess('신청이 완료되었습니다.');
navigate({ to: ROUTE.HOME });
}
};
Expand Down
2 changes: 1 addition & 1 deletion apps/graduate/src/client/pages/apply/ui/ApplyDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function ApplyDrawer({
}: ApplyDrawerProps) {
const router = useRouter();
const handleCancel = () => {
router.navigate({ to: ROUTE.APPLY, params: { confirm: false } });
router.navigate({ to: ROUTE.APPLY, search: { confirm: false } });
};

const { index, step } = useStep({ selectedOption, confirm });
Expand Down
24 changes: 13 additions & 11 deletions apps/graduate/src/client/pages/apply/ui/ApplyPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link, useNavigate, useSearch } from '@tanstack/react-router';
import { useNavigate, useSearch } from '@tanstack/react-router';
import { Button } from 'antd';
import { useState } from 'react';

Expand All @@ -18,9 +18,7 @@ import { vars } from '~/vars.css';

export default function ApplyPage() {
const navigate = useNavigate();
const { confirm } = useSearch({ from: '/apply' }) as {
confirm: boolean;
};
const { confirm } = useSearch({ from: '/apply' });
const [selectedOption, setSelectedOption] = useState<GraduationType>(
GRADUATION_TYPE.THESIS,
);
Expand All @@ -35,6 +33,10 @@ export default function ApplyPage() {
});
};

const openConfirmDrawer = () => {
navigate({ to: ROUTE.APPLY, search: { confirm: true } });
};

return (
<div className={styles.container}>
<header style={{ width: '100%', marginBottom: vars.spacing.md }}>
Expand Down Expand Up @@ -86,15 +88,15 @@ export default function ApplyPage() {
isSubmitting={isSubmitting}
/>

<Link
to={ROUTE.APPLY}
search={{ confirm: true }}
<Button
size='large'
className={styles.button}
type='primary'
onClick={openConfirmDrawer}
style={{ width: '100%' }}
>
<Button size='large' className={styles.button} type='primary'>
제출하기
</Button>
</Link>
제출하기
</Button>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const useSubmitLogin = ({
}) => {
return useMutation({
mutationFn: submitLogin,
meta: { suppressErrorToast: true },
onSuccess: response => {
setAccessToken(response.accessToken);
setRefreshToken(response.refreshToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const submitCertificate = async (data: FormData) => {
export const useSubmitCertificate = () => {
return useMutation({
mutationFn: submitCertificate,
meta: { suppressErrorToast: true },
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: studentKeys.files() });
queryClient.invalidateQueries({ queryKey: userKeys.graduationStatus() });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { message, Upload, UploadProps } from 'antd';
import { Upload, UploadProps } from 'antd';
import { InboxIcon } from 'lucide-react';

import { notifyError, notifySuccess, notifyWarning } from '~/shared/utils';

import { useSubmitCertificate } from '../api/submitCertificate';

const { Dragger } = Upload;
Expand All @@ -18,12 +20,15 @@ export const FileUploadDragger = () => {
const response = await submitCertificate(formData);

onSuccess?.(response);
message.success(
notifySuccess(
`${(file as File).name} 파일이 성공적으로 업로드되었습니다.`,
);
} catch (error) {
onError?.(error as Error);
message.error(`${(file as File).name} 파일 업로드에 실패했습니다.`);
notifyError(
error,
`${(file as File).name} 파일 업로드에 실패했습니다.`,
);
}
};

Expand All @@ -32,7 +37,7 @@ export const FileUploadDragger = () => {
file.type === 'application/pdf' ||
file.name.toLowerCase().endsWith('.pdf');
if (!isPdf) {
alert(
notifyWarning(
`${file.name}은(는) PDF 파일이 아닙니다. PDF 파일만 업로드할 수 있습니다.`,
);
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ export const useFetchGraduationStatus = () => {
return useQuery({
queryKey: userKeys.graduationStatus(),
queryFn: () => fetchGraduationStatus(),
retry: false,
meta: { suppressErrorToast: true },
});
};
33 changes: 28 additions & 5 deletions apps/graduate/src/client/pages/home/hooks/useHomePageData.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
import { WORKFLOW_STAGE_INFO } from '~/shared/constants/graduationWorkflow';
import { WORKFLOW_STAGE } from '~/shared/types/graduation';

import { useFetchGraduationStatus } from '../api/fetchGraduationStatus';

export const useHomePageData = () => {
const {
data: graduationStatus,
isLoading: graduationStatusLoading,
isError: graduationStatusIsError,
error: graduationStatusError,
} = useFetchGraduationStatus();

const currentStatus =
graduationStatus?.status ?? WORKFLOW_STAGE.TYPE_NOT_SELECTED;
if (graduationStatusLoading) {
return {
graduationStatusData: graduationStatus,
graduationStatusLoading: true,
graduationStatusError: undefined,
currentStatus: undefined,
title: undefined,
description: undefined,
button: undefined,
};
}

if (graduationStatusIsError || !graduationStatus) {
return {
graduationStatusData: undefined,
graduationStatusLoading: false,
graduationStatusError,
currentStatus: undefined,
title: '졸업 정보를 확인할 수 없어요.',
description:
'졸업 대상자로 등록되지 않았거나 정보를 불러올 수 없어요.\n담당자에게 문의해 주세요.',
button: undefined,
};
}

const currentStatus = graduationStatus.status;
const statusTextData = WORKFLOW_STAGE_INFO[currentStatus];

return {
graduationStatusData: graduationStatus,
graduationStatusLoading,
graduationStatusError,
graduationStatusLoading: false,
graduationStatusError: undefined,
currentStatus,
title: statusTextData?.title,
description: statusTextData?.description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const submitThesis = async (data: FormData) => {
export const useSubmitThesis = () => {
return useMutation({
mutationFn: submitThesis,
meta: { suppressErrorToast: true },
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: studentKeys.files() });
queryClient.invalidateQueries({ queryKey: userKeys.graduationStatus() });
Expand Down
Loading
Loading