From 70a9426fc8c34453814b9c1ee58a6f4100c53491 Mon Sep 17 00:00:00 2001 From: Jeon Eonseok Date: Thu, 28 Nov 2024 13:47:31 +0900 Subject: [PATCH 1/6] fix: form validation off --- src/components/org/OrgAdmin/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/org/OrgAdmin/index.tsx b/src/components/org/OrgAdmin/index.tsx index ce0095a..eb6052d 100644 --- a/src/components/org/OrgAdmin/index.tsx +++ b/src/components/org/OrgAdmin/index.tsx @@ -67,7 +67,7 @@ function OrgAdmin() { /> -
+ {selectedPart === '공통' ? ( Date: Thu, 28 Nov 2024 14:13:44 +0900 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=EB=B0=B0=ED=8F=AC=20=EB=88=84?= =?UTF-8?q?=EB=A5=B4=EB=A9=B4=20revalidate=20=EC=95=88=20=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=97=90=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/OrgAdmin/RecruitSection/Fna.tsx | 83 +++++++++++++++++++ .../RecruitSection/PartCurriculum.tsx | 30 ++++++- 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/src/components/org/OrgAdmin/RecruitSection/Fna.tsx b/src/components/org/OrgAdmin/RecruitSection/Fna.tsx index ddc7539..43e453e 100644 --- a/src/components/org/OrgAdmin/RecruitSection/Fna.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/Fna.tsx @@ -10,6 +10,8 @@ import { StFnaWrapper, StTextAreaWrapper } from './style'; const Fna = () => { const { register, + clearErrors, + setError, formState: { errors }, } = useFormContext(); @@ -44,6 +46,21 @@ const Fna = () => { fixedHeight={74} maxHeight={74} placeholder="질문을 입력해주세요." + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors( + `recruitQuestion_${selectedPart}_questions_0_question`, + ); + } else { + setError( + `recruitQuestion_${selectedPart}_questions_0_question`, + { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }, + ); + } + }} isError={ errors[`recruitQuestion_${selectedPart}_questions_0_question`] ?.message != undefined @@ -61,6 +78,18 @@ const Fna = () => { fixedHeight={74} maxHeight={74} placeholder="답변을 입력해주세요." + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors( + `recruitQuestion_${selectedPart}_questions_0_answer`, + ); + } else { + setError(`recruitQuestion_${selectedPart}_questions_0_answer`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); + } + }} isError={ errors[`recruitQuestion_${selectedPart}_questions_0_answer`] ?.message != undefined @@ -86,6 +115,21 @@ const Fna = () => { fixedHeight={74} maxHeight={74} placeholder="질문을 입력해주세요." + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors( + `recruitQuestion_${selectedPart}_questions_1_question`, + ); + } else { + setError( + `recruitQuestion_${selectedPart}_questions_1_question`, + { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }, + ); + } + }} isError={ errors[`recruitQuestion_${selectedPart}_questions_1_question`] ?.message != undefined @@ -103,6 +147,18 @@ const Fna = () => { fixedHeight={74} maxHeight={74} placeholder="답변을 입력해주세요." + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors( + `recruitQuestion_${selectedPart}_questions_1_answer`, + ); + } else { + setError(`recruitQuestion_${selectedPart}_questions_1_answer`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); + } + }} isError={ errors[`recruitQuestion_${selectedPart}_questions_1_answer`] ?.message != undefined @@ -128,6 +184,21 @@ const Fna = () => { fixedHeight={74} maxHeight={74} placeholder="질문을 입력해주세요." + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors( + `recruitQuestion_${selectedPart}_questions_2_question`, + ); + } else { + setError( + `recruitQuestion_${selectedPart}_questions_2_question`, + { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }, + ); + } + }} isError={ errors[`recruitQuestion_${selectedPart}_questions_2_question`] ?.message != undefined @@ -144,6 +215,18 @@ const Fna = () => { fixedHeight={74} maxHeight={74} placeholder="답변을 입력해주세요." + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors( + `recruitQuestion_${selectedPart}_questions_2_answer`, + ); + } else { + setError(`recruitQuestion_${selectedPart}_questions_2_answer`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); + } + }} isError={ errors[`recruitQuestion_${selectedPart}_questions_2_answer`] ?.message != undefined diff --git a/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx b/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx index 362a171..5d81cb5 100644 --- a/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { VALIDATION_CHECK } from '@/utils/org'; @@ -10,6 +10,8 @@ import { StTextAreaWrapper } from './style'; const PartCurriculum = () => { const { register, + clearErrors, + setError, formState: { errors }, } = useFormContext(); @@ -19,6 +21,10 @@ const PartCurriculum = () => { setSelectedPart(value); }; + useEffect(() => { + console.log(errors); + }, [errors]); + return ( @@ -28,7 +34,7 @@ const PartCurriculum = () => { selectedPart={selectedPart} onSetSelectedPart={handleSetSelectedPart} /> - + { fixedHeight={158} maxHeight={158} placeholder="파트별 설명을 작성해주세요." + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors(`recruitPartCurriculum_${selectedPart}_content`); + } else { + setError(`recruitPartCurriculum_${selectedPart}_content`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); + } + }} isError={ errors[`recruitPartCurriculum_${selectedPart}_content`]?.message != undefined @@ -63,6 +79,16 @@ const PartCurriculum = () => { ex. - 어려움과 고민을 편하게 나누고 공감할 수 있는 유대감과 열린 마음을 가진 분 - 타 파트와 협업하며 존중과 신뢰를 바탕으로 원활한 팀워크를 만들어갈 수 있는 분`} + onChange={(e) => { + if (e.currentTarget.value) { + clearErrors(`recruitPartCurriculum_${selectedPart}_preference`); + } else { + setError(`recruitPartCurriculum_${selectedPart}_preference`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); + } + }} isError={ errors[`recruitPartCurriculum_${selectedPart}_preference`] ?.message != undefined From 4e4043e6e1ec1762cca84f8d66687cff62779dd3 Mon Sep 17 00:00:00 2001 From: Jeon Eonseok Date: Thu, 28 Nov 2024 14:51:15 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=ED=8C=8C=ED=8A=B8=EB=B3=84=20?= =?UTF-8?q?=EC=86=8C=EA=B0=9C=20=ED=95=84=EC=88=98=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/OrgAdmin/PartCategory/index.tsx | 10 ++-- .../RecruitSection/PartCurriculum.tsx | 51 ++++++++++--------- .../org/OrgAdmin/RecruitSection/index.tsx | 23 +++++++-- src/components/org/OrgAdmin/index.tsx | 37 ++++++++++++-- src/utils/org.ts | 4 +- 5 files changed, 87 insertions(+), 38 deletions(-) diff --git a/src/components/org/OrgAdmin/PartCategory/index.tsx b/src/components/org/OrgAdmin/PartCategory/index.tsx index 637ba1e..a08a0e2 100644 --- a/src/components/org/OrgAdmin/PartCategory/index.tsx +++ b/src/components/org/OrgAdmin/PartCategory/index.tsx @@ -1,15 +1,15 @@ import { Chip } from '@sopt-makers/ui'; -import { PART_LIST } from '@/utils/org'; +import { PART_KO, PART_LIST } from '@/utils/org'; import { StPartCategoryWrapper } from './style'; interface PartCategoryProps { - selectedPart: string; - onSetSelectedPart: (part: string) => void; + curriculumPart: PART_KO; + onSetSelectedPart: (part: PART_KO) => void; } const PartCategory = ({ - selectedPart, + curriculumPart, onSetSelectedPart, }: PartCategoryProps) => { return ( @@ -18,7 +18,7 @@ const PartCategory = ({ onSetSelectedPart(part)} - active={selectedPart === part}> + active={curriculumPart === part}> {part} ))} diff --git a/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx b/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx index 5d81cb5..55caf27 100644 --- a/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx @@ -1,13 +1,20 @@ -import { useEffect, useState } from 'react'; import { useFormContext } from 'react-hook-form'; -import { VALIDATION_CHECK } from '@/utils/org'; +import { PART_KO, VALIDATION_CHECK } from '@/utils/org'; import PartCategory from '../PartCategory'; import { StTextArea, StTitle, StTitleWrapper, StWrapper } from '../style'; import { StTextAreaWrapper } from './style'; -const PartCurriculum = () => { +interface RecruitSectionProps { + curriculumPart: PART_KO; + onChangeCurriculumPart: (part: PART_KO) => void; +} + +const PartCurriculum = ({ + curriculumPart, + onChangeCurriculumPart, +}: RecruitSectionProps) => { const { register, clearErrors, @@ -15,32 +22,26 @@ const PartCurriculum = () => { formState: { errors }, } = useFormContext(); - const [selectedPart, setSelectedPart] = useState('기획'); - - const handleSetSelectedPart = (value: string) => { - setSelectedPart(value); + const handleSetSelectedPart = (value: PART_KO) => { + onChangeCurriculumPart(value); }; - useEffect(() => { - console.log(errors); - }, [errors]); - return ( 파트별 소개 - + { placeholder="파트별 설명을 작성해주세요." onChange={(e) => { if (e.currentTarget.value) { - clearErrors(`recruitPartCurriculum_${selectedPart}_content`); + clearErrors(`recruitPartCurriculum_${curriculumPart}_content`); } else { - setError(`recruitPartCurriculum_${selectedPart}_content`, { + setError(`recruitPartCurriculum_${curriculumPart}_content`, { type: 'required', message: VALIDATION_CHECK.required.errorText, }); } }} isError={ - errors[`recruitPartCurriculum_${selectedPart}_content`]?.message != - undefined + errors[`recruitPartCurriculum_${curriculumPart}_content`] + ?.message != undefined } errorMessage={ - errors[`recruitPartCurriculum_${selectedPart}_content`] + errors[`recruitPartCurriculum_${curriculumPart}_content`] ?.message as string } /> { if (e.currentTarget.value) { - clearErrors(`recruitPartCurriculum_${selectedPart}_preference`); + clearErrors(`recruitPartCurriculum_${curriculumPart}_preference`); } else { - setError(`recruitPartCurriculum_${selectedPart}_preference`, { + setError(`recruitPartCurriculum_${curriculumPart}_preference`, { type: 'required', message: VALIDATION_CHECK.required.errorText, }); } }} isError={ - errors[`recruitPartCurriculum_${selectedPart}_preference`] + errors[`recruitPartCurriculum_${curriculumPart}_preference`] ?.message != undefined } errorMessage={ - errors[`recruitPartCurriculum_${selectedPart}_preference`] + errors[`recruitPartCurriculum_${curriculumPart}_preference`] ?.message as string } /> diff --git a/src/components/org/OrgAdmin/RecruitSection/index.tsx b/src/components/org/OrgAdmin/RecruitSection/index.tsx index 9e51a7d..097c054 100644 --- a/src/components/org/OrgAdmin/RecruitSection/index.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/index.tsx @@ -1,14 +1,31 @@ +import { PART_KO } from '@/utils/org'; + import { StContainer } from '../style'; import Fna from './Fna'; import Header from './Header'; import PartCurriculum from './PartCurriculum'; -const RecruitSection = () => { +interface RecruitSectionProps { + curriculumPart: PART_KO; + onChangeCurriculumPart: (part: PART_KO) => void; + fnaPart: string; + onChangeFnaPart: (part: string) => void; +} + +const RecruitSection = ({ + curriculumPart, + onChangeCurriculumPart, + fnaPart, + onChangeFnaPart, +}: RecruitSectionProps) => { return (
- - + + ); }; diff --git a/src/components/org/OrgAdmin/index.tsx b/src/components/org/OrgAdmin/index.tsx index eb6052d..9286176 100644 --- a/src/components/org/OrgAdmin/index.tsx +++ b/src/components/org/OrgAdmin/index.tsx @@ -3,7 +3,12 @@ import { FormProvider, useForm } from 'react-hook-form'; import { StListHeader } from '@/components/attendanceAdmin/session/SessionList/style'; import FilterButton from '@/components/common/FilterButton'; -import { ORG_ADMIN_LIST, SCHEDULE_FIELDS } from '@/utils/org'; +import { + ORG_ADMIN_LIST, + PART_KO, + PART_LIST, + SCHEDULE_FIELDS, +} from '@/utils/org'; import AboutSection from './AboutSection'; import SubmitIcon from './assets/SubmitIcon'; @@ -16,6 +21,9 @@ import { Group } from './types'; function OrgAdmin() { const [selectedPart, setSelectedPart] = useState('공통'); const [group, setGroup] = useState('OB'); + const [curriculumPart, setCurriculumPart] = useState('기획'); + const [fnaPart, setFnaPart] = useState('기획'); + const methods = useForm({ mode: 'onBlur' }); const { handleSubmit, getValues } = methods; @@ -49,9 +57,23 @@ function OrgAdmin() { return true; }; + const validateCurriculum = () => { + for (const part of PART_LIST) { + const content = getValues(`recruitPartCurriculum_${part}_content`); + const preference = getValues(`recruitPartCurriculum_${part}_preference`); + if (!content || !preference) { + setCurriculumPart(part); + setSelectedPart('지원하기'); + return false; + } + } + return true; + }; + const onSubmit = (data: any) => { - const isValid = validateSchedule(); - if (isValid) { + const isScheduleValid = validateSchedule(); + const isCurriculumValid = validateCurriculum(); + if (isScheduleValid && isCurriculumValid) { console.log(data); } }; @@ -80,7 +102,14 @@ function OrgAdmin() { ) : selectedPart === '홈' ? ( ) : ( - + + setCurriculumPart(part) + } + fnaPart={fnaPart} + onChangeFnaPart={(part: PART_KO) => setFnaPart(part)} + /> )} diff --git a/src/utils/org.ts b/src/utils/org.ts index b909b68..d8f2e3e 100644 --- a/src/utils/org.ts +++ b/src/utils/org.ts @@ -32,7 +32,9 @@ export const 임원진_LIST = [ ] as const; // utils/session/partList와 순서 달라서 분리 -export const PART_LIST = [ +export type PART_KO = '기획' | '디자인' | '안드로이드' | 'iOS' | '웹' | '서버'; + +export const PART_LIST: PART_KO[] = [ '기획', '디자인', '안드로이드', From f2336caa3f2853ff75a2972f8c96c34739928f4f Mon Sep 17 00:00:00 2001 From: Jeon Eonseok Date: Thu, 28 Nov 2024 14:58:17 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20fna=20=ED=95=84=EC=88=98=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/OrgAdmin/PartCategory/index.tsx | 6 +- .../org/OrgAdmin/RecruitSection/Fna.tsx | 140 +++++++----------- .../RecruitSection/PartCurriculum.tsx | 2 +- .../org/OrgAdmin/RecruitSection/index.tsx | 4 +- src/components/org/OrgAdmin/index.tsx | 41 ++++- 5 files changed, 102 insertions(+), 91 deletions(-) diff --git a/src/components/org/OrgAdmin/PartCategory/index.tsx b/src/components/org/OrgAdmin/PartCategory/index.tsx index a08a0e2..118386f 100644 --- a/src/components/org/OrgAdmin/PartCategory/index.tsx +++ b/src/components/org/OrgAdmin/PartCategory/index.tsx @@ -5,11 +5,11 @@ import { PART_KO, PART_LIST } from '@/utils/org'; import { StPartCategoryWrapper } from './style'; interface PartCategoryProps { - curriculumPart: PART_KO; + selectedPart: PART_KO; onSetSelectedPart: (part: PART_KO) => void; } const PartCategory = ({ - curriculumPart, + selectedPart, onSetSelectedPart, }: PartCategoryProps) => { return ( @@ -18,7 +18,7 @@ const PartCategory = ({ onSetSelectedPart(part)} - active={curriculumPart === part}> + active={selectedPart === part}> {part} ))} diff --git a/src/components/org/OrgAdmin/RecruitSection/Fna.tsx b/src/components/org/OrgAdmin/RecruitSection/Fna.tsx index 43e453e..0fa2608 100644 --- a/src/components/org/OrgAdmin/RecruitSection/Fna.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/Fna.tsx @@ -1,24 +1,26 @@ import { useState } from 'react'; import { useFormContext } from 'react-hook-form'; -import { VALIDATION_CHECK } from '@/utils/org'; +import { PART_KO, VALIDATION_CHECK } from '@/utils/org'; import PartCategory from '../PartCategory'; import { StTextArea, StTitle, StTitleWrapper, StWrapper } from '../style'; import { StFnaWrapper, StTextAreaWrapper } from './style'; -const Fna = () => { +interface FanProps { + fnaPart: PART_KO; + onChangeFnaPart: (part: PART_KO) => void; +} + +const Fna = ({ fnaPart, onChangeFnaPart }: FanProps) => { const { register, clearErrors, setError, formState: { errors }, } = useFormContext(); - - const [selectedPart, setSelectedPart] = useState('기획'); - - const handleSetSelectedPart = (value: string) => { - setSelectedPart(value); + const handleSetSelectedPart = (value: PART_KO) => { + onChangeFnaPart(value); }; return ( @@ -27,18 +29,15 @@ const Fna = () => { 자주 묻는 질문 - + { placeholder="질문을 입력해주세요." onChange={(e) => { if (e.currentTarget.value) { - clearErrors( - `recruitQuestion_${selectedPart}_questions_0_question`, - ); + clearErrors(`recruitQuestion_${fnaPart}_questions_0_question`); } else { - setError( - `recruitQuestion_${selectedPart}_questions_0_question`, - { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }, - ); + setError(`recruitQuestion_${fnaPart}_questions_0_question`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); } }} isError={ - errors[`recruitQuestion_${selectedPart}_questions_0_question`] + errors[`recruitQuestion_${fnaPart}_questions_0_question`] ?.message != undefined } errorMessage={ - errors[`recruitQuestion_${selectedPart}_questions_0_question`] + errors[`recruitQuestion_${fnaPart}_questions_0_question`] ?.message as string } /> { placeholder="답변을 입력해주세요." onChange={(e) => { if (e.currentTarget.value) { - clearErrors( - `recruitQuestion_${selectedPart}_questions_0_answer`, - ); + clearErrors(`recruitQuestion_${fnaPart}_questions_0_answer`); } else { - setError(`recruitQuestion_${selectedPart}_questions_0_answer`, { + setError(`recruitQuestion_${fnaPart}_questions_0_answer`, { type: 'required', message: VALIDATION_CHECK.required.errorText, }); } }} isError={ - errors[`recruitQuestion_${selectedPart}_questions_0_answer`] + errors[`recruitQuestion_${fnaPart}_questions_0_answer`] ?.message != undefined } errorMessage={ - errors[`recruitQuestion_${selectedPart}_questions_0_answer`] + errors[`recruitQuestion_${fnaPart}_questions_0_answer`] ?.message as string } /> { placeholder="질문을 입력해주세요." onChange={(e) => { if (e.currentTarget.value) { - clearErrors( - `recruitQuestion_${selectedPart}_questions_1_question`, - ); + clearErrors(`recruitQuestion_${fnaPart}_questions_1_question`); } else { - setError( - `recruitQuestion_${selectedPart}_questions_1_question`, - { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }, - ); + setError(`recruitQuestion_${fnaPart}_questions_1_question`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); } }} isError={ - errors[`recruitQuestion_${selectedPart}_questions_1_question`] + errors[`recruitQuestion_${fnaPart}_questions_1_question`] ?.message != undefined } errorMessage={ - errors[`recruitQuestion_${selectedPart}_questions_1_question`] + errors[`recruitQuestion_${fnaPart}_questions_1_question`] ?.message as string } /> { placeholder="답변을 입력해주세요." onChange={(e) => { if (e.currentTarget.value) { - clearErrors( - `recruitQuestion_${selectedPart}_questions_1_answer`, - ); + clearErrors(`recruitQuestion_${fnaPart}_questions_1_answer`); } else { - setError(`recruitQuestion_${selectedPart}_questions_1_answer`, { + setError(`recruitQuestion_${fnaPart}_questions_1_answer`, { type: 'required', message: VALIDATION_CHECK.required.errorText, }); } }} isError={ - errors[`recruitQuestion_${selectedPart}_questions_1_answer`] + errors[`recruitQuestion_${fnaPart}_questions_1_answer`] ?.message != undefined } errorMessage={ - errors[`recruitQuestion_${selectedPart}_questions_1_answer`] + errors[`recruitQuestion_${fnaPart}_questions_1_answer`] ?.message as string } /> { placeholder="질문을 입력해주세요." onChange={(e) => { if (e.currentTarget.value) { - clearErrors( - `recruitQuestion_${selectedPart}_questions_2_question`, - ); + clearErrors(`recruitQuestion_${fnaPart}_questions_2_question`); } else { - setError( - `recruitQuestion_${selectedPart}_questions_2_question`, - { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }, - ); + setError(`recruitQuestion_${fnaPart}_questions_2_question`, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); } }} isError={ - errors[`recruitQuestion_${selectedPart}_questions_2_question`] + errors[`recruitQuestion_${fnaPart}_questions_2_question`] ?.message != undefined } errorMessage={ - errors[`recruitQuestion_${selectedPart}_questions_2_question`] + errors[`recruitQuestion_${fnaPart}_questions_2_question`] ?.message as string } /> { placeholder="답변을 입력해주세요." onChange={(e) => { if (e.currentTarget.value) { - clearErrors( - `recruitQuestion_${selectedPart}_questions_2_answer`, - ); + clearErrors(`recruitQuestion_${fnaPart}_questions_2_answer`); } else { - setError(`recruitQuestion_${selectedPart}_questions_2_answer`, { + setError(`recruitQuestion_${fnaPart}_questions_2_answer`, { type: 'required', message: VALIDATION_CHECK.required.errorText, }); } }} isError={ - errors[`recruitQuestion_${selectedPart}_questions_2_answer`] + errors[`recruitQuestion_${fnaPart}_questions_2_answer`] ?.message != undefined } errorMessage={ - errors[`recruitQuestion_${selectedPart}_questions_2_answer`] + errors[`recruitQuestion_${fnaPart}_questions_2_answer`] ?.message as string } /> diff --git a/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx b/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx index 55caf27..dc5ca3e 100644 --- a/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/PartCurriculum.tsx @@ -32,7 +32,7 @@ const PartCurriculum = ({ 파트별 소개 diff --git a/src/components/org/OrgAdmin/RecruitSection/index.tsx b/src/components/org/OrgAdmin/RecruitSection/index.tsx index 097c054..66cd506 100644 --- a/src/components/org/OrgAdmin/RecruitSection/index.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/index.tsx @@ -8,8 +8,8 @@ import PartCurriculum from './PartCurriculum'; interface RecruitSectionProps { curriculumPart: PART_KO; onChangeCurriculumPart: (part: PART_KO) => void; - fnaPart: string; - onChangeFnaPart: (part: string) => void; + fnaPart: PART_KO; + onChangeFnaPart: (part: PART_KO) => void; } const RecruitSection = ({ diff --git a/src/components/org/OrgAdmin/index.tsx b/src/components/org/OrgAdmin/index.tsx index 9286176..9eba0ba 100644 --- a/src/components/org/OrgAdmin/index.tsx +++ b/src/components/org/OrgAdmin/index.tsx @@ -70,10 +70,49 @@ function OrgAdmin() { return true; }; + const validateFna = () => { + for (const part of PART_LIST) { + const partQuestion1 = getValues( + `recruitQuestion_${part}_questions_0_question`, + ); + const partAnswer1 = getValues( + `recruitQuestion_${part}_questions_0_answer`, + ); + const partQuestion2 = getValues( + `recruitQuestion_${part}_questions_1_question`, + ); + const partAnswer2 = getValues( + `recruitQuestion_${part}_questions_1_answer`, + ); + const partQuestion3 = getValues( + `recruitQuestion_${part}_questions_2_question`, + ); + const partAnswer3 = getValues( + `recruitQuestion_${part}_questions_2_answer`, + ); + + if ( + !partQuestion1 || + !partAnswer1 || + !partQuestion2 || + !partAnswer2 || + !partQuestion3 || + !partAnswer3 + ) { + setFnaPart(part); + setSelectedPart('지원하기'); + return false; + } + } + return true; + }; + const onSubmit = (data: any) => { const isScheduleValid = validateSchedule(); const isCurriculumValid = validateCurriculum(); - if (isScheduleValid && isCurriculumValid) { + const isFnaValid = validateFna(); + + if (isScheduleValid && isCurriculumValid && isFnaValid) { console.log(data); } }; From e9513e55c8d4c33dd28a75f2a7a3798e658b4012 Mon Sep 17 00:00:00 2001 From: Jeon Eonseok Date: Thu, 28 Nov 2024 15:11:07 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20=EB=B0=98=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/OrgAdmin/RecruitSection/Fna.tsx | 241 +++++------------- src/components/org/OrgAdmin/index.tsx | 35 +-- 2 files changed, 78 insertions(+), 198 deletions(-) diff --git a/src/components/org/OrgAdmin/RecruitSection/Fna.tsx b/src/components/org/OrgAdmin/RecruitSection/Fna.tsx index 0fa2608..3052652 100644 --- a/src/components/org/OrgAdmin/RecruitSection/Fna.tsx +++ b/src/components/org/OrgAdmin/RecruitSection/Fna.tsx @@ -1,4 +1,3 @@ -import { useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { PART_KO, VALIDATION_CHECK } from '@/utils/org'; @@ -7,22 +6,36 @@ import PartCategory from '../PartCategory'; import { StTextArea, StTitle, StTitleWrapper, StWrapper } from '../style'; import { StFnaWrapper, StTextAreaWrapper } from './style'; -interface FanProps { +const QUESTION_NUMBERS = [0, 1, 2]; + +interface FnaProps { fnaPart: PART_KO; onChangeFnaPart: (part: PART_KO) => void; } -const Fna = ({ fnaPart, onChangeFnaPart }: FanProps) => { +const Fna = ({ fnaPart, onChangeFnaPart }: FnaProps) => { const { register, clearErrors, setError, formState: { errors }, } = useFormContext(); + const handleSetSelectedPart = (value: PART_KO) => { onChangeFnaPart(value); }; + const handleValidation = (field: string, value: string) => { + if (value) { + clearErrors(field); + } else { + setError(field, { + type: 'required', + message: VALIDATION_CHECK.required.errorText, + }); + } + }; + return ( @@ -33,182 +46,64 @@ const Fna = ({ fnaPart, onChangeFnaPart }: FanProps) => { onSetSelectedPart={handleSetSelectedPart} /> - - { - if (e.currentTarget.value) { - clearErrors(`recruitQuestion_${fnaPart}_questions_0_question`); - } else { - setError(`recruitQuestion_${fnaPart}_questions_0_question`, { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }); + {QUESTION_NUMBERS.map((index) => ( + + + handleValidation( + `recruitQuestion_${fnaPart}_questions_${index}_question`, + e.currentTarget.value, + ) } - }} - isError={ - errors[`recruitQuestion_${fnaPart}_questions_0_question`] - ?.message != undefined - } - errorMessage={ - errors[`recruitQuestion_${fnaPart}_questions_0_question`] - ?.message as string - } - /> - { - if (e.currentTarget.value) { - clearErrors(`recruitQuestion_${fnaPart}_questions_0_answer`); - } else { - setError(`recruitQuestion_${fnaPart}_questions_0_answer`, { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }); + isError={ + !!errors[ + `recruitQuestion_${fnaPart}_questions_${index}_question` + ] } - }} - isError={ - errors[`recruitQuestion_${fnaPart}_questions_0_answer`] - ?.message != undefined - } - errorMessage={ - errors[`recruitQuestion_${fnaPart}_questions_0_answer`] - ?.message as string - } - /> - - - { - if (e.currentTarget.value) { - clearErrors(`recruitQuestion_${fnaPart}_questions_1_question`); - } else { - setError(`recruitQuestion_${fnaPart}_questions_1_question`, { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }); + errorMessage={ + errors[`recruitQuestion_${fnaPart}_questions_${index}_question`] + ?.message as string } - }} - isError={ - errors[`recruitQuestion_${fnaPart}_questions_1_question`] - ?.message != undefined - } - errorMessage={ - errors[`recruitQuestion_${fnaPart}_questions_1_question`] - ?.message as string - } - /> - { - if (e.currentTarget.value) { - clearErrors(`recruitQuestion_${fnaPart}_questions_1_answer`); - } else { - setError(`recruitQuestion_${fnaPart}_questions_1_answer`, { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }); + /> + + handleValidation( + `recruitQuestion_${fnaPart}_questions_${index}_answer`, + e.currentTarget.value, + ) } - }} - isError={ - errors[`recruitQuestion_${fnaPart}_questions_1_answer`] - ?.message != undefined - } - errorMessage={ - errors[`recruitQuestion_${fnaPart}_questions_1_answer`] - ?.message as string - } - /> - - - { - if (e.currentTarget.value) { - clearErrors(`recruitQuestion_${fnaPart}_questions_2_question`); - } else { - setError(`recruitQuestion_${fnaPart}_questions_2_question`, { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }); + isError={ + !!errors[`recruitQuestion_${fnaPart}_questions_${index}_answer`] } - }} - isError={ - errors[`recruitQuestion_${fnaPart}_questions_2_question`] - ?.message != undefined - } - errorMessage={ - errors[`recruitQuestion_${fnaPart}_questions_2_question`] - ?.message as string - } - /> - { - if (e.currentTarget.value) { - clearErrors(`recruitQuestion_${fnaPart}_questions_2_answer`); - } else { - setError(`recruitQuestion_${fnaPart}_questions_2_answer`, { - type: 'required', - message: VALIDATION_CHECK.required.errorText, - }); + errorMessage={ + errors[`recruitQuestion_${fnaPart}_questions_${index}_answer`] + ?.message as string } - }} - isError={ - errors[`recruitQuestion_${fnaPart}_questions_2_answer`] - ?.message != undefined - } - errorMessage={ - errors[`recruitQuestion_${fnaPart}_questions_2_answer`] - ?.message as string - } - /> - + /> + + ))} ); diff --git a/src/components/org/OrgAdmin/index.tsx b/src/components/org/OrgAdmin/index.tsx index 9eba0ba..09a0aa9 100644 --- a/src/components/org/OrgAdmin/index.tsx +++ b/src/components/org/OrgAdmin/index.tsx @@ -72,33 +72,18 @@ function OrgAdmin() { const validateFna = () => { for (const part of PART_LIST) { - const partQuestion1 = getValues( - `recruitQuestion_${part}_questions_0_question`, - ); - const partAnswer1 = getValues( - `recruitQuestion_${part}_questions_0_answer`, - ); - const partQuestion2 = getValues( - `recruitQuestion_${part}_questions_1_question`, - ); - const partAnswer2 = getValues( - `recruitQuestion_${part}_questions_1_answer`, - ); - const partQuestion3 = getValues( - `recruitQuestion_${part}_questions_2_question`, - ); - const partAnswer3 = getValues( - `recruitQuestion_${part}_questions_2_answer`, + const questionsAndAnswers = Array.from({ length: 3 }, (_, index) => ({ + question: getValues( + `recruitQuestion_${part}_questions_${index}_question`, + ), + answer: getValues(`recruitQuestion_${part}_questions_${index}_answer`), + })); + + const isPartValid = questionsAndAnswers.every( + ({ question, answer }) => !!question && !!answer, ); - if ( - !partQuestion1 || - !partAnswer1 || - !partQuestion2 || - !partAnswer2 || - !partQuestion3 || - !partAnswer3 - ) { + if (!isPartValid) { setFnaPart(part); setSelectedPart('지원하기'); return false; From dca389b5a7a3d2928254803bf4a38ea21f855977 Mon Sep 17 00:00:00 2001 From: Jeon Eonseok Date: Thu, 28 Nov 2024 15:18:40 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20type=20error=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/OrgAdmin/AboutSection/Curriculum/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/org/OrgAdmin/AboutSection/Curriculum/index.tsx b/src/components/org/OrgAdmin/AboutSection/Curriculum/index.tsx index a96a34c..18dc249 100644 --- a/src/components/org/OrgAdmin/AboutSection/Curriculum/index.tsx +++ b/src/components/org/OrgAdmin/AboutSection/Curriculum/index.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { useFormContext } from 'react-hook-form'; -import { PART_LIST, VALIDATION_CHECK } from '@/utils/org'; +import { PART_KO, PART_LIST, VALIDATION_CHECK } from '@/utils/org'; import PartCategory from '../../PartCategory'; import { StInput, StTitle, StWrapper } from '../style'; @@ -21,9 +21,9 @@ const Curriculum = () => { formState: { errors }, } = useFormContext(); - const [selectedPart, setSelectedPart] = useState('기획'); + const [selectedPart, setSelectedPart] = useState('기획'); - const handleSetSelectedPart = (value: string) => { + const handleSetSelectedPart = (value: PART_KO) => { setSelectedPart(value); };