diff --git a/web-ui/src/app/cases/[caseNumber]/compose/page.tsx b/web-ui/src/app/cases/[caseNumber]/compose/page.tsx index 5bfcf43..5884779 100644 --- a/web-ui/src/app/cases/[caseNumber]/compose/page.tsx +++ b/web-ui/src/app/cases/[caseNumber]/compose/page.tsx @@ -14,6 +14,10 @@ import { DecisionBlocksPanel } from "@/components/cases/decision-blocks-panel"; import { Markdown } from "@/components/ui/markdown"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { useCase, type CaseStatus } from "@/lib/api/cases"; +import { + useCaseLearningStatus, + type CaseLearningStatus, +} from "@/lib/api/learning"; import { useResearchAnalysis } from "@/lib/api/research"; import { useCasePrecedents } from "@/lib/api/precedents"; import { APPEAL_SUBTYPES } from "@/lib/practice-area"; @@ -52,6 +56,45 @@ function subtypeLabel(subtype?: string | null): string | null { return APPEAL_SUBTYPES.find((s) => s.value === subtype)?.label ?? null; } +// ── Staged-pipeline indicator text (mockup 03) — derived from the live +// learning-status, same source as the drafts-panel LearningStatusBadges. ────── +function voiceLearningText(s?: CaseLearningStatus): string { + if (!s?.final_uploaded) return "ממתין להעלאת הסופי"; + const v = s.voice_learning; + if (v.outcome === "succeeded") { + const bits = [`${v.lessons_count} לקחים הופקו`]; + if (v.lessons_proposed > 0) bits.push(`${v.lessons_proposed} הוצעו לאישור`); + return `✓ הושלם · ${bits.join(" · ")}`; + } + if (v.outcome === "failed") return v.error ? `✗ נכשל — ${v.error}` : "✗ נכשל"; + return "ממתין להרצה"; +} + +function halachaExtractionText(s?: CaseLearningStatus): string { + if (!s?.final_uploaded) return "ממתין להעלאת הסופי"; + const h = s.halacha_extraction; + if (!h.enrolled_in_corpus) + return h.not_enrolled_reason ?? "לא נכנס לקורפוס-הפסיקה"; + switch (h.status) { + case "completed": + return `✓ הושלם · חולצו ${h.halachot_count} · ${h.approved} אושרו · ${h.rejected} נדחו`; + case "processing": + return "רץ עכשיו…"; + case "pending": + case "busy": + return "בתור"; + case "partial": + return `חלקי · חולצו ${h.halachot_count}`; + case "failed": + case "extraction_failed": + return "✗ נכשל"; + case "no_chunks": + return "אין טקסט לחילוץ"; + default: + return "ממתין להרצה"; + } +} + function ProseSection({ title, content }: { title: string; content?: string }) { if (!content?.trim()) return null; return ( @@ -77,6 +120,7 @@ function FinishRail({ const fileRef = useRef(null); const [uploading, setUploading] = useState(false); const [uploadMsg, setUploadMsg] = useState<{ ok: boolean; text: string } | null>(null); + const learning = useCaseLearningStatus(caseNumber); async function handleUpload(file: File) { setUploading(true); @@ -168,10 +212,10 @@ function FinishRail({ {/* mockup 03: stage indicators — informational pointers, not actions */}
- הרץ למידת-קול — ממתין להעלאת הסופי + הרץ למידת-קול — {voiceLearningText(learning.data)}
- הרץ אימות-הלכות — ממתין להעלאת הסופי + הרץ אימות-הלכות — {halachaExtractionText(learning.data)}