From 4c9d2d80ef4ff2776fa42ff69e2c64b80fba270d Mon Sep 17 00:00:00 2001 From: Denis Thiessen Date: Sun, 5 May 2024 18:28:24 +0200 Subject: [PATCH] feat: Added questionnaire component. --- package-lock.json | 13 ++++ package.json | 1 + .../questionnaire/QuestionComponent.jsx | 63 +++++++++++++++++++ src/components/questionnaire/QuestionData.jsx | 36 +++++++++++ .../questionnaire/QuestionnaireData.jsx | 27 ++++++++ src/pages/TestQuestionnaire.jsx | 22 +++++++ 6 files changed, 162 insertions(+) create mode 100644 src/components/questionnaire/QuestionComponent.jsx create mode 100644 src/components/questionnaire/QuestionData.jsx create mode 100644 src/components/questionnaire/QuestionnaireData.jsx create mode 100644 src/pages/TestQuestionnaire.jsx diff --git a/package-lock.json b/package-lock.json index 11e8dc3..69db57b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "sonification-study-framework", "version": "0.1.0", "dependencies": { + "@geist-ui/core": "^2.3.8", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -2390,6 +2391,18 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@geist-ui/core": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@geist-ui/core/-/core-2.3.8.tgz", + "integrity": "sha512-OKwGgTA4+fBM41eQbqDoUj4XBycZbYH7Ynrn6LPO5yKX7zeWPu/R7HN3vB4/oHt34VTDQI5sDNb1SirHvNyB5w==", + "dependencies": { + "@babel/runtime": "^7.16.7" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", diff --git a/package.json b/package.json index bc8e3b5..1b3283f 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@geist-ui/core": "^2.3.8", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", diff --git a/src/components/questionnaire/QuestionComponent.jsx b/src/components/questionnaire/QuestionComponent.jsx new file mode 100644 index 0000000..d855819 --- /dev/null +++ b/src/components/questionnaire/QuestionComponent.jsx @@ -0,0 +1,63 @@ +// QuestionComponent.js +import React, { useEffect } from "react"; +import { Slider, Input, Radio, Checkbox, Link } from '@geist-ui/core'; + +export default function QuestionComponent(props) { + const { questionData, onUpdateAnswerData } = props; + + useEffect(() => { + // Update questionData when component mounts or props change + questionData.sData({ "id": props.id, "answerValue": questionData.answerValue }); + }, [props.id, questionData.answerValue]); + + // Define a function to handle answer data change + const handleAnswerChange = (val) => { + questionData.sAnswerData(val); + onUpdateAnswerData(questionData.gAnswerData()); // Update answerData in parent component + }; + + // Determine and render answer element based on props + var element; + if (props.answerType === "slider") { + element = ( + + ); + } else if (props.answerType === "radio") { + const btnIndexes = Array.from({ length: props.maxElement }, (_, i) => i + 1); + element = ( + + {btnIndexes.map((x) => {x})} + + ); + } else if (props.answerType === "checkbox") { + const btnIndexes = Array.from({ length: props.maxElement }, (_, i) => i + 1); + element = ( + + {btnIndexes.map((x) => {x})} + + ); + } else { + element = ( + handleAnswerChange(e.target.value)} + clearable + /> + ); + } + + // Render the component + return ( +
+

{props.text}

+ {element} + {props.referBack && ←} + → +
+ ); +} diff --git a/src/components/questionnaire/QuestionData.jsx b/src/components/questionnaire/QuestionData.jsx new file mode 100644 index 0000000..2134ce5 --- /dev/null +++ b/src/components/questionnaire/QuestionData.jsx @@ -0,0 +1,36 @@ +import {useState} from "react"; + +export function useQuestionData() { + const [data, setData] = useState({}); + + function setQuestionData(questionData) { + setData(questionData); + }; + + function getQuestionData() { + return data; + } + + function setAnswerValue(val) { + data.answerValue = val; + setData(data); + } + + function getAnswerValue() { + return data.answerValue; + } + + function reset() { + setData({}); + }; + + const inputProps = { + sData: setQuestionData, + gData: getQuestionData, + sAnswerData: setAnswerValue, + gAnswerData: getAnswerValue, + r: reset + }; + + return inputProps; +} \ No newline at end of file diff --git a/src/components/questionnaire/QuestionnaireData.jsx b/src/components/questionnaire/QuestionnaireData.jsx new file mode 100644 index 0000000..3f1c345 --- /dev/null +++ b/src/components/questionnaire/QuestionnaireData.jsx @@ -0,0 +1,27 @@ +// useQuestionComponent.js +import { useState, useEffect } from "react"; +import { useQuestionData } from "./QuestionData"; + +export function useQuestionComponent(answerType, maxElement, text, referBack, referTo) { + const [answerData, setAnswerData] = useState(null); + const questionData = useQuestionData({}); + + useEffect(() => { + setAnswerData(questionData.gAnswerData()); + }, [questionData]); + + const handleUpdateAnswerData = (data) => { + setAnswerData(data); + }; + + return { + questionData, + answerData, + handleUpdateAnswerData, // Pass the function here + answerType, + maxElement, + text, + referBack, + referTo + }; +} diff --git a/src/pages/TestQuestionnaire.jsx b/src/pages/TestQuestionnaire.jsx new file mode 100644 index 0000000..a426968 --- /dev/null +++ b/src/pages/TestQuestionnaire.jsx @@ -0,0 +1,22 @@ +import React from "react"; +import { useParams } from 'react-router-dom'; +import QuestionComponent from "../components/questionnaire/QuestionComponent"; +import { useQuestionComponent } from "../components/questionnaire/QuestionnaireData"; + + +export default function TestQuestionnaire() { + const { id } = useParams() + + const q1Props = useQuestionComponent("checkbox", 4, "Lorem Ipsum", "./info", "./q2"); + const q2Props = useQuestionComponent("slider", 8, "Lorem Ipsum Ye", "./q1", "./info"); + + const questionProperties = {"q1": q1Props, "q2": q2Props}; + const questionProperty = questionProperties[id]; + + return ( +
+ +

Current Answer Data: {JSON.stringify(questionProperty.answerData)}

+
+ ); +}