diff --git a/app/form/client.tsx b/app/form/client.tsx index a8002de..7ada417 100644 --- a/app/form/client.tsx +++ b/app/form/client.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; @@ -67,23 +67,50 @@ interface FormFillerClientProps { initialAnswers?: Record; } +const LS_KEY = (formId: string) => `form-draft-${formId}`; + export function FormFillerClient({ form, questions, initialAnswers = {} }: FormFillerClientProps) { const router = useRouter(); - - // Pre-process checkbox answers since they are stored as comma-separated strings + + // Merge: server answers take precedence over localStorage draft + const getInitialState = () => { + const serverAnswers = { ...initialAnswers }; + let draft: Record = {}; + try { + const raw = localStorage.getItem(LS_KEY(form.id)); + if (raw) draft = JSON.parse(raw); + } catch {} + // Merge draft under server values + return { ...draft, ...serverAnswers }; + }; + + const merged = getInitialState(); + + // Pre-process checkbox answers const initialCheckboxes: Record = {}; for (const q of questions) { - if (q.type === "checkbox" && initialAnswers[q.id]) { - initialCheckboxes[q.id] = initialAnswers[q.id].split(", "); + if (q.type === "checkbox" && merged[q.id]) { + initialCheckboxes[q.id] = merged[q.id].split(", "); } } - const [answers, setAnswers] = useState>(initialAnswers); + const [answers, setAnswers] = useState>(merged); const [checkboxAnswers, setCheckboxAnswers] = useState>(initialCheckboxes); const [submitting, setSubmitting] = useState(false); const isUpdating = Object.keys(initialAnswers).length > 0; + // Persist to localStorage whenever answers change + useEffect(() => { + try { + const combined: Record = { ...answers }; + for (const [qId, opts] of Object.entries(checkboxAnswers)) { + combined[qId] = opts.join(", "); + } + localStorage.setItem(LS_KEY(form.id), JSON.stringify(combined)); + } catch {} + }, [answers, checkboxAnswers, form.id]); + const handleTextChange = (questionId: string, value: string) => { setAnswers((prev) => ({ ...prev, [questionId]: value })); }; @@ -144,10 +171,7 @@ export function FormFillerClient({ form, questions, initialAnswers = {} }: FormF const res = await submitForm(form.id, formattedAnswers); if (res.ok) { toast.success(isUpdating ? "Form updated successfully!" : "Form submitted successfully!"); - if (!isUpdating) { - setAnswers({}); - setCheckboxAnswers({}); - } + // Fields are kept as-is; localStorage already reflects current state } } catch (err: any) { console.error(err); diff --git a/components/tooltip.tsx b/components/tooltip.tsx new file mode 100644 index 0000000..7d46747 --- /dev/null +++ b/components/tooltip.tsx @@ -0,0 +1,31 @@ +"use client"; + +import type { ReactNode } from "react"; +import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip"; + +export function SimpleTooltip({ + text, + children, + side, + className, + align, + ...props +}: { + text?: ReactNode; + side?: "top" | "right" | "bottom" | "left" | undefined; + className?: string; + align?: "center" | "start" | "end" | undefined; +} & React.ComponentProps) { + return ( + + {children} + + {text} + + + ); +} \ No newline at end of file