You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.0 KiB
118 lines
4.0 KiB
"use client";
|
|
|
|
import { ExplanationUiFont } from "./explanation-ui-font";
|
|
import type { QuestionField } from "@/data/question-data";
|
|
import { useQuestionAnswers } from "./question-answer-storage";
|
|
import QuestionTitle from "./question-title";
|
|
|
|
type QuestionRadioProps = {
|
|
question: QuestionField;
|
|
questionIndex: number;
|
|
disabled?: boolean;
|
|
};
|
|
|
|
export function QuestionRadio({
|
|
question,
|
|
questionIndex,
|
|
disabled,
|
|
}: QuestionRadioProps) {
|
|
const options = question.extras.options || [];
|
|
const { getAnswerValue, setAnswerValue } = useQuestionAnswers();
|
|
const value = getAnswerValue(question, questionIndex);
|
|
|
|
if (options.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
// Render horizontally if all options are short (e.g. Single, Divorced, Widowed)
|
|
const isShortOptions =
|
|
options.length <= 4 && options.every((opt) => opt.length <= 15);
|
|
|
|
return (
|
|
<div
|
|
className={[
|
|
"flex w-full flex-col gap-3.5 transition-opacity duration-200",
|
|
disabled ? "pointer-events-none opacity-30" : "",
|
|
].join(" ")}
|
|
>
|
|
<QuestionTitle question={question} />
|
|
|
|
<div
|
|
className={
|
|
isShortOptions
|
|
? "flex flex-row flex-wrap items-center gap-3 pt-1"
|
|
: "flex flex-col gap-3.5 pt-1"
|
|
}
|
|
>
|
|
{options.map((option) => {
|
|
const optionId = `question-${questionIndex}-${option}`;
|
|
const isSelected = String(value) === option;
|
|
|
|
return (
|
|
<label
|
|
key={option}
|
|
htmlFor={optionId}
|
|
className={[
|
|
"cursor-pointer rounded-[16px] font-semibold text-[15px] transition-all duration-200 active:scale-[0.99] flex items-center gap-3",
|
|
isShortOptions
|
|
? "flex-1 min-w-[90px] px-5 py-3.5 text-center justify-center"
|
|
: "w-full px-5 py-4 text-start leading-snug",
|
|
isSelected
|
|
? "bg-[#F0445B] text-white shadow-[0_8px_20px_rgba(240,68,91,0.25)]"
|
|
: "bg-[#FAFAFA] text-[#181818] hover:bg-white shadow-[0_2px_6px_rgba(0,0,0,0.03)] border border-[#F0EDED]",
|
|
].join(" ")}
|
|
>
|
|
<input
|
|
type="radio"
|
|
id={optionId}
|
|
name={`question-${questionIndex}`}
|
|
value={option}
|
|
checked={isSelected}
|
|
disabled={disabled}
|
|
onChange={() => setAnswerValue(question, questionIndex, option)}
|
|
className="sr-only"
|
|
/>
|
|
{!isShortOptions && (
|
|
<div
|
|
className={[
|
|
"size-[18px] shrink-0 rounded-full border-[2px] transition-all flex items-center justify-center",
|
|
isSelected
|
|
? "border-white bg-white text-[#F0445B]"
|
|
: "border-[#D0D5DD] bg-white text-transparent",
|
|
].join(" ")}
|
|
>
|
|
{isSelected && (
|
|
<div className="size-[8px] rounded-full bg-current" />
|
|
)}
|
|
</div>
|
|
)}
|
|
{option.includes(" - ") ? (
|
|
(() => {
|
|
const parts = option.split(" - ");
|
|
const title = parts[0];
|
|
const description = parts.slice(1).join(" - ");
|
|
return (
|
|
<span className="flex flex-col gap-1 text-start flex-1">
|
|
<span className="font-bold">{title}</span>
|
|
<ExplanationUiFont
|
|
textColor={
|
|
isSelected ? "text-white/85" : "text-[#667085]"
|
|
}
|
|
>
|
|
{description}
|
|
</ExplanationUiFont>
|
|
</span>
|
|
);
|
|
})()
|
|
) : (
|
|
<span className="flex-1">{option}</span>
|
|
)}
|
|
</label>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default QuestionRadio;
|