import { useState, useEffect } from "react"; import { useChatStore } from "@/stores"; import { cn } from "@/lib/utils"; export function QuestionDialog() { const { pendingQuestion, respondQuestion } = useChatStore(); const [customInput, setCustomInput] = useState(""); const [showCustom, setShowCustom] = useState(false); const [selectedIndex, setSelectedIndex] = useState(1); const [questionIndex, setQuestionIndex] = useState(0); const [answers, setAnswers] = useState>({}); const [multiSelected, setMultiSelected] = useState([]); const questions = pendingQuestion?.questions ?? []; const question = questions[questionIndex]; const isMultiSelect = question?.multi_select === true; const isLastQuestion = questionIndex + 1 >= questions.length; useEffect(() => { if (pendingQuestion) { setShowCustom(false); setCustomInput(""); setSelectedIndex(1); setQuestionIndex(0); setAnswers({}); setMultiSelected([]); } }, [pendingQuestion?.id]); if (!pendingQuestion || !question) return null; // Step through the questions one by one; submit all answers after the last. const handleAnswer = async (answer: string) => { const nextAnswers = { ...answers, [question.question]: answer }; if (!isLastQuestion) { setAnswers(nextAnswers); setQuestionIndex(questionIndex + 1); setShowCustom(false); setCustomInput(""); setSelectedIndex(1); setMultiSelected([]); } else { await respondQuestion(nextAnswers); } }; const handleSelect = async (optionLabel: string) => { if (isMultiSelect) { setMultiSelected((prev) => prev.includes(optionLabel) ? prev.filter((value) => value !== optionLabel) : [...prev, optionLabel], ); return; } await handleAnswer(optionLabel); }; const handleCustomSubmit = async () => { const value = customInput.trim(); if (!value) return; if (isMultiSelect) { setMultiSelected((prev) => (prev.includes(value) ? prev : [...prev, value])); setCustomInput(""); setShowCustom(false); return; } await handleAnswer(value); }; const options = question.options || []; const customIndex = options.length + 1; const customValues = multiSelected.filter((value) => !options.some((option) => option.label === value)); return (
{questions.length > 1 && (
Question {questionIndex + 1} of {questions.length}
)} {question.header &&
{question.header}
}
{question.question}
{isMultiSelect &&
Select all that apply
}
{options.map((option, idx) => { const isChecked = isMultiSelect && multiSelected.includes(option.label); const isHighlighted = selectedIndex === idx + 1; return ( ); })} {customValues.map((value) => ( ))} {showCustom ? (
setCustomInput(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") void handleCustomSubmit(); if (e.key === "Escape") setShowCustom(false); }} placeholder="Enter your response…" className="flex-1 px-2 py-1 rounded-md text-xs border border-border bg-background outline-none focus:border-blue-500" />
) : ( )} {isMultiSelect && ( )}
); }