diff --git a/app/routes/create-form.tsx b/app/routes/create-form.tsx new file mode 100644 index 0000000..171f771 --- /dev/null +++ b/app/routes/create-form.tsx @@ -0,0 +1,145 @@ +import { useState, useEffect } from "react" +import { useNavigate } from "react-router" +import { ArrowLeft } from "lucide-react" +import { Link } from "react-router" +import { Navbar } from "@/components/shared/navbar" +import { Footer } from "@/components/shared/footer" +import { FormInput } from "@/components/shared/form-input" +import { FormButton } from "@/components/shared/form-button" +import { QuestionEditor } from "@/components/forms/question-editor" +import { useAuth } from "@/app/context/auth-context" +import { createForm } from "@/lib/api" +import type { CreateQuestion } from "@/lib/types" + +const TYPES_WITH_OPTIONS = ["multiple_choice", "checkbox", "dropdown"] + +export default function CreateFormPage() { + const { user, loading: authLoading } = useAuth() + const navigate = useNavigate() + + const [title, setTitle] = useState("") + const [description, setDescription] = useState("") + const [questions, setQuestions] = useState([ + { type: "short_text", title: "", required: false, position: 1, options: [] }, + ]) + const [submitting, setSubmitting] = useState(false) + const [error, setError] = useState(null) + + useEffect(() => { + if (!authLoading && !user) { + navigate("/login") + } + }, [user, authLoading, navigate]) + + if (authLoading || !user) return null + + async function handleSubmit(e: React.FormEvent) { + e.preventDefault() + setError(null) + + if (!title.trim()) { + setError("Form title is required.") + return + } + + const hasEmptyQuestion = questions.some((q) => !q.title.trim()) + if (hasEmptyQuestion) { + setError("All questions must have a title.") + return + } + + const hasEmptyOption = questions.some( + (q) => + TYPES_WITH_OPTIONS.includes(q.type) && + (q.options.length === 0 || q.options.some((o) => !o.label.trim())) + ) + if (hasEmptyOption) { + setError("All options must have a label.") + return + } + + setSubmitting(true) + try { + const result = await createForm({ + title: title.trim(), + description: description.trim(), + questions, + }) + navigate(`/form/${result.id}`) + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to create form.") + } finally { + setSubmitting(false) + } + } + + return ( +
+ + +
+
+ + + Back to forms + + +

+ Create New Form +

+ +
+ {error && ( +
+ {error} +
+ )} + +
+
+
+ setTitle(e.target.value)} + required + /> +
+ +