{"$schema":"https:\/\/ui.particle.academy\/schema\/registry-item.json","name":"question-renderer","type":"registry:ui","title":"QuestionRenderer","description":"One question of any of the four types: multiple choice, multiple select, true\/false, short answer.","package":"classroom","dependencies":["@particle-academy\/react-fancy"],"registryDependencies":["types"],"files":[{"path":"components\/fancy\/question-renderer\/QuestionRenderer.tsx","content":"import {\r\n    CheckboxGroup,\r\n    RadioGroup,\r\n    Text,\r\n    Textarea,\r\n} from '@particle-academy\/react-fancy';\r\nimport type { Question } from '..\/types';\r\n\r\nexport type AnswerValue =\r\n    | { kind: 'option_id'; value: number }\r\n    | { kind: 'option_ids'; value: number[] }\r\n    | { kind: 'text'; value: string }\r\n    | null;\r\n\r\nexport interface QuestionRendererProps {\r\n    question: Question;\r\n    value: AnswerValue;\r\n    onChange: (next: AnswerValue) => void;\r\n    disabled?: boolean;\r\n}\r\n\r\nexport function QuestionRenderer({\r\n    question,\r\n    value,\r\n    onChange,\r\n    disabled,\r\n}: QuestionRendererProps) {\r\n    const options = question.options ?? [];\r\n\r\n    if (question.type === 'multiple_choice' || question.type === 'true_false') {\r\n        const selected =\r\n            value?.kind === 'option_id' ? String(value.value) : undefined;\r\n\r\n        return (\r\n            <div className=\"grid gap-3\">\r\n                <Text weight=\"semibold\" className=\"!text-base\">\r\n                    {question.prompt}\r\n                <\/Text>\r\n                <RadioGroup<string>\r\n                    name={`q-${question.id}`}\r\n                    list={options.map((o) => ({ value: String(o.id), label: o.label }))}\r\n                    value={selected}\r\n                    onValueChange={(next) =>\r\n                        onChange({ kind: 'option_id', value: Number(next) })\r\n                    }\r\n                    disabled={disabled}\r\n                \/>\r\n            <\/div>\r\n        );\r\n    }\r\n\r\n    if (question.type === 'multiple_select') {\r\n        const selected =\r\n            value?.kind === 'option_ids' ? value.value.map(String) : undefined;\r\n\r\n        return (\r\n            <div className=\"grid gap-3\">\r\n                <Text weight=\"semibold\" className=\"!text-base\">\r\n                    {question.prompt}\r\n                <\/Text>\r\n                <Text size=\"sm\" color=\"muted\">\r\n                    Select all that apply.\r\n                <\/Text>\r\n                <CheckboxGroup<string>\r\n                    name={`q-${question.id}`}\r\n                    list={options.map((o) => ({ value: String(o.id), label: o.label }))}\r\n                    value={selected}\r\n                    onValueChange={(next) =>\r\n                        onChange({ kind: 'option_ids', value: next.map(Number) })\r\n                    }\r\n                    disabled={disabled}\r\n                \/>\r\n            <\/div>\r\n        );\r\n    }\r\n\r\n    \/\/ short_answer\r\n    const text = value?.kind === 'text' ? value.value : '';\r\n    return (\r\n        <div className=\"grid gap-3\">\r\n            <Text weight=\"semibold\" className=\"!text-base\">\r\n                {question.prompt}\r\n            <\/Text>\r\n            <Textarea\r\n                value={text}\r\n                onChange={(e) =>\r\n                    onChange({\r\n                        kind: 'text',\r\n                        value: (e.target as HTMLTextAreaElement).value,\r\n                    })\r\n                }\r\n                disabled={disabled}\r\n                rows={4}\r\n                placeholder=\"Type your answer here\u2026\"\r\n            \/>\r\n        <\/div>\r\n    );\r\n}\r\n\r\nexport function answerValueToPayload(\r\n    questionId: number,\r\n    value: AnswerValue,\r\n): { question_id: number; answer: unknown } {\r\n    if (!value) return { question_id: questionId, answer: null };\r\n    switch (value.kind) {\r\n        case 'option_id':\r\n            return { question_id: questionId, answer: { option_id: value.value } };\r\n        case 'option_ids':\r\n            return { question_id: questionId, answer: { option_ids: value.value } };\r\n        case 'text':\r\n            return { question_id: questionId, answer: { text: value.value } };\r\n    }\r\n}\r\n","type":"registry:ui","target":"components\/fancy\/question-renderer\/QuestionRenderer.tsx"}]}