diff --git a/src/components/Widgets/SignupQuestionsWidget/OptionsWidget.tsx b/src/components/Widgets/SignupQuestionsWidget/OptionsWidget.tsx index ab57700..1be4d07 100644 --- a/src/components/Widgets/SignupQuestionsWidget/OptionsWidget.tsx +++ b/src/components/Widgets/SignupQuestionsWidget/OptionsWidget.tsx @@ -1,49 +1,72 @@ import React from "react"; import Checkbox from "@components/Widgets/Checkbox/Checkbox"; +import { SignupFormQuestion } from "@models/Signup"; +import { Lang } from "src/i18n"; import { - Question, InputProps, optionTypes, SignupQuestionError, + InputProps, optionTypes, SignupQuestionError, } from "./common"; interface OptionsWidgetProps { inputProps: InputProps; - onChange: (value: Question[]) => void; + onChange: (value: SignupFormQuestion[]) => void; } class OptionsWidget extends React.Component { - handleListOptionsChange = (questions: Question[], index: number): React.ChangeEventHandler => (event) => { + handleListOptionsChange = (questions: SignupFormQuestion[], index: number, lang: Lang): React.ChangeEventHandler => (event) => { const { onChange } = this.props; const val = event.target.value; const lst = val.split(";").map((p) => p.trimLeft()); - // eslint-disable-next-line no-param-reassign - questions[index].options = lst; + + if (lang === "fi") { + // eslint-disable-next-line no-param-reassign + questions[index].options = { + ...questions[index].options, + enumNames_fi: lst, + enum: lst, + }; + } + if (lang === "en") { + // eslint-disable-next-line no-param-reassign + questions[index].options = { + ...questions[index].options, + enumNames_en: lst, + }; + } onChange(questions); }; - handleTextOptionsChange = (questions: Question[], index: number): React.ChangeEventHandler => (event) => { + handleInfoTextOptionsChange = (questions: SignupFormQuestion[], index: number, lang: Lang): React.ChangeEventHandler => (event) => { const { onChange } = this.props; const val = event.target.value; - // eslint-disable-next-line no-param-reassign - questions[index].options = val as unknown as string[]; // TODO: Check type + + if (lang === "fi") { + // eslint-disable-next-line no-param-reassign + questions[index].description_fi = val; + } + if (lang === "en") { + // eslint-disable-next-line no-param-reassign + questions[index].description_en = val; + } onChange(questions); }; - handleIntegerOptionsChange = (questions: Question[], index: number): React.ChangeEventHandler => (event) => { + handleIntegerOptionsChange = (questions: SignupFormQuestion[], index: number): React.ChangeEventHandler => (event) => { const { onChange } = this.props; const val = event.target.value; if (val !== "") { const lst = val.split(";").map((p) => p.trimLeft()); // Ignore everything else but the two first values // eslint-disable-next-line no-param-reassign - questions[index].options = lst.splice(0, 2); + questions[index].options.enum = lst.splice(0, 2); } else { // eslint-disable-next-line no-param-reassign - questions[index].options = []; + questions[index].options.enum = []; } onChange(questions); }; - handleRequiredChange = (questions: Question[], index: number): React.ChangeEventHandler => (event) => { + handleRequiredChange = (questions: SignupFormQuestion[], index: number): React.ChangeEventHandler => (event) => { const { onChange } = this.props; const val: boolean = event.target.checked; // eslint-disable-next-line no-param-reassign @@ -67,7 +90,7 @@ class OptionsWidget extends React.Component { render(): JSX.Element { const { inputProps } = this.props; const { - type, value, questions, index, + value, type, questions, index, } = inputProps; if (!optionTypes.includes(type)) { throw new SignupQuestionError(`Question widget type "${type}" not in types array.`); @@ -82,25 +105,29 @@ class OptionsWidget extends React.Component { <> + - {this.requiredField()} ); } if (type === "integer") { - const lst = value as string[]; - const joinedValue = lst.join(";"); return ( <> {this.requiredField()} @@ -109,15 +136,20 @@ class OptionsWidget extends React.Component { } if (type === "radiobutton") { - const lst = value as string[]; - const joinedValue = lst.join(";"); return ( <> + @@ -125,15 +157,20 @@ class OptionsWidget extends React.Component { } if (type === "checkbox") { - const lst = value as string[]; - const joinedValue = lst.join(";"); return ( <> + {this.requiredField()} diff --git a/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx b/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx index 5fba0e6..e000707 100644 --- a/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx +++ b/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx @@ -2,7 +2,8 @@ import React, { ReactNode } from "react"; import styled from "styled-components"; import { Draggable } from "react-beautiful-dnd"; import colors from "@theme/colors"; -import { Question, InputProps } from "./common"; +import { SignupFormQuestion } from "@models/Signup"; +import { Lang } from "src/i18n"; import OptionsWidget from "./OptionsWidget"; import TypeWidget from "./TypeWidget"; import QuestionElement from "./Question"; @@ -16,26 +17,28 @@ const WidgetRow = styled.div` `; interface QuestionListProps { - questions: Question[]; + questions: SignupFormQuestion[]; innerRef: React.Ref; placeholder: ReactNode; - onChange: (value: Question[]) => void; + onChange: (value: SignupFormQuestion[]) => void; } class QuestionList extends React.Component { - renderTextWidget = ({ questions, value, index }: InputProps): JSX.Element => ( - - ); - - handleNameInputChange = (questions: Question[], index: number): React.ChangeEventHandler => (event) => { + handleNameInputChange = (questions: SignupFormQuestion[], index: number, lang: Lang): React.ChangeEventHandler => (event) => { const { onChange } = this.props; const val = event.target.value; - // eslint-disable-next-line no-param-reassign - questions[index].name = val; + if (lang === "fi") { + // eslint-disable-next-line no-param-reassign + questions[index].title_fi = val; + } + if (lang === "en") { + // eslint-disable-next-line no-param-reassign + questions[index].title_en = val; + } onChange(questions); }; - handleElementRemove = (questions: Question[], index: number) => (): void => { + handleElementRemove = (questions: SignupFormQuestion[], index: number) => (): void => { const { onChange } = this.props; const newQuestions = [...questions]; newQuestions.splice(index, 1); @@ -45,11 +48,6 @@ class QuestionList extends React.Component { renderQuestions(): JSX.Element[] { const { questions, onChange } = this.props; return questions.map((q, index) => { - const nameWidgetProps = { - value: q.name, type: "text", questions, index, - }; - const nameWidget = this.renderTextWidget(nameWidgetProps); - const dataProps = { value: q.options, type: q.type, questions, index, }; @@ -66,7 +64,8 @@ class QuestionList extends React.Component { - {nameWidget} + + {typeSelectWidget} {optionsWidget} diff --git a/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx b/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx index 7e3c084..71aa0ae 100644 --- a/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx +++ b/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx @@ -4,8 +4,8 @@ import shortid from "shortid"; import { DragDropContext, Droppable } from "react-beautiful-dnd"; import colors from "@theme/colors"; import AddIcon from "@components/AddIcon"; +import { SignupFormQuestion } from "@models/Signup"; import QuestionList from "./QuestionList"; -import { Question } from "./common"; const Widget = styled.div` & > button { @@ -40,24 +40,25 @@ interface SignupQuestionsWidgetProps { } const SignupQuestionsWidget: React.FC = ({ value, onFocus, onChange }) => { - const onValueChange = (questions: Question[]) => { + const onValueChange = (questions: SignupFormQuestion[]) => { const newValue = JSON.stringify(questions); onChange(newValue); }; const handleNewRowClick = (questions) => () => { - const newRow: Question = { + const newRow: SignupFormQuestion = { id: shortid.generate(), - name: `Question #${questions.length + 1}`, - options: [], + title_fi: `Question #${questions.length + 1}`, + title_en: `Question #${questions.length + 1}`, + options: undefined, type: "text", }; - const newQuestions: Question[] = questions.concat([newRow]); + const newQuestions: SignupFormQuestion[] = questions.concat([newRow]); onValueChange(newQuestions); }; - const handleDragEnd = (questions: Question[]) => (result) => { + const handleDragEnd = (questions: SignupFormQuestion[]) => (result) => { const srcIndex = result.source.index; const dstIndex = result.destination.index; const srcCopy = { ...questions[srcIndex] }; @@ -66,7 +67,7 @@ const SignupQuestionsWidget: React.FC = ({ value, on onValueChange(questions); }; - const questions = JSON.parse(value) as Question[]; + const questions: SignupFormQuestion[] = JSON.parse(value); return ( diff --git a/src/components/Widgets/SignupQuestionsWidget/TypeWidget.tsx b/src/components/Widgets/SignupQuestionsWidget/TypeWidget.tsx index 3541360..4d0b9a1 100644 --- a/src/components/Widgets/SignupQuestionsWidget/TypeWidget.tsx +++ b/src/components/Widgets/SignupQuestionsWidget/TypeWidget.tsx @@ -1,32 +1,29 @@ import React from "react"; -import { Question, InputProps, optionTypes } from "./common"; +import { SignupFormQuestion } from "@models/Signup"; +import { InputProps, optionTypes } from "./common"; interface TypeWidgetProps { inputProps: InputProps; - onChange: (value: Question[]) => void; + onChange: (value: SignupFormQuestion[]) => void; } -class TypeWidget extends React.Component { - handleTypeChange = (questions: Question[], index: number): React.ChangeEventHandler => (event) => { - const { onChange } = this.props; - const val = event.target.value as Question["type"]; +const TypeWidget = ({ onChange, inputProps }: TypeWidgetProps): JSX.Element => { + const handleTypeChange = (questions: SignupFormQuestion[], index: number): React.ChangeEventHandler => (event) => { + const val = event.target.value as SignupFormQuestion["type"]; // eslint-disable-next-line no-param-reassign questions[index].type = val; onChange(questions); }; - render(): JSX.Element { - const { inputProps } = this.props; - const { type, questions, index } = inputProps; - const options = optionTypes.map((t) => ( - - )); - return ( - - ); - } -} + const { questions, type, index } = inputProps; + const options = optionTypes.map((t) => ( + + )); + return ( + + ); +}; export default TypeWidget; diff --git a/src/components/Widgets/SignupQuestionsWidget/common.ts b/src/components/Widgets/SignupQuestionsWidget/common.ts index 753a8fd..5e73f16 100644 --- a/src/components/Widgets/SignupQuestionsWidget/common.ts +++ b/src/components/Widgets/SignupQuestionsWidget/common.ts @@ -1,3 +1,5 @@ +import type { SignupFormQuestion } from "@models/Signup"; + export interface Question { id: string; name: string; @@ -10,8 +12,8 @@ export interface Question { export interface InputProps { index: number; - value: string | string[]; - questions: Question[]; + value: SignupFormQuestion["options"]; + questions: SignupFormQuestion[]; type: string; } diff --git a/src/pages/admin/signups/[id]/list.tsx b/src/pages/admin/signups/[id]/list.tsx index d474696..a3723dc 100644 --- a/src/pages/admin/signups/[id]/list.tsx +++ b/src/pages/admin/signups/[id]/list.tsx @@ -49,7 +49,7 @@ const SignupEmailPage: NextPage = () => { // TODO: ATM we filter 'info' questions from table here. Maybe remove them from answer JSON altogether? const questions = signupForm ? signupForm.questions.filter((q) => q.type !== "info").map((q) => ({ - title: q.name, + title: q.title_fi, id: q.id, })) : [];