diff --git a/src/components/recruit/RecruitBasicInfoSection.jsx b/src/components/recruit/RecruitBasicInfoSection.jsx index 77066d1..c25101e 100644 --- a/src/components/recruit/RecruitBasicInfoSection.jsx +++ b/src/components/recruit/RecruitBasicInfoSection.jsx @@ -18,6 +18,7 @@ export function RecruitBasicInfoSection({ title, form, errors, hasSubmitted, onC value={form.name} onChange={onChange} required + maxLength={8} inputClassName="w-full max-w-[617px]" error={hasSubmitted ? errors.name : ''} /> diff --git a/src/pages/visitor/RecruitPage.jsx b/src/pages/visitor/RecruitPage.jsx index 9a7038c..bf6a5fe 100644 --- a/src/pages/visitor/RecruitPage.jsx +++ b/src/pages/visitor/RecruitPage.jsx @@ -1,8 +1,11 @@ +import { useEffect } from 'react'; + import { RecruitApplyInfoSection } from '@/components/recruit/RecruitApplyInfoSection'; import { RecruitBasicInfoSection } from '@/components/recruit/RecruitBasicInfoSection'; import { RecruitConfirmModal } from '@/components/recruit/RecruitConfirmModal'; import { RecruitPrivacyAgreementSection } from '@/components/recruit/RecruitPrivacyAgreementSection'; import { useRecruitForm } from '@/hooks/useRecruitForm'; +import { ROUTES } from '@/constants/routes'; const TEXT = { titleAccent: '신입 부원', @@ -16,6 +19,9 @@ const TEXT = { const majorOptions = ['응용소프트웨어공학과']; +const LEAVE_CONFIRM_MESSAGE = + '입력하신 정보는 저장되지 않습니다.\n페이지를 이동하시겠습니까?'; + function RecruitPage() { const { form, @@ -30,6 +36,37 @@ function RecruitPage() { closeConfirm, } = useRecruitForm(); + const isDirty = Object.values(form).some((value) => value !== ''); + + useEffect(() => { + if (!isDirty) return; + + const handleLeavePage = (event) => { + const link = event.target.closest('a[href]'); + + if (!link || link.pathname === ROUTES.RECRUIT || link.pathname === ROUTES.RECRUIT_COMPLETE) { + return; + } + + if (!window.confirm(LEAVE_CONFIRM_MESSAGE)) { + event.preventDefault(); + } + }; + + const handleBeforeUnload = (event) => { + event.preventDefault(); + event.returnValue = ''; + }; + + document.addEventListener('click', handleLeavePage, true); + window.addEventListener('beforeunload', handleBeforeUnload); + + return () => { + document.removeEventListener('click', handleLeavePage, true); + window.removeEventListener('beforeunload', handleBeforeUnload); + }; + }, [isDirty]); + return (