157 lines
4.0 KiB
TypeScript
157 lines
4.0 KiB
TypeScript
import { ApolloError, useMutation } from '@apollo/client'
|
|
import { ChangeEvent, FormEvent, useState } from 'react'
|
|
import { CREATEFORM } from '../../apollo'
|
|
import { MutationCreateFormArgs, ServerAnswer } from '../../apollo/typeDefs.gen'
|
|
|
|
type FormQuestion<T extends string> = {
|
|
title: string
|
|
type: T
|
|
variants: string[]
|
|
}
|
|
|
|
type Form<T extends string> = {
|
|
title: string
|
|
questions: FormQuestion<T>[]
|
|
}
|
|
|
|
export type FormatQuestionsToSubmitType = <T extends string>(
|
|
questions: FormQuestion<T>[]
|
|
) => string
|
|
|
|
interface ICreateFormMutation {
|
|
createForm: ServerAnswer
|
|
}
|
|
|
|
type FormSubmitType = (e: FormEvent<HTMLFormElement>) => void
|
|
|
|
type HandleFormTitleChangeType = (e: ChangeEvent<HTMLInputElement>) => void
|
|
|
|
type CreateQuestionType<T extends string> = (type: T) => void
|
|
|
|
type HandleQuestionTitleChangeType = (
|
|
questionNumber: number,
|
|
e: ChangeEvent<HTMLInputElement>
|
|
) => void
|
|
|
|
type AddVariantType = (questionNumber: number) => void
|
|
|
|
type HandleAnswerVariantChangeType = (
|
|
questionNumber: number,
|
|
variantNumber: number,
|
|
e: ChangeEvent<HTMLInputElement>
|
|
) => void
|
|
|
|
type UseFormCreatorHookTurple<T extends string> = [
|
|
Form<T>,
|
|
[
|
|
FormSubmitType,
|
|
{
|
|
submitData: ICreateFormMutation | null | undefined
|
|
submitError: ApolloError | undefined
|
|
submitLoading: boolean
|
|
}
|
|
],
|
|
{
|
|
handleFormTitleChange: HandleFormTitleChangeType
|
|
addQuestion: CreateQuestionType<T>
|
|
handleQuestionTitleChange: HandleQuestionTitleChangeType
|
|
handleAnswerVariantChange: HandleAnswerVariantChangeType
|
|
addVariant: AddVariantType
|
|
}
|
|
]
|
|
|
|
export const useFormCreator = <T extends string>(
|
|
formatQuestionsToSubmit: FormatQuestionsToSubmitType
|
|
): UseFormCreatorHookTurple<T> => {
|
|
const [form, setState] = useState<Form<T>>({ title: '', questions: [] })
|
|
|
|
const [
|
|
doFormCreation,
|
|
{ error: submitError, data: submitData, loading: submitLoading },
|
|
] = useMutation<ICreateFormMutation, MutationCreateFormArgs>(CREATEFORM, {
|
|
variables: {
|
|
title: form.title,
|
|
questions: formatQuestionsToSubmit<T>(form.questions),
|
|
},
|
|
})
|
|
|
|
const formSubmit: FormSubmitType = (e) => {
|
|
e.preventDefault()
|
|
console.log({
|
|
title: form.title,
|
|
questions: formatQuestionsToSubmit<T>(form.questions),
|
|
})
|
|
doFormCreation()
|
|
}
|
|
|
|
const handleFormTitleChange: HandleFormTitleChangeType = (e) => {
|
|
const title = e.currentTarget.value
|
|
setState((prev) => ({ ...prev, title }))
|
|
}
|
|
|
|
const createQuestion: CreateQuestionType<T> = (type) => {
|
|
setState(({ title, questions }) => ({
|
|
title,
|
|
questions: questions.concat({ title: '', type, variants: [] }),
|
|
}))
|
|
}
|
|
|
|
const handleQuestionTitleChange: HandleQuestionTitleChangeType = (
|
|
questionNumber,
|
|
e
|
|
) => {
|
|
const questionTitle = e.currentTarget.value
|
|
setState(({ title, questions }) => ({
|
|
title,
|
|
questions: questions.map((el, index) =>
|
|
index === questionNumber ? { ...el, title: questionTitle } : el
|
|
),
|
|
}))
|
|
}
|
|
|
|
const handleAnswerVariantChange: HandleAnswerVariantChangeType = (
|
|
questionNumber,
|
|
variantNumber,
|
|
e
|
|
) => {
|
|
const variantText = e.currentTarget.value
|
|
setState(({ title, questions }) => ({
|
|
title,
|
|
questions: questions.map((question, questionIndex) =>
|
|
questionIndex === questionNumber
|
|
? {
|
|
...question,
|
|
variants: question.variants.map((variant, variantIndex) =>
|
|
variantIndex === variantNumber ? variantText : variant
|
|
),
|
|
}
|
|
: question
|
|
),
|
|
}))
|
|
}
|
|
|
|
const addVariant: AddVariantType = (questionNumber) => {
|
|
console.log()
|
|
setState(({ title, questions }) => ({
|
|
title,
|
|
questions: questions.map((el, index) => ({
|
|
...el,
|
|
variants:
|
|
index === questionNumber ? el.variants.concat('') : el.variants,
|
|
})),
|
|
}))
|
|
}
|
|
|
|
return [
|
|
form,
|
|
[formSubmit, { submitData, submitError, submitLoading }],
|
|
{
|
|
handleFormTitleChange,
|
|
addQuestion: createQuestion,
|
|
handleQuestionTitleChange,
|
|
handleAnswerVariantChange,
|
|
addVariant,
|
|
},
|
|
]
|
|
}
|