diff --git a/src/components/cases/litigation-tab.tsx b/src/components/cases/litigation-tab.tsx new file mode 100644 index 0000000..977fd79 --- /dev/null +++ b/src/components/cases/litigation-tab.tsx @@ -0,0 +1,260 @@ +import { useState } from "react"; +import { supabase } from "@/integrations/supabase/client"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; +import { Separator } from "@/components/ui/separator"; +import { Pencil, Save, X, Calendar, Gavel, Scale, FileSearch, Users, AlertCircle } from "lucide-react"; +import { toast } from "sonner"; +import { formatCurrency, formatDate } from "@/lib/format"; + +interface Props { + caseRecord: any; + canManage: boolean; + onSaved: () => void; +} + +const FIELDS: Array<{ key: string; label: string; type?: string; full?: boolean }> = [ + { key: "case_caption", label: "Case caption", full: true }, + { key: "court_case_number", label: "Court case #" }, + { key: "litigation_stage", label: "Litigation stage" }, + { key: "court", label: "Court" }, + { key: "jurisdiction", label: "Jurisdiction" }, + { key: "judge", label: "Judge" }, + { key: "filing_date", label: "Filing date", type: "date" }, + { key: "next_hearing_date", label: "Next hearing", type: "date" }, + { key: "statute_of_limitations", label: "Statute of limitations", type: "date" }, + { key: "claim_amount", label: "Claim amount", type: "number" }, + { key: "settlement_amount", label: "Settlement amount", type: "number" }, +]; + +const OPPOSING: Array<{ key: string; label: string }> = [ + { key: "opposing_party", label: "Opposing party" }, + { key: "opposing_counsel", label: "Opposing counsel" }, + { key: "opposing_counsel_firm", label: "Counsel firm" }, + { key: "opposing_counsel_email", label: "Counsel email" }, + { key: "opposing_counsel_phone", label: "Counsel phone" }, +]; + +export function CaseLitigationTab({ caseRecord, canManage, onSaved }: Props) { + const [editing, setEditing] = useState(false); + const [saving, setSaving] = useState(false); + const [form, setForm] = useState(() => ({ ...caseRecord })); + const [keyDates, setKeyDates] = useState>( + Array.isArray(caseRecord.key_dates) ? caseRecord.key_dates : [], + ); + + const startEdit = () => { + setForm({ ...caseRecord }); + setKeyDates(Array.isArray(caseRecord.key_dates) ? caseRecord.key_dates : []); + setEditing(true); + }; + + const cancel = () => { + setEditing(false); + }; + + const save = async () => { + setSaving(true); + const payload: any = { key_dates: keyDates.filter((k) => k.date || k.label) }; + [...FIELDS, ...OPPOSING, { key: "case_summary", label: "", type: "text" }, { key: "next_hearing_notes", label: "", type: "text" }].forEach((f) => { + const v = form[f.key]; + if (f.type === "number") payload[f.key] = v === "" || v == null ? null : Number(v); + else payload[f.key] = v === "" ? null : v ?? null; + }); + const { error } = await supabase.from("cases").update(payload).eq("id", caseRecord.id); + setSaving(false); + if (error) { + toast.error("Could not save", { description: error.message }); + return; + } + toast.success("Litigation details updated"); + setEditing(false); + onSaved(); + }; + + const renderValue = (key: string, type?: string) => { + const v = caseRecord[key]; + if (v == null || v === "") return —; + if (type === "date") return formatDate(v); + if (type === "number") return formatCurrency(Number(v)); + return String(v); + }; + + const updateKeyDate = (i: number, patch: Partial<{ date: string; label: string }>) => { + setKeyDates((prev) => prev.map((k, idx) => (idx === i ? { ...k, ...patch } : k))); + }; + + return ( +
+
+
+

Litigation overview

+

Court details, opposing parties, and key dates.

+
+ {canManage && !editing && ( + + )} + {editing && ( +
+ + +
+ )} +
+ + + +
} title="Case summary"> + {editing ? ( +