"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import { AppShell } from "@/components/app-shell"; import { Input } from "@/components/ui/input"; import { useMissingPrecedents, type MissingPrecedentStatus, } from "@/lib/api/missing-precedents"; import { MissingPrecedentsTable } from "@/components/missing-precedents/missing-precedents-table"; /** * Missing-precedents page (TaskMaster #35). * * Surfaces citations that party briefs invoke but which aren't yet in the * precedent_library. A status filter (chips) narrows the table; each row uses * the same table component. Drawer (sheet) opens on row click with metadata + * upload form that routes to internal_decision_upload (ערר/בל"מ citations) or * precedent_library_upload (court rulings). */ type StatusFilter = MissingPrecedentStatus | "all"; const STATUS_CHIPS: { value: StatusFilter; label: string }[] = [ { value: "open", label: "פתוח" }, { value: "uploaded", label: "הועלה" }, { value: "closed", label: "נסגר" }, { value: "irrelevant", label: "לא-רלוונטי" }, { value: "all", label: "הכל" }, ]; export default function MissingPrecedentsPage() { const [search, setSearch] = useState(""); const [legalTopic, setLegalTopic] = useState(""); const [filter, setFilter] = useState("open"); /* Debounce the filters so the table fires one query after the user stops * typing — not one per keystroke. The search term matches the gap's own * מראה-מקום, case name, and cited-in appeal number (server-side ILIKE). */ const [searchQ, setSearchQ] = useState(""); const [legalTopicQ, setLegalTopicQ] = useState(""); useEffect(() => { const t = setTimeout(() => setSearchQ(search.trim()), 350); return () => clearTimeout(t); }, [search]); useEffect(() => { const t = setTimeout(() => setLegalTopicQ(legalTopic.trim()), 350); return () => clearTimeout(t); }, [legalTopic]); const counts = useMissingPrecedents({ limit: 1 }); const byStatus = counts.data?.by_status ?? {}; return (
{/* title + inline open-count pill (mockup 09 `.open-count`) */}

פסיקה חסרה בקורפוס

{byStatus.open ? ( {byStatus.open} פתוחים ) : null}

פסיקה שצוטטה בכתבי-הטענות אך אינה קיימת בקורפוס. השלמתה מאפשרת אימות-הלכה ועיגון-מקור (INV-AH). סוכן המחקר רושם פערים אוטומטית; היו"ר סוגר אותם על־ידי העלאת המסמך — ניתוב אוטומטי בין הקורפוס הסמכותי (פסקי דין) להחלטות ועדות ערר.

{/* shared filters */}
setSearch(e.target.value)} placeholder="85074 או 1017-03-26" dir="rtl" />
setLegalTopic(e.target.value)} placeholder="זכות עמידה" dir="rtl" />
{/* status filter chips (mockup 09 `.filters`) — active = navy filled */}
{STATUS_CHIPS.map((c) => { const active = filter === c.value; const count = c.value === "all" ? undefined : (byStatus[c.value as MissingPrecedentStatus] ?? 0); return ( ); })}
{/* lifecycle note (mockup 09 `.lifecycle`) */}
מחזור-חיים:{" "} פתוח →{" "} הועלה →{" "} נסגר. פריט נפתח אוטומטית בעת חילוץ ציטוט שאין לו תקדים בקורפוס; בהעלאת פסק-הדין הוא מקושר לרשומת הפסיקה דרך{" "} linked_case_law_id {" "} ונסגר. פריט שאינו רלוונטי מסומן{" "} לא-רלוונטי מבלי שתידרש העלאה.
); } type LifecycleTone = "open" | "up" | "closed" | "na"; function LifecycleChip({ tone, children, }: { tone: LifecycleTone; children: React.ReactNode; }) { const cls: Record = { open: "bg-warn-bg text-warn", up: "bg-info-bg text-info", closed: "bg-success-bg text-success", na: "bg-rule-soft text-ink-muted", }; return ( {children} ); }