import React, { useState, useEffect } from 'react'; import { API } from '../../api/API'; import { toast } from 'sonner'; interface Question { id: string; sectionName: string; questionText: string; inputType: 'text' | 'yesno' | 'file' | 'number'; options?: any; weight: number; order: number; isMandatory: boolean; } interface QuestionnaireFormProps { applicationId: string; onComplete?: () => void; readOnly?: boolean; existingResponses?: any[]; publicMode?: boolean; // New prop initialQuestions?: Question[]; // New prop to avoid re-fetching } const QuestionnaireForm: React.FC = ({ applicationId, onComplete, readOnly = false, existingResponses, publicMode = false, initialQuestions }) => { const [questions, setQuestions] = useState(initialQuestions || []); const [responses, setResponses] = useState>({}); const [loading, setLoading] = useState(!initialQuestions); const [submitting, setSubmitting] = useState(false); useEffect(() => { if (!initialQuestions) { fetchQuestionnaire(); } if (existingResponses) { const initialResponses: any = {}; existingResponses.forEach(r => { initialResponses[r.questionId] = r.responseValue; }); setResponses(initialResponses); } }, [existingResponses, initialQuestions]); const fetchQuestionnaire = async () => { try { // In public mode, we shouldn't fetch "latest" as it requires auth. // Public page should provide initialQuestions. // But if we ever needed to fetch, we'd need a public endpoint for just questions or rely on the parent. if (publicMode) { setLoading(false); return; } const res = await API.getLatestQuestionnaire(); if (res.data && res.data.data && res.data.data.questions) { setQuestions(res.data.data.questions); } } catch (error) { console.error(error); toast.error('Failed to load questionnaire'); } finally { setLoading(false); } }; const handleInputChange = (questionId: string, value: any) => { if (readOnly) return; setResponses(prev => ({ ...prev, [questionId]: value })); }; const handleSubmit = async () => { const missing = questions.filter(q => q.isMandatory && !responses[q.id]); if (missing.length > 0) { toast.error(`Please answer all mandatory questions. Missing: ${missing.length}`); return; } try { setSubmitting(true); const payload = Object.entries(responses).map(([qId, val]) => ({ questionId: qId, value: val })); if (publicMode) { await API.submitPublicResponse({ applicationId, responses: payload }); } else { await API.submitQuestionnaireResponse({ applicationId, responses: payload }); } toast.success('Responses submitted successfully'); if (onComplete) onComplete(); } catch (error) { console.error(error); toast.error('Failed to submit responses'); } finally { setSubmitting(false); } }; if (loading) return
Loading questionnaire...
; if (questions.length === 0) return
No active questionnaire found.
; const sections = questions.reduce((acc, q) => { if (!acc[q.sectionName]) acc[q.sectionName] = []; acc[q.sectionName].push(q); return acc; }, {} as Record); return (

Dealership Assessment Questionnaire

{Object.entries(sections).map(([sectionName, sectionQuestions]) => (

{sectionName}

{sectionQuestions.map(q => (
{q.inputType === 'text' && ( handleInputChange(q.id, e.target.value)} value={responses[q.id] || ''} disabled={readOnly} /> )} {q.inputType === 'number' && ( handleInputChange(q.id, e.target.value)} value={responses[q.id] || ''} disabled={readOnly} /> )} {q.inputType === 'yesno' && (
)}
))}
))} {!readOnly && ( )}
); }; export default QuestionnaireForm;