From 0735ad940059cdff5cca1adb046b15ba1045fe75 Mon Sep 17 00:00:00 2001 From: Ethen1264 Date: Mon, 27 Jan 2025 23:09:05 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=90=9BFix:=20create=20form=20submit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/form/[expo_id]/route.ts | 5 +++- src/shared/types/create-form/type.ts | 10 ++++++++ src/views/create-form/api/createForm.ts | 11 ++------- .../create-form/model/formCreateRouter.ts | 9 +++----- src/views/create-form/model/useCreateForm.ts | 12 +++------- src/views/create-form/ui/createForm/index.tsx | 23 ++++++++++--------- .../ui/ExpoCreatedContainer/index.tsx | 2 +- 7 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/app/api/form/[expo_id]/route.ts b/src/app/api/form/[expo_id]/route.ts index 26e33f0..c47e7ec 100644 --- a/src/app/api/form/[expo_id]/route.ts +++ b/src/app/api/form/[expo_id]/route.ts @@ -20,7 +20,10 @@ export async function POST( : {}; try { const response = await apiClient.post(`/form/${expo_id}`, body, config); - return NextResponse.json(response.data); + return new NextResponse(JSON.stringify(response.data), { + status: response.status, + headers: { 'Content-Type': 'application/json' }, + }); } catch (error) { const axiosError = error as AxiosError<{ message: string }>; diff --git a/src/shared/types/create-form/type.ts b/src/shared/types/create-form/type.ts index 7fb0a52..54c87c1 100644 --- a/src/shared/types/create-form/type.ts +++ b/src/shared/types/create-form/type.ts @@ -21,3 +21,13 @@ export interface OptionProps { index: number; isCheckBox?: boolean; } + +export interface CreateFormRequest { + informationImage: string; + participantType: string; + dynamicForm: { + title: string; + formType: string; + jsonData: string; + }[]; +} diff --git a/src/views/create-form/api/createForm.ts b/src/views/create-form/api/createForm.ts index 315f744..8b75f77 100644 --- a/src/views/create-form/api/createForm.ts +++ b/src/views/create-form/api/createForm.ts @@ -1,18 +1,11 @@ import axios from 'axios'; +import { CreateFormRequest } from '@/shared/types/create-form/type'; export const createForm = async ({ data, id, }: { - data: { - informationImage: string; - participantType: string; - dynamicForm: { - title: string; - formType: string; - jsonData: Record; - }[]; - }; + data: CreateFormRequest; id: string; }) => { const response = await axios.post(`/api/form/${id}`, data); diff --git a/src/views/create-form/model/formCreateRouter.ts b/src/views/create-form/model/formCreateRouter.ts index f4e5a81..6f0443a 100644 --- a/src/views/create-form/model/formCreateRouter.ts +++ b/src/views/create-form/model/formCreateRouter.ts @@ -10,13 +10,10 @@ export const formCreateRouter = ({ router: AppRouterInstance; }) => { switch (navigation) { - case 'standard': - router.push(`/create-form/${id}?navigation=training`); + case 'STANDARD': + router.push(`/create-form/${id}?navigation=TRAINEE`); break; - case 'training': - router.push(`/create-form/${id}?navigation=survey`); - break; - case 'survey': + case 'TRAINEE': router.push('/'); break; default: diff --git a/src/views/create-form/model/useCreateForm.ts b/src/views/create-form/model/useCreateForm.ts index f023de3..8dd3861 100644 --- a/src/views/create-form/model/useCreateForm.ts +++ b/src/views/create-form/model/useCreateForm.ts @@ -1,6 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime'; import { toast } from 'react-toastify'; +import { CreateFormRequest } from '@/shared/types/create-form/type'; import { createForm } from '../api/createForm'; import { formCreateRouter } from './formCreateRouter'; @@ -13,15 +14,8 @@ export const useCreateForm = ( return useMutation({ mutationKey: ['createForm', id, navigation], - mutationFn: (formattedData: { - informationImage: string; - participantType: string; - dynamicForm: { - title: string; - formType: string; - jsonData: Record; - }[]; - }) => createForm({ data: formattedData, id }), + mutationFn: (formattedData: CreateFormRequest) => + createForm({ data: formattedData, id }), onSuccess: () => { toast.success('폼이 생성되었습니다.'); formCreateRouter({ id, navigation, router }); diff --git a/src/views/create-form/ui/createForm/index.tsx b/src/views/create-form/ui/createForm/index.tsx index 3b4a0b3..0ebd96c 100644 --- a/src/views/create-form/ui/createForm/index.tsx +++ b/src/views/create-form/ui/createForm/index.tsx @@ -37,16 +37,18 @@ const CreateForm = ({ id }: { id: string }) => { const onSubmit = (data: FormValues) => { const formattedData = { informationImage: '', - participantType: navigation?.toUpperCase() || 'STANDARD', + participantType: navigation || 'STANDARD', dynamicForm: data.questions.map((question) => ({ title: question.title, formType: question.formType, - jsonData: question.options.reduce( - (acc, option, index) => { - acc[(index + 1).toString()] = option.value; - return acc; - }, - {} as Record, + jsonData: JSON.stringify( + question.options.reduce( + (acc, option, index) => { + acc[(index + 1).toString()] = option.value; + return acc; + }, + {} as Record, + ), ), })), }; @@ -55,9 +57,8 @@ const CreateForm = ({ id }: { id: string }) => { }; const navigationTitles: Record = { - standard: '참가자 폼', - training: '연수자 폼', - survey: '만족도 조사 폼', + STANDARD: '참가자 폼', + TRAINEE: '연수자 폼', }; useEffect(() => { @@ -72,7 +73,7 @@ const CreateForm = ({ id }: { id: string }) => { className="mx-auto w-full max-w-[792px] flex-1 space-y-4 px-5" >
{fields.map((field, index) => ( diff --git a/src/widgets/expo-created/ui/ExpoCreatedContainer/index.tsx b/src/widgets/expo-created/ui/ExpoCreatedContainer/index.tsx index 411636c..7544951 100644 --- a/src/widgets/expo-created/ui/ExpoCreatedContainer/index.tsx +++ b/src/widgets/expo-created/ui/ExpoCreatedContainer/index.tsx @@ -8,7 +8,7 @@ import { Button } from '@/shared/ui'; const ExpoCreatedContainer = ({ id }: { id: string }) => { const router = useRouter(); const handleButton = () => { - router.push(`/create-form/${id}?navigation=standard`); + router.push(`/create-form/${id}?navigation=STANDARD`); }; return (
From 3c66fecef62956568d0f453434a6e1762043ffde Mon Sep 17 00:00:00 2001 From: Ethen1264 Date: Thu, 30 Jan 2025 21:45:13 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9BFix:=20create-form?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/create-form/index.tsx | 1 - .../create-form/ui/FormTitle/index.tsx | 4 ++- .../create-form/ui/OptionItem/index.tsx | 2 +- .../create-form/ui/TextOption/index.tsx | 30 ----------------- src/shared/ui/ToggleButton/index.tsx | 6 ++-- src/views/create-form/ui/createForm/index.tsx | 18 +++++++++-- .../create-form/ui/FormContainer/index.tsx | 32 +++++++++++-------- 7 files changed, 41 insertions(+), 52 deletions(-) delete mode 100644 src/entities/create-form/ui/TextOption/index.tsx diff --git a/src/entities/create-form/index.tsx b/src/entities/create-form/index.tsx index 96cb643..b0e6524 100644 --- a/src/entities/create-form/index.tsx +++ b/src/entities/create-form/index.tsx @@ -6,6 +6,5 @@ export { default as FormTypeSelect } from './ui/FormTypeSelect'; export { default as MultipleChoiceOption } from './ui/MultipleChoiceOption'; export { default as PictureOption } from './ui/PictureOption'; export { default as RequiredToggle } from './ui/RequiredToggle'; -export { default as TextOption } from './ui/TextOption'; export { default as CreateFormButton } from './ui/CreateFormButton'; export { default as CheckBox } from './ui/CheckBox'; diff --git a/src/entities/create-form/ui/FormTitle/index.tsx b/src/entities/create-form/ui/FormTitle/index.tsx index abe448e..69c895f 100644 --- a/src/entities/create-form/ui/FormTitle/index.tsx +++ b/src/entities/create-form/ui/FormTitle/index.tsx @@ -11,7 +11,9 @@ const FormTitle = ({ register, index }: Props) => { return (
diff --git a/src/entities/create-form/ui/OptionItem/index.tsx b/src/entities/create-form/ui/OptionItem/index.tsx index 1fa02d0..2e47745 100644 --- a/src/entities/create-form/ui/OptionItem/index.tsx +++ b/src/entities/create-form/ui/OptionItem/index.tsx @@ -25,7 +25,7 @@ const OptionItem = ({
{icon} diff --git a/src/entities/create-form/ui/TextOption/index.tsx b/src/entities/create-form/ui/TextOption/index.tsx deleted file mode 100644 index 2a5157e..0000000 --- a/src/entities/create-form/ui/TextOption/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { OptionProps } from '@/shared/types/create-form/type'; -import OptionItem from '../OptionItem'; -import OtherOption from '../OtherOptionProps'; - -const TextOption = ({ - fields, - remove, - register, - index, - isCheckBox, -}: OptionProps) => { - return ( -
- {fields.map((option, optionIndex) => ( - - ))} - {isCheckBox ? : null} -
- ); -}; - -export default TextOption; diff --git a/src/shared/ui/ToggleButton/index.tsx b/src/shared/ui/ToggleButton/index.tsx index 730e5eb..6ee2f9b 100644 --- a/src/shared/ui/ToggleButton/index.tsx +++ b/src/shared/ui/ToggleButton/index.tsx @@ -14,11 +14,11 @@ function ToggleButton() { return ( diff --git a/src/views/create-form/ui/createForm/index.tsx b/src/views/create-form/ui/createForm/index.tsx index 0ebd96c..4a34624 100644 --- a/src/views/create-form/ui/createForm/index.tsx +++ b/src/views/create-form/ui/createForm/index.tsx @@ -3,7 +3,9 @@ import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect } from 'react'; import { useFieldArray, useForm } from 'react-hook-form'; +import { toast } from 'react-toastify'; import { CreateFormButton } from '@/entities/create-form'; +import { handleFormErrors } from '@/shared/model/formErrorUtils'; import { preventEvent } from '@/shared/model/preventEvent'; import { FormValues, Option } from '@/shared/types/create-form/type'; import { Button, PageHeader } from '@/shared/ui'; @@ -28,6 +30,10 @@ const CreateForm = ({ id }: { id: string }) => { name: 'questions', }); + const showError = (message: string) => { + toast.error(message); + }; + const { mutate: createForm, isPending, @@ -35,6 +41,10 @@ const CreateForm = ({ id }: { id: string }) => { } = useCreateForm(id, navigation, router); const onSubmit = (data: FormValues) => { + if (fields.length === 0) { + toast.error('최소 한 개의 폼을 추가해주세요'); + return; + } const formattedData = { informationImage: '', participantType: navigation || 'STANDARD', @@ -52,7 +62,6 @@ const CreateForm = ({ id }: { id: string }) => { ), })), }; - console.log(formattedData); createForm(formattedData); }; @@ -69,8 +78,11 @@ const CreateForm = ({ id }: { id: string }) => {
{ + console.log(errors); + handleFormErrors(errors, showError); + })} + className="mx-auto w-full max-w-[792px] flex-1 space-y-4 px-5 pb-5" > = { - SENTENCE: ( - - ), CHECKBOX: ( { + if (selectedOption?.value === 'SENTENCE') { + setValue(`questions.${index}.options`, []); + } + + if ( + selectedOption?.value === 'SENTENCE' || + selectedOption?.value === 'IMAGE' + ) { + setIsCheckBox(false); + } + }, [selectedOption, index, setValue]); + return (
@@ -123,10 +126,13 @@ const FormContainer = ({
{renderOptionComponent()}
- append({ value: '' })} /> + {selectedOption?.value !== 'SENTENCE' ? ( + append({ value: '' })} /> + ) : null}
- {selectedOption?.value !== 'IMAGE' ? ( + {selectedOption?.value !== 'IMAGE' && + selectedOption?.value !== 'SENTENCE' ? (