"use client"; import { useEffect, useState } from "react"; import { Save, Sparkles } from "lucide-react"; import { toast } from "sonner"; import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, } from "@/components/ui/sheet"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Skeleton } from "@/components/ui/skeleton"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { usePrecedent, useUpdatePrecedent, useRequestMetadataExtraction, type PracticeArea, type SourceType, } from "@/lib/api/precedent-library"; import { PRACTICE_AREAS, PRECEDENT_LEVELS, SOURCE_TYPES, appealSubtypeLabel, } from "./practice-area"; import { ExtractedHalachotSection } from "./extracted-halachot"; type Props = { caseLawId: string | null; onOpenChange: (open: boolean) => void; }; /* All editable fields. Pulled fresh from /api/precedent-library/{id} * each time the sheet opens so the form reflects any auto-fill that * happened in the background. */ type FormState = { citation: string; case_name: string; court: string; decision_date: string; practice_area: PracticeArea; appeal_subtype: string; source_type: SourceType; precedent_level: string; is_binding: boolean; subject_tags: string; summary: string; headnote: string; key_quote: string; }; const EMPTY: FormState = { citation: "", case_name: "", court: "", decision_date: "", practice_area: "", appeal_subtype: "", source_type: "", precedent_level: "", is_binding: true, subject_tags: "", summary: "", headnote: "", key_quote: "", }; export function PrecedentEditSheet({ caseLawId, onOpenChange }: Props) { const open = caseLawId !== null; const { data: record, isPending } = usePrecedent(caseLawId); const update = useUpdatePrecedent(); const requestMetadata = useRequestMetadataExtraction(); const [form, setForm] = useState(EMPTY); // Hydrate form when the record loads. useEffect(() => { if (!record) return; // eslint-disable-next-line react-hooks/set-state-in-effect setForm({ citation: record.case_number || "", case_name: record.case_name || "", court: record.court || "", decision_date: record.date ? record.date.slice(0, 10) : "", practice_area: (record.practice_area || "") as PracticeArea, appeal_subtype: appealSubtypeLabel(record.appeal_subtype), source_type: (record.source_type || "") as SourceType, precedent_level: record.precedent_level || "", is_binding: record.is_binding ?? true, subject_tags: (record.subject_tags || []).join(", "), summary: record.summary || "", headnote: record.headnote || "", key_quote: (record as { key_quote?: string }).key_quote || "", }); }, [record]); const onSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!caseLawId) return; try { const patch: Record = { case_name: form.case_name.trim(), court: form.court.trim(), practice_area: form.practice_area || undefined, appeal_subtype: form.appeal_subtype.trim(), source_type: form.source_type || undefined, precedent_level: form.precedent_level || undefined, is_binding: form.is_binding, subject_tags: form.subject_tags .split(",").map((t) => t.trim()).filter(Boolean), summary: form.summary.trim(), headnote: form.headnote.trim(), key_quote: form.key_quote.trim(), }; if (form.decision_date) patch.decision_date = form.decision_date; // citation (case_number) is the unique key; we don't allow editing it // here to avoid orphaning halachot. To rename, delete + re-upload. await update.mutateAsync({ id: caseLawId, patch }); toast.success("נשמר"); onOpenChange(false); } catch (err) { toast.error(err instanceof Error ? err.message : "שגיאה"); } }; const onRequestMetadata = async () => { if (!caseLawId) return; try { await requestMetadata.mutateAsync(caseLawId); toast.success( "סומן לחילוץ מטא-דאטה. הריצי מ-Claude Code: precedent_process_pending", ); } catch (err) { toast.error(err instanceof Error ? err.message : "שגיאה"); } }; return ( { if (!o) onOpenChange(false); }}> עריכת פרטי פסיקה כל השדות ניתנים לעריכה חוץ ממראה המקום (מזהה ייחודי). כפתור "חלץ מטא-דאטה" שולח בקשה לתור מקומי שאני מרוקן מ-Claude Code (ה-LLM רץ מקומית עם claude session, לא ב-API). {isPending || !record ? (
{[...Array(6)].map((_, i) => )}
) : ( <>
מראה מקום (לא ניתן לעריכה)
{record.case_number}
setForm({ ...form, case_name: e.target.value })} placeholder="ערר 403/17 / אהרון ברק" />
setForm({ ...form, court: e.target.value })} />
setForm({ ...form, decision_date: e.target.value })} />
setForm({ ...form, appeal_subtype: e.target.value })} placeholder="תכנית רחביה / סופיות ההחלטה" />
{PRACTICE_AREAS.map((a) => ( ))}
setForm({ ...form, subject_tags: e.target.value })} placeholder="חניה, קווי בניין, שיקול דעת" />