"use client"; import { useEffect, useRef, useState } from "react"; import { useRouter } from "next/navigation"; import { useForm, Controller } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { toast } from "sonner"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { PartiesField } from "@/components/wizard/parties-field"; import { useCreateCase } from "@/lib/api/cases"; import { caseCreateSchema, expectedOutcomes, type CaseCreateInput, } from "@/lib/schemas/case"; import { PRACTICE_AREAS, APPEAL_SUBTYPES, deriveSubtype, type AppealSubtype, } from "@/lib/practice-area"; const STEPS = [ { key: "basics", label: "פרטי יסוד" }, { key: "parties", label: "צדדים" }, { key: "details", label: "השלמות" }, ] as const; type StepKey = (typeof STEPS)[number]["key"]; /* Fields validated at each step — lets the user fix just what's on screen * before moving forward, instead of surfacing all errors from page 1. */ const STEP_FIELDS: Record = { basics: ["case_number", "title", "practice_area", "appeal_subtype"], parties: ["appellants", "respondents"], details: ["subject", "hearing_date", "expected_outcome", "notes", "property_address", "permit_number"], }; function FieldError({ message }: { message?: string }) { if (!message) return null; return

{message}

; } export function CaseWizard() { const router = useRouter(); const [step, setStep] = useState("basics"); const mutate = useCreateCase(); const form = useForm({ resolver: zodResolver(caseCreateSchema), mode: "onBlur", defaultValues: { case_number: "", title: "", appellants: [], respondents: [], subject: "", property_address: "", permit_number: "", hearing_date: "", notes: "", expected_outcome: "", practice_area: "appeals_committee", appeal_subtype: "unknown", }, }); /* * Auto-fill appeal_subtype from the case number as the user types, but * stop the moment they manually pick a value from the dropdown. Mirrors * the wireSubtypeAutofill() behaviour of the vanilla UI * (legal-ai/web/static/index.html around line 2770). */ const userTouchedSubtype = useRef(false); const caseNumber = form.watch("case_number"); const practiceArea = form.watch("practice_area"); useEffect(() => { if (userTouchedSubtype.current) return; const derived = deriveSubtype(caseNumber, practiceArea); if (derived !== form.getValues("appeal_subtype")) { form.setValue("appeal_subtype", derived, { shouldValidate: false }); } }, [caseNumber, practiceArea, form]); const stepIndex = STEPS.findIndex((s) => s.key === step); const isLast = stepIndex === STEPS.length - 1; const goNext = async () => { const ok = await form.trigger(STEP_FIELDS[step]); if (!ok) return; setStep(STEPS[stepIndex + 1].key); }; const goBack = () => setStep(STEPS[stepIndex - 1].key); const onSubmit = form.handleSubmit(async (values) => { try { const res = await mutate.mutateAsync(values); toast.success("תיק חדש נוצר"); const created = res?.case_number || values.case_number; router.push(`/cases/${encodeURIComponent(created)}`); } catch (e) { toast.error(e instanceof Error ? e.message : "שגיאה ביצירת תיק"); } }); return ( {/* Stepper */}
    {STEPS.map((s, i) => { const active = i === stepIndex; const done = i < stepIndex; return (
  1. {done ? "✓" : i + 1} {s.label} {i < STEPS.length - 1 && ( )}
  2. ); })}
{step === "basics" && (
( )} />
( )} />

מזוהה אוטומטית ממספר התיק

)} {step === "parties" && (
( )} />
( )} />
)} {step === "details" && (
( )} />