From 9152f16569ac9437768dbec3da9a1eb1f2034370 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 11 Aug 2026 01:48:43 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=EC=9E=84=EC=9B=90=20=ED=95=9C?= =?UTF-8?q?=EC=A4=84=EC=86=8C=EA=B0=9C=20=EC=9E=85=EB=A0=A5=20=EA=B8=80?= =?UTF-8?q?=EC=9E=90=EC=88=98=20=EC=A0=9C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/OrgAdmin/AboutSection/Executives/ExecInfo.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/org/OrgAdmin/AboutSection/Executives/ExecInfo.tsx b/src/components/org/OrgAdmin/AboutSection/Executives/ExecInfo.tsx index 65535549..c55dba95 100644 --- a/src/components/org/OrgAdmin/AboutSection/Executives/ExecInfo.tsx +++ b/src/components/org/OrgAdmin/AboutSection/Executives/ExecInfo.tsx @@ -17,6 +17,8 @@ import { StSNSWrapper, } from './style'; +const EXEC_INTRODUCTION_MAX_LENGTH = 23; + interface ExecInfoProps { selectedExec: EXEC_TYPE; isEditable?: boolean; @@ -90,6 +92,7 @@ const ExecInfo = ({ placeholder="ex. 새로운 도전을 위해 과감히 용기내는 사람" required disabled={!isEditable} + maxLength={EXEC_INTRODUCTION_MAX_LENGTH} /> From 91ca0b911a953b12de38b7e486102220a0de732e Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 11 Aug 2026 01:48:44 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=ED=8C=8C=ED=8A=B8=20=ED=95=9C?= =?UTF-8?q?=EC=A4=84=EC=86=8C=EA=B0=9C=20=EA=B3=B5=EB=B0=B1=EB=A7=8C=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=ED=95=84=EC=88=98=EA=B0=92=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecruitSection/_components/PartIntroduction/index.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/org/OrgAdmin/RecruitSection/_components/PartIntroduction/index.tsx b/src/components/org/OrgAdmin/RecruitSection/_components/PartIntroduction/index.tsx index fa2790d7..0e2a7002 100644 --- a/src/components/org/OrgAdmin/RecruitSection/_components/PartIntroduction/index.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/_components/PartIntroduction/index.tsx @@ -119,6 +119,14 @@ const PartIntroSection = ({ const handleOneLineValidation = useCallback( (value: string) => { + if (!value.trim()) { + setError(oneLineFieldName, { + type: 'required', + message: ERROR_MESSAGES.required, + }); + return; + } + if (value.length > ONE_LINE_MAX_LENGTH) { setError(oneLineFieldName, { type: 'maxLength', From e9dbb5136623ea84d62bf6f66d0dbb0164c2f829 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 11 Aug 2026 01:48:47 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=EB=AA=A8=EC=A7=91=20=EC=84=B9?= =?UTF-8?q?=EC=85=98=20=EC=A0=9C=EC=B6=9C=20=EC=8B=9C=20=ED=8C=8C=ED=8A=B8?= =?UTF-8?q?=20=ED=95=9C=EC=A4=84=EC=86=8C=EA=B0=9C=20=EA=B8=80=EC=9E=90?= =?UTF-8?q?=EC=88=98/=EA=B3=B5=EB=B0=B1=20=EA=B2=80=EC=A6=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/OrgAdmin/RecruitSection/index.tsx | 1 + src/components/org/OrgAdmin/utils.ts | 36 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/components/org/OrgAdmin/RecruitSection/index.tsx b/src/components/org/OrgAdmin/RecruitSection/index.tsx index b4e88907..be5700be 100644 --- a/src/components/org/OrgAdmin/RecruitSection/index.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/index.tsx @@ -80,6 +80,7 @@ const RecruitSectionContent = () => { return validationRecruitInputs( getValues, setError, + onChangeIntroPart, onChangeCurriculumPart, onChangeFnaPart, ); diff --git a/src/components/org/OrgAdmin/utils.ts b/src/components/org/OrgAdmin/utils.ts index 061671f8..6aa54335 100644 --- a/src/components/org/OrgAdmin/utils.ts +++ b/src/components/org/OrgAdmin/utils.ts @@ -1,5 +1,9 @@ import type { FieldValues } from 'react-hook-form'; +import { + ONE_LINE_MAX_LENGTH, + ONE_LINE_MAX_LENGTH_ERROR_MESSAGE, +} from '@/components/org/OrgAdmin/RecruitSection/_constants/constants'; import { type PART_KO, PART_LIST, VALIDATION_CHECK } from '@/utils/org'; import { EXEC_ROLE_LIST, toMemberRole } from './AboutSection/memberRole'; @@ -206,14 +210,24 @@ export const validationAboutInputs = ( export const validationRecruitInputs = ( getValues: (payload?: string | string[]) => FieldValues, setError: (name: string, error: { type: string; message: string }) => void, + setIntroPart: (introPart: PART_KO) => void, setCurriculumPart: (curriculumPart: PART_KO) => void, setFnaPart: (fnaPart: PART_KO) => void, ) => { const { recruitHeaderImage, recruitPartCurriculum, recruitQuestion } = getValues(); - const fieldsToValidate = [ + const fieldsToValidate: { + name: string; + value: unknown; + maxLength?: number; + }[] = [ { name: 'recruitHeaderImage', value: recruitHeaderImage }, + ...PART_LIST.map((part) => ({ + name: `partIntroduction${part}`, + value: getValues(`partIntroduction${part}`), + maxLength: ONE_LINE_MAX_LENGTH, + })), ...PART_LIST.flatMap((part) => ['content', 'preference'].map((item) => ({ name: `recruitPartCurriculum.${part}.${item}`, @@ -237,8 +251,22 @@ export const validationRecruitInputs = ( let isAllFilled = true; - for (const { name, value } of fieldsToValidate) { - if (!value) { + for (const { name, value, maxLength } of fieldsToValidate) { + if (typeof value === 'string' && maxLength && value.length > maxLength) { + isAllFilled = false; + + setError(name, { + type: 'maxLength', + message: ONE_LINE_MAX_LENGTH_ERROR_MESSAGE, + }); + + if (name.startsWith('partIntroduction')) + setIntroPart(name.replace('partIntroduction', '') as PART_KO); + + break; + } + + if (!value || (typeof value === 'string' && !value.trim())) { isAllFilled = false; setError(name, { @@ -246,6 +274,8 @@ export const validationRecruitInputs = ( message: VALIDATION_CHECK.required.errorText, }); + if (name.startsWith('partIntroduction')) + setIntroPart(name.replace('partIntroduction', '') as PART_KO); if (name.includes('recruitPartCurriculum')) setCurriculumPart(name.split('.')[1] as PART_KO); if (name.includes('recruitQuestion')) From b5f6d3114ddb2f785cffc176d2c1f77cc0bc4b18 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 11 Aug 2026 01:48:50 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EC=A0=9C?= =?UTF-8?q?=EB=AA=A9/=EB=82=B4=EC=9A=A9=20=EA=B8=80=EC=9E=90=EC=88=98=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=20=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_components/Modal/EditReviewModal.tsx | 19 ++++++++++++++++--- .../HomeSection/_constants/constants.ts | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/components/org/OrgAdmin/HomeSection/_components/Modal/EditReviewModal.tsx b/src/components/org/OrgAdmin/HomeSection/_components/Modal/EditReviewModal.tsx index aebfaf6c..f324dd6e 100644 --- a/src/components/org/OrgAdmin/HomeSection/_components/Modal/EditReviewModal.tsx +++ b/src/components/org/OrgAdmin/HomeSection/_components/Modal/EditReviewModal.tsx @@ -16,9 +16,11 @@ import { import { EMPTY_REVIEW, REVIEW_CONTENT_MAX_HEIGHT, + REVIEW_CONTENT_MAX_LENGTH, REVIEW_CONTENT_MIN_HEIGHT, + REVIEW_TITLE_MAX_LENGTH, } from '@/components/org/OrgAdmin/HomeSection/_constants/constants'; -import { ReviewForm } from '@/components/org/OrgAdmin/HomeSection/_types/types'; +import type { ReviewForm } from '@/components/org/OrgAdmin/HomeSection/_types/types'; import { useEditReviewMutation, useReviewQuery, @@ -81,7 +83,14 @@ export const EditReviewModal = ({ }; const handleSubmit = () => { - if (!reviewId || !review.title || !review.content || !review.authorInfo) { + if ( + !reviewId || + !review.title || + !review.content || + !review.authorInfo || + review.title.length > REVIEW_TITLE_MAX_LENGTH || + (review.content?.length ?? 0) > REVIEW_CONTENT_MAX_LENGTH + ) { return; } @@ -99,7 +108,9 @@ export const EditReviewModal = ({ !reviewId || !review.title || !review.content || - !review.authorInfo; + !review.authorInfo || + review.title.length > REVIEW_TITLE_MAX_LENGTH || + (review.content?.length ?? 0) > REVIEW_CONTENT_MAX_LENGTH; return ( isOpen && ( @@ -114,6 +125,7 @@ export const EditReviewModal = ({ required labelText="리뷰 제목" descriptionText="공백 포함 최대 10자까지 작성할 수 있어요" + maxLength={REVIEW_TITLE_MAX_LENGTH} placeholder="ex. 후회없는 활동" /> @@ -128,6 +140,7 @@ export const EditReviewModal = ({ descriptionText: '공백 포함 최대 200자까지 작성할 수 있어요', }} placeholder="ex. 좋은 사람들도 많이 만났고 기획분야를 제대로 배울 수 있었던 기회였어요. 대학생활 마지막 대외 활동이었지만, 회사 일을 하면서도 미련을 못버리고 메이커스나 솝텀을 기웃거려요. 엄청 오랜 기간동안 애정을 담고 있는 단체예요." + maxLength={REVIEW_CONTENT_MAX_LENGTH} maxHeight={REVIEW_CONTENT_MAX_HEIGHT} /> diff --git a/src/components/org/OrgAdmin/HomeSection/_constants/constants.ts b/src/components/org/OrgAdmin/HomeSection/_constants/constants.ts index 9ded0522..3495ddce 100644 --- a/src/components/org/OrgAdmin/HomeSection/_constants/constants.ts +++ b/src/components/org/OrgAdmin/HomeSection/_constants/constants.ts @@ -26,6 +26,8 @@ export const DEPLOY_TOAST_OPTION: Record<'success' | 'error', ToastOptionType> = export const REVIEW_CONTENT_MIN_HEIGHT = 104; export const REVIEW_CONTENT_MAX_HEIGHT = 220; +export const REVIEW_TITLE_MAX_LENGTH = 10; +export const REVIEW_CONTENT_MAX_LENGTH = 200; export const EMPTY_REVIEW: ReviewForm = { title: '',