"use client"; import { Skeleton } from "@/components/ui/skeleton"; import { useLibraryStats } from "@/lib/api/precedent-library"; import { practiceAreaLabel } from "./practice-area"; const fmt = (n: number) => n.toLocaleString("he-IL"); function StatCard({ label, value }: { label: string; value: number | string }) { return (
{label}
{value}
); } /** #5 — review-status funnel: one stacked bar (approved / pending / rejected) * + legend with counts. Surfaces the rejected count now exposed by the stats * endpoint, so the review pipeline is visible at a glance (mockup 07b). */ function ReviewFunnel({ approved, pending, rejected, }: { approved: number; pending: number; rejected: number }) { const total = approved + pending + rejected; const pct = (n: number) => (total > 0 ? `${(n / total) * 100}%` : "0%"); return (

סטטוס סקירת הלכות

מאושרות (זמינות לסוכנים) {fmt(approved)} ממתינות לאישור {fmt(pending)} נדחו {fmt(rejected)}
); } /** Distribution rendered as horizontal bars (was a plain count list). */ function DistributionBars({ title, rows, }: { title: string; rows: { label: string; count: number }[] }) { const max = Math.max(1, ...rows.map((r) => r.count)); return (

{title}

{rows.length === 0 ? (

אין נתונים

) : ( )}
); } export function LibraryStatsPanel() { const { data, isPending, error } = useLibraryStats(); if (error) { return (
{error.message}
); } if (isPending || !data) { return (
{[...Array(2)].map((_, i) => )}
); } return (
({ label: practiceAreaLabel(r.practice_area || null), count: r.count, }))} /> ({ label: r.precedent_level || "לא סווג", count: r.count, }))} />
); }