/** * 单个问题渲染组件 */ import { useState } from 'react' import { cn } from '@/lib/utils' import { Label } from '@/components/ui/label' import { Input } from '@/components/ui/input' import { Textarea } from '@/components/ui/textarea' import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group' import { Checkbox } from '@/components/ui/checkbox' import { Slider } from '@/components/ui/slider' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Star } from 'lucide-react' import type { SurveyQuestion as SurveyQuestionType } from '@/types/survey' interface SurveyQuestionProps { question: SurveyQuestionType value: string | string[] | number | undefined onChange: (value: string | string[] | number) => void error?: string disabled?: boolean } export function SurveyQuestion({ question, value, onChange, error, disabled = false }: SurveyQuestionProps) { const [hoverRating, setHoverRating] = useState(null) // 如果问题设置了只读,则禁用输入 const isDisabled = disabled || question.readOnly const renderQuestion = () => { switch (question.type) { case 'single': return ( {question.options?.map((option) => (
))}
) case 'multiple': { const selectedValues = (value as string[]) || [] return (
{question.options?.map((option) => (
= question.maxSelections && !selectedValues.includes(option.value) )} onCheckedChange={(checked) => { if (checked) { onChange([...selectedValues, option.value]) } else { onChange(selectedValues.filter(v => v !== option.value)) } }} />
))} {question.maxSelections && (

最多选择 {question.maxSelections} 项

)}
) } case 'text': return ( onChange(e.target.value)} placeholder={question.placeholder || '请输入...'} disabled={isDisabled} readOnly={question.readOnly} maxLength={question.maxLength} className={cn(question.readOnly && "bg-muted cursor-not-allowed")} /> ) case 'textarea': return (