fix(precedents): פיצול תג-הלכות ל-מאושר/ממתין/נדחה + הדגשת שורות-טיפול #215

Merged
chaim merged 1 commits from worktree-halacha-3split into main 2026-06-12 04:30:24 +00:00
3 changed files with 35 additions and 5 deletions

View File

@@ -3700,7 +3700,11 @@ async def list_external_case_law(
created_at,
(SELECT COUNT(*) FROM halachot h WHERE h.case_law_id = case_law.id) AS halachot_count,
(SELECT COUNT(*) FROM halachot h WHERE h.case_law_id = case_law.id
AND h.review_status IN ('approved', 'published')) AS approved_count
AND h.review_status IN ('approved', 'published')) AS approved_count,
(SELECT COUNT(*) FROM halachot h WHERE h.case_law_id = case_law.id
AND h.review_status IN ('pending_review', 'deferred')) AS pending_count,
(SELECT COUNT(*) FROM halachot h WHERE h.case_law_id = case_law.id
AND h.review_status = 'rejected') AS rejected_count
FROM case_law
WHERE {where_sql}
ORDER BY created_at DESC

View File

@@ -138,13 +138,37 @@ function StatusPill({ p }: { p: Precedent }) {
if (p.halachot_count === 0) {
return <Badge variant="outline">ללא הלכות</Badge>;
}
// Split the count into approved / pending / rejected so a high total no
// longer reads as "lots waiting" when the remainder is actually rejected.
// Pending is the only state that needs the chair — highlight it in red.
const hasPending = p.pending_count > 0;
return (
<Badge variant="outline" className="bg-gold-wash text-gold-deep border-gold/40">
{p.approved_count}/{p.halachot_count} מאושרות
<Badge
variant="outline"
dir="ltr"
className="bg-gold-wash text-gold-deep border-gold/40 tabular-nums"
title={`${p.approved_count} מאושרות · ${p.pending_count} ממתינות · ${p.rejected_count} נדחו`}
>
<span className="text-success font-semibold">{p.approved_count}</span>
<span className="text-ink-light">/</span>
<span className={hasPending ? "text-danger font-bold" : "text-ink-light"}>
{p.pending_count}
</span>
<span className="text-ink-light">/</span>
<span className="text-ink-muted">{p.rejected_count}</span>
<span className="ms-1 text-[0.7rem] text-ink-muted">הלכות</span>
</Badge>
);
}
// Rows with halachot still awaiting the chair get a reddish wash so the
// "needs attention" queue is visible at a glance without opening each row.
function rowClassName(p: Precedent): string {
return p.pending_count > 0
? "border-rule bg-danger-bg/40 hover:bg-danger-bg/60 align-top"
: "border-rule hover:bg-gold-wash/30 align-top";
}
function CourtRow({ p, onEdit }: { p: Precedent; onEdit: (id: string) => void }) {
const del = useDeletePrecedent();
const reqHalachot = useRequestHalachotExtraction();
@@ -175,7 +199,7 @@ function CourtRow({ p, onEdit }: { p: Precedent; onEdit: (id: string) => void })
};
return (
<TableRow className="border-rule hover:bg-gold-wash/30 align-top">
<TableRow className={rowClassName(p)}>
<TableCell
className="font-semibold text-navy text-right whitespace-normal break-words min-w-[280px] max-w-[420px] py-3"
dir="rtl"
@@ -276,7 +300,7 @@ function CommitteeRow({ p, onEdit }: { p: Precedent; onEdit: (id: string) => voi
};
return (
<TableRow className="border-rule hover:bg-gold-wash/30 align-top">
<TableRow className={rowClassName(p)}>
<TableCell
className="font-semibold text-navy text-right whitespace-normal break-words min-w-[200px] max-w-[320px] py-3"
dir="rtl"

View File

@@ -57,6 +57,8 @@ export type Precedent = {
created_at: string;
halachot_count: number;
approved_count: number;
pending_count: number;
rejected_count: number;
};
export type Halacha = {