Skip to content

Commit

Permalink
ensure user feedback even when rejecting
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronmcadam committed Aug 5, 2024
1 parent 639d4e4 commit ce1a12c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 27 deletions.
34 changes: 26 additions & 8 deletions src/components/quiz-option.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -16,21 +16,39 @@ export const QuizOption = React.memo(function QuizOption({
display,
value,
}: QuizOptionProps) {
const type = display === "Yes" || display === "No" ? "boolean" : "image";

return (
<Button
onClick={onClick}
variant="outline"
className={cn("mt-2 h-auto flex flex-col relative", {
"ring-2 ring-primary": isSelected,
// TODO: only apply this after clicking the option because otherwise, when navigating back to a question,
// the selected option will blink.
"animate-blink": isSelected,
})}
className={cn(
"mt-2 h-auto flex flex-col items-center justify-center relative",
{
"ring-2 ring-primary": isSelected,
// TODO: only apply this after clicking the option because otherwise, when navigating back to a question,
// the selected option will blink.
"animate-blink": isSelected,
},
)}
>
{isSelected ? (
<CircleCheck className="h-5 w-5 text-primary absolute top-2 right-2" />
) : null}
<span dangerouslySetInnerHTML={{ __html: display }} />
{display === "Yes" ? (
<div className="flex items-center h-[154px]">
<Check className="flex-grow text-brand-600 h-16 w-16" />
</div>
) : null}
{display === "No" ? (
<div className="flex items-center h-[154px]">
<X className="text-brand-600 h-16 w-16" />
</div>
) : null}
<span
className={cn({ "h-[154px]": type === "image" })}
dangerouslySetInnerHTML={{ __html: display }}
/>
{value}
</Button>
);
Expand Down
32 changes: 13 additions & 19 deletions src/components/quiz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down

0 comments on commit ce1a12c

Please sign in to comment.