From ce1a12c40a9c43c06c121b5ed01e607a632d20f5 Mon Sep 17 00:00:00 2001 From: Aaron McAdam Date: Mon, 5 Aug 2024 16:33:06 +0100 Subject: [PATCH] ensure user feedback even when rejecting --- src/components/quiz-option.tsx | 34 ++++++++++++++++++++++++++-------- src/components/quiz.tsx | 32 +++++++++++++------------------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/components/quiz-option.tsx b/src/components/quiz-option.tsx index cb70ddd..ced25cc 100644 --- a/src/components/quiz-option.tsx +++ b/src/components/quiz-option.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { cn } from "@/lib/utils"; import { Button } from "./ui/button"; -import { CircleCheck } from "lucide-react"; +import { Check, CircleCheck, X } from "lucide-react"; export type QuizOptionProps = { onClick: () => void; @@ -16,21 +16,39 @@ export const QuizOption = React.memo(function QuizOption({ display, value, }: QuizOptionProps) { + const type = display === "Yes" || display === "No" ? "boolean" : "image"; + return ( ); diff --git a/src/components/quiz.tsx b/src/components/quiz.tsx index 82ec03d..453b92a 100644 --- a/src/components/quiz.tsx +++ b/src/components/quiz.tsx @@ -39,12 +39,15 @@ export function Quiz() { }); // TODO: Perf: we may want to somehow preload the display HTML because - // we're seeing some flicker when images have to load + // we're seeing some flicker when images have to load. + // Hard coding the height of the option helps, but it's not ideal. + // We'd probably need to parse or regex the html to check what element it is. React.useEffect(() => { fetch("/api/questions") .then((res) => res.json()) .then((data: Question[]) => - setQuizState({ + setQuizState((prevState) => ({ + ...prevState, // Map the fetched data to the view model state // Set the first question as "current" and the rest as "upcoming" questions: data.map((q, i) => { @@ -55,26 +58,10 @@ export function Quiz() { status: i === 0 ? "current" : "upcoming", }; }), - currentIndex: 0, - result: null, - }), + })), ); }, []); - React.useEffect(() => { - const isRejected = quizState.questions.some((q) => q.response?.isRejection); - const isAccepted = - quizState.questions.length > 0 - ? quizState.questions.every((q) => q.status === "complete") - : false; - - if (isRejected) { - setQuizState((prevState) => ({ ...prevState, result: "rejected" })); - } else if (isAccepted) { - setQuizState((prevState) => ({ ...prevState, result: "accepted" })); - } - }, [quizState.questions]); - const currentQuestion = quizState.questions[quizState.currentIndex]; // Update the current question with its response and "complete" status @@ -113,6 +100,12 @@ export function Quiz() { return q; }); + const isRejected = updatedQuestions.some( + (q) => q.response?.isRejection, + ); + const isAccepted = updatedQuestions.every( + (q) => q.status === "complete", + ); return { ...prevState, @@ -121,6 +114,7 @@ export function Quiz() { nextIndex < prevState.questions.length ? nextIndex : prevState.currentIndex, + result: isRejected ? "rejected" : isAccepted ? "accepted" : null, }; }); }, 600); // 600ms delay for double blink effect