"use client"; import { useMemo, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { CorroborationBadge } from "@/components/precedents/corroboration-badge"; import type { Halacha } from "@/lib/api/precedent-library"; const RULE_TYPE_LABELS: Record = { binding: "הלכה מחייבת", interpretive: "פרשני", procedural: "פרוצדורלי", obiter: "אמרת אגב", application: "יישום הלכה", persuasive: "משכנע", }; type StatusFilter = "all" | "approved" | "pending" | "rejected"; export function ReviewStatusPill({ status }: { status: Halacha["review_status"] }) { if (status === "approved" || status === "published") { return ( מאושרת ); } if (status === "pending_review") { return ( ממתינה ); } return ( נדחתה ); } /* Read-only roll-up of every halacha extracted from a precedent — * approved + pending + rejected. The "ממתין לאישור" tab only surfaces * pending items globally; this section is the per-case view. To act on * an item (approve / edit / reject), go to the review tab — keeping the * surfaces separated avoids duplicate review UX in two places. */ export function ExtractedHalachotSection({ halachot }: { halachot: Halacha[] }) { const [filter, setFilter] = useState("all"); const counts = useMemo(() => { const c = { all: halachot.length, approved: 0, pending: 0, rejected: 0 }; for (const h of halachot) { if (h.review_status === "approved" || h.review_status === "published") { c.approved++; } else if (h.review_status === "pending_review") { c.pending++; } else if (h.review_status === "rejected") { c.rejected++; } } return c; }, [halachot]); const sorted = useMemo(() => { const matches = (h: Halacha) => { if (filter === "all") return true; if (filter === "approved") { return h.review_status === "approved" || h.review_status === "published"; } if (filter === "pending") return h.review_status === "pending_review"; return h.review_status === "rejected"; }; /* Surface citation-corroborated halachot first: any with a badge * (positive count or a negative treatment) float to the top, ordered * by corroboration strength; the rest keep document order by index. */ const hasTag = (h: Halacha) => (h.corroboration_count ?? 0) > 0 || (h.corroboration_negative ?? false); return halachot .filter(matches) .sort((a, b) => { const tagDelta = Number(hasTag(b)) - Number(hasTag(a)); if (tagDelta !== 0) return tagDelta; const countDelta = (b.corroboration_count ?? 0) - (a.corroboration_count ?? 0); if (countDelta !== 0) return countDelta; return a.halacha_index - b.halacha_index; }); }, [halachot, filter]); if (!halachot.length) { return (
עדיין לא חולצו הלכות מהפסיקה הזו.
); } const tabs: { key: StatusFilter; label: string; count: number }[] = [ { key: "all", label: "הכל", count: counts.all }, { key: "approved", label: "מאושרות", count: counts.approved }, { key: "pending", label: "ממתינות", count: counts.pending }, { key: "rejected", label: "נדחו", count: counts.rejected }, ]; return (

הלכות שחולצו ({counts.all})

{tabs.map((t) => { const active = filter === t.key; return ( ); })}
{!sorted.length ? (
אין הלכות בקטגוריה זו.
) : (
    {sorted.map((h) => (
  1. #{h.halacha_index} {RULE_TYPE_LABELS[h.rule_type] ?? h.rule_type} ביטחון {h.confidence.toFixed(2)} {h.page_reference ? ( {h.page_reference} ) : null}

    {h.rule_statement}

    {h.reasoning_summary ? (

    היגיון: {h.reasoning_summary}

    ) : null} {h.supporting_quote ? (
    “{h.supporting_quote}”
    ) : null} {h.subject_tags?.length ? (
    {h.subject_tags.map((t) => ( {t} ))}
    ) : null}
  2. ))}
)}
); }