import { useState, useEffect } from "react" import { useParams, Link } from "react-router" import { ArrowLeft, CheckCircle2, FileText, Star, ChevronDown, Calendar, Send, } from "lucide-react" import { Navbar } from "@/components/shared/navbar" import { Footer } from "@/components/shared/footer" import { FormButton } from "@/components/shared/form-button" import { getFormById, submitFormResponse } from "@/lib/api" import type { FormDetail, Question } from "@/lib/types" export default function SubmitFormPage() { const { id } = useParams() const [form, setForm] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [answers, setAnswers] = useState>({}) const [submitting, setSubmitting] = useState(false) const [submitted, setSubmitted] = useState(false) const [validationErrors, setValidationErrors] = useState>({}) useEffect(() => { if (!id) return async function fetchForm() { try { const data = await getFormById(id!) setForm(data) // Initialize empty answers const initial: Record = {} data.questions.forEach((q) => { initial[q.id] = "" }) setAnswers(initial) } catch (err) { if (err instanceof Response && err.status === 404) { setError("Form not found") } else { setError("Failed to load form. Please try again.") } } finally { setLoading(false) } } fetchForm() }, [id]) function updateAnswer(questionId: string, value: string) { setAnswers((prev) => ({ ...prev, [questionId]: value })) // Clear validation error on change if (validationErrors[questionId]) { setValidationErrors((prev) => { const next = { ...prev } delete next[questionId] return next }) } } function validate(): boolean { if (!form) return false const errors: Record = {} form.questions.forEach((q) => { if (q.required && !answers[q.id]?.trim()) { errors[q.id] = "This question is required" } }) setValidationErrors(errors) return Object.keys(errors).length === 0 } async function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!id || !form) return if (!validate()) { // Scroll to first error const firstErrorId = form.questions.find((q) => validationErrors[q.id] || (q.required && !answers[q.id]?.trim()))?.id if (firstErrorId) { document.getElementById(`question-${firstErrorId}`)?.scrollIntoView({ behavior: "smooth", block: "center" }) } return } setSubmitting(true) setError(null) try { await submitFormResponse(id, { answers: form.questions .filter((q) => answers[q.id]?.trim()) .map((q) => ({ question_id: q.id, answer: answers[q.id].trim(), })), }) setSubmitted(true) } catch (err) { setError(err instanceof Error ? err.message : "Failed to submit response") } finally { setSubmitting(false) } } if (loading) { return (

Loading form...

) } if (error && !form) { return (

{error}

Back to forms
) } if (submitted) { return (

Response Submitted!

Thank you for filling out {form?.title}. Your response has been recorded.

{ setSubmitted(false) // Reset answers if (form) { const initial: Record = {} form.questions.forEach((q) => { initial[q.id] = "" }) setAnswers(initial) } }} > Submit another response Back to forms
) } if (!form) return null return (
Back to form preview

{form.title}

{form.description}

{form.questions.length} questions * Required
{error && (
{error}
)}
{form.questions.map((question, index) => ( updateAnswer(question.id, val)} error={validationErrors[question.id]} /> ))}
{submitting ? ( "Submitting..." ) : ( <> Submit )}
) } // ─── Question field component ──────────────────────────────────────────────── interface QuestionFieldProps { question: Question index: number value: string onChange: (value: string) => void error?: string } function QuestionField({ question, index, value, onChange, error }: QuestionFieldProps) { return (
{index + 1}

{question.title} {question.required && ( * )}

{question.type.replace("_", " ")}

{question.type === "short_text" && ( onChange(e.target.value)} placeholder="Your answer" className="w-full rounded-lg border border-input bg-background px-3.5 py-2.5 text-sm text-foreground placeholder:text-muted-foreground outline-none transition-colors focus:border-primary focus:ring-2 focus:ring-primary/20" /> )} {question.type === "long_text" && (