From a06f3132631b0d716d335b5af72be629d5a916c7 Mon Sep 17 00:00:00 2001 From: Kimbosung521 Date: Tue, 23 Jun 2026 10:01:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=ED=94=BC=EB=93=9C=EB=B0=B1=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 신입 부원 모집 이름 길이 제한 추가, 지원하기에서 다른 페이지로 이동 시 alert 창 추가 --- .../recruit/RecruitBasicInfoSection.jsx | 1 + src/hooks/useRecruitForm.js | 10 +++++++- src/pages/visitor/RecruitPage.jsx | 23 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) 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/hooks/useRecruitForm.js b/src/hooks/useRecruitForm.js index 06c4055..4549e04 100644 --- a/src/hooks/useRecruitForm.js +++ b/src/hooks/useRecruitForm.js @@ -20,7 +20,15 @@ export function useRecruitForm() { const handleChange = (event) => { const { name, value } = event.target; - const nextValue = name === 'phone' ? formatPhoneNumber(value) : value; + let nextValue = value; + + if (name === 'phone') { + nextValue = formatPhoneNumber(value); + } + + if (name === 'name') { + nextValue = value.replace(/[^ㄱ-ㅎㅏ-ㅣ가-힣]/g, '').slice(0, 8); + } setForm((prevForm) => ({ ...prevForm, [name]: nextValue })); setErrors((prevErrors) => ({ diff --git a/src/pages/visitor/RecruitPage.jsx b/src/pages/visitor/RecruitPage.jsx index 9a7038c..54dbd15 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,23 @@ function RecruitPage() { closeConfirm, } = useRecruitForm(); + useEffect(() => { + 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(); + } + }; + + document.addEventListener('click', handleLeavePage, true); + return () => document.removeEventListener('click', handleLeavePage, true); + }, []); + return (
From 6de2435cc0cf95c906de746be89f8883a2d60f2d Mon Sep 17 00:00:00 2001 From: Kimbosung521 Date: Tue, 23 Jun 2026 10:14:09 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=EC=A0=9C=EB=AF=B8=EB=82=98=EC=9D=B4=20?= =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useRecruitForm.js | 10 +--------- src/pages/visitor/RecruitPage.jsx | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/hooks/useRecruitForm.js b/src/hooks/useRecruitForm.js index 4549e04..06c4055 100644 --- a/src/hooks/useRecruitForm.js +++ b/src/hooks/useRecruitForm.js @@ -20,15 +20,7 @@ export function useRecruitForm() { const handleChange = (event) => { const { name, value } = event.target; - let nextValue = value; - - if (name === 'phone') { - nextValue = formatPhoneNumber(value); - } - - if (name === 'name') { - nextValue = value.replace(/[^ㄱ-ㅎㅏ-ㅣ가-힣]/g, '').slice(0, 8); - } + const nextValue = name === 'phone' ? formatPhoneNumber(value) : value; setForm((prevForm) => ({ ...prevForm, [name]: nextValue })); setErrors((prevErrors) => ({ diff --git a/src/pages/visitor/RecruitPage.jsx b/src/pages/visitor/RecruitPage.jsx index 54dbd15..bf6a5fe 100644 --- a/src/pages/visitor/RecruitPage.jsx +++ b/src/pages/visitor/RecruitPage.jsx @@ -36,7 +36,11 @@ 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]'); @@ -49,9 +53,19 @@ function RecruitPage() { } }; + const handleBeforeUnload = (event) => { + event.preventDefault(); + event.returnValue = ''; + }; + document.addEventListener('click', handleLeavePage, true); - return () => document.removeEventListener('click', handleLeavePage, true); - }, []); + window.addEventListener('beforeunload', handleBeforeUnload); + + return () => { + document.removeEventListener('click', handleLeavePage, true); + window.removeEventListener('beforeunload', handleBeforeUnload); + }; + }, [isDirty]); return (