From 62456f41288eb0f03c5092d36610d566f275c8b5 Mon Sep 17 00:00:00 2001 From: Max Nanis Date: Tue, 3 Jun 2025 20:06:44 +0700 Subject: selectQuestionById, useMemo selector (MultiChoice.choices makes a lot of lookup). Setting up the Questions view to do Pagination to tab through available questions and view one at a time --- src/pages/Questions.tsx | 154 ++++++++++++++++++++++++------------------------ 1 file changed, 77 insertions(+), 77 deletions(-) (limited to 'src/pages') diff --git a/src/pages/Questions.tsx b/src/pages/Questions.tsx index 0a3f43e..9eb7cba 100644 --- a/src/pages/Questions.tsx +++ b/src/pages/Questions.tsx @@ -1,23 +1,29 @@ -import React from 'react' -import {UpkQuestion} from "@/api"; -import {UpkQuestionChoice} from "@/api/models/upk-question-choice.ts"; +import React, {useMemo, useState} from 'react' +import {UpkQuestion, UpkQuestionChoice} from "@/api"; import {Card, CardContent, CardHeader} from "@/components/ui/card.tsx"; -import {useAppSelector} from "@/hooks.ts"; +import {useAppDispatch, useAppSelector} from "@/hooks.ts"; +import {addAnswer, makeSelectChoicesByQuestion} from "@/models/answerSlice.ts"; +import {selectQuestionById} from "@/models/questionSlice.ts"; +import {useSelector} from "react-redux"; +import {Button} from "@/components/ui/button" +import { + Pagination, + PaginationContent, + PaginationItem, + PaginationLink, + PaginationNext, +} from "@/components/ui/pagination" const TextEntry: React.FC<{ question: UpkQuestion }> = ({question}) => { - // const dispatch = useAppDispatch() - // const buckets = useAppSelector(state => state.buckets) - - // const handleInputChange = (event: React.ChangeEvent) => { - // // Don't allow any input changes after they triggered submission... - // if (question._complete || question._processing) { - // return - // } - // - // // Assign the input value as an answer to the question - // const newValue = event.target.value; - // dispatch(setAnswer({questionId: question.questionId, val: newValue})) - // }; + const dispatch = useAppDispatch() + const selectAnswer = useMemo(() => makeSelectChoicesByQuestion(question), [question]); + const answer = useSelector(selectAnswer); + + const handleInputChange = (event: React.ChangeEvent) => { + dispatch(addAnswer({question: question, val: event.target.value})) + }; + + console.log("TextEntry.answer", answer) return ( @@ -30,83 +36,52 @@ const TextEntry: React.FC<{ question: UpkQuestion }> = ({question}) => { id="text-entry-input" aria-describedby="" placeholder="" - // onInput={handleInputChange} + onKeyDown={handleInputChange} /> - {/*{question.error_msg}*/} + {answer.error_msg} ) } const MultiChoiceItem: React.FC<{ question: UpkQuestion, choice: UpkQuestionChoice }> = ({question, choice}) => { - - // const onclick = function () { - // // Assign the input value as an answer to the question - // let answer = getAnswer; - // let click_value = childView.model.get("choice_id") - // - // switch (question.selector) { - // - // case "SA": /// Single Answer - // answer.set("values", [{"value": click_value}]); - // break - // - // case "MA": /// Multi Answer - // let current_values: AnswerValueItemType[] = answer.get("values") ?? []; - // - // if (includes(map(current_values, "value"), click_value)) { - // // The item has already been selected - // current_values = remove(current_values, (v) => { - // return v["value"] != click_value - // }) - // - // } else { - // // It's a new selection - // current_values.push({"value": click_value}) - // } - // - // answer.set("values", current_values); - // break - // } - // childView.render(); - // - // // Validate the answer and show any information - // let res: QuestionValidationResult = this.model.validateAnswer() - // this.ui.message.text(res["message"]); - // } - - // const render = function () { - // let answer = this.getOption("answer"); - // let current_values: AnswerValueItemType[] = answer.get("values") ?? []; - // let current_values_values = map(current_values, "value"); - // - // if (includes(current_values_values, this.model.get("choice_id"))) { - // this.$el.addClass("selected"); - // } - // } + const dispatch = useAppDispatch() + const selectAnswer = useMemo(() => makeSelectChoicesByQuestion(question), [question]); + const answer = useSelector(selectAnswer); + const selected = answer.values.includes(choice.choice_id) return ( - <> + ) } const MultipleChoice: React.FC<{ question: UpkQuestion }> = ({question}) => { + const selectAnswer = useMemo(() => makeSelectChoicesByQuestion(question), [question]); + const answer = useSelector(selectAnswer); return ( {question.question_text} - {/*{question.error_msg}*/} + {answer.error_msg} - { - question.choices.map(c => { - return - }) - } +
    + { + question.choices.map(c => { + return + }) + } +
) @@ -128,6 +103,12 @@ const ProfileQuestionFull: React.FC = ({question}) => { const QuestionsPage = () => { const questions = useAppSelector(state => state.questions) + const [activeQuestionID, setQuestionID] = useState(() => questions[0].question_id); + + const selectQuestion = useMemo(() => selectQuestionById(activeQuestionID), [questions]); + const question = useSelector(selectQuestion); + + console.log(activeQuestionID, questions) return (
@@ -135,11 +116,30 @@ const QuestionsPage = () => { A total of {questions.length} questions are available.

- { - questions.map(q => { - return ; - }) - } + + + { + questions.map((q, i) => { + return ( + + setQuestionID(q.question_id)} + > + {i+1} + + + ) + }) + } + + + + + + + + +
); } -- cgit v1.2.3