feat(ui): IA redesign → production · יישום נאמן של 16 הדפים הנותרים למוקאפים
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 6s
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 6s
תיקון הגישה: יישום מלא ונאמן של עיצוב-המוקאפים המאושרים (Claude Design) על כל הדפים — שינוי-הרכב אמיתי פר-מוקאפ, לא ליטוש-טוקנים. כל hook/query/mutation/טאב/ טופס/נתון נשמר (אומת: tsc נקי + בדיקת-נוכחות hooks קריטיים; 0 פונקציונליות נמחקה). דפים (← מוקאפ): - בית — לוח: KPI + "תיקים לפי סטטוס" (bars) + כרטיס-אישורים + CTA כפול. - ארכיון — filter-bar שטוח + טבלה נקייה + צ'יפי-סוג/תוצאה. - הערות יו״ר — פריסה דו-טורית + טופס-הוספה חי + כרטיסי-הערה. - ספריית-פסיקה — tabs קו-תחתון + כרטיסי-תוצאה halacha/קטע + AuthorityBadge. - דף-תקדים — באנר-meta parchment + דו-טורי + provenance pills. - פסיקה-חסרה — pill פתוחים + צ'יפי-סטטוס + CTA העלאה. - יומונים — אזור-העלאה מקווקו + כרטיסי-digest + "ממתין" כתווית פסיבית. - גרף — פאנל-צד שכבות/אנליטיקה + canvas parchment. - אימון-סגנון — פורטרט: banner + KPI + אנטומיה + ביטויי-חתימה. - מתודולוגיה — עורך-צ'קליסט + "חל על:" + canon chip. - מיומנויות/סקריפטים — טבלאות אמיתיות + צ'יפי-סטטוס. - הגדרות — sidenav דו-טורי + env-rows עם "ממתין ל-redeploy". - דף-תיק — באנר-תיק parchment + tabs + timeline + "פתח עורך החלטה". - תפעול — SectionHeaders + טבלת-שירותים + כרטיסי-שער gold-wash. - compose — באנר-תיק + SOT pill + פריסה דו-טורית + "השלמה והעברה". תיקונים שלי אחרי הסוכנים: documents-panel (הוצאת רכיב Shell מ-render — React Compiler), scripts useMemo deps. /approvals כבר נבנה מחדש נאמנה (commit קודם). בדיקות: npx tsc --noEmit ✓ · eslint ✓ (לבד מ-learning-panel:109 קיים-מראש). שימור-פונקציונליות אומת. CI Docker build = שער סופי לפני deploy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,10 @@
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { SubjectDonut } from "@/components/training/subject-donut";
|
||||
import { useStyleReport } from "@/lib/api/training";
|
||||
import { useStyleReport, useCuratorStats } from "@/lib/api/training";
|
||||
|
||||
// Mockup 12 anatomy palette — info · gold · gold-deep · success, cycling.
|
||||
const ANATOMY_COLORS = ["#4e6a8c", "#a97d3a", "#8b6428", "#4a7c59"];
|
||||
|
||||
function KPICard({
|
||||
label,
|
||||
@@ -16,15 +19,13 @@ function KPICard({
|
||||
}) {
|
||||
return (
|
||||
<Card className="bg-surface border-rule shadow-sm">
|
||||
<CardContent className="px-5 py-4 flex flex-col gap-0.5">
|
||||
<span className="text-[0.72rem] uppercase tracking-[0.08em] text-ink-muted">
|
||||
{label}
|
||||
</span>
|
||||
<span className="font-display text-[2rem] font-black leading-none text-navy">
|
||||
<CardContent className="px-[18px] py-4 flex flex-col">
|
||||
<span className="font-display text-[1.85rem] font-bold leading-[1.1] text-navy tabular-nums">
|
||||
{value}
|
||||
</span>
|
||||
<span className="text-[0.81rem] text-ink-soft mt-1">{label}</span>
|
||||
{caption && (
|
||||
<span className="text-[0.78rem] text-ink-muted mt-1">{caption}</span>
|
||||
<span className="text-[0.72rem] text-ink-muted mt-0.5">{caption}</span>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -33,6 +34,7 @@ function KPICard({
|
||||
|
||||
export function StyleReportPanel() {
|
||||
const { data, isPending, error } = useStyleReport();
|
||||
const curator = useCuratorStats();
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
@@ -63,14 +65,13 @@ export function StyleReportPanel() {
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Headline */}
|
||||
<Card className="bg-gold-wash border-gold/40 shadow-sm">
|
||||
<CardContent className="px-6 py-4">
|
||||
<p className="font-display text-gold-deep text-lg font-semibold leading-snug">
|
||||
★ {c.headline}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
{/* Headline banner — gold-wash, ★ aligned to start (mockup 12) */}
|
||||
<div className="flex items-start gap-3 rounded-lg border border-gold bg-gold-wash px-5 py-4 shadow-sm">
|
||||
<span className="text-gold-deep text-xl leading-tight shrink-0">★</span>
|
||||
<p className="text-ink-soft text-[0.95rem] leading-relaxed m-0">
|
||||
{c.headline}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* KPIs */}
|
||||
<div className="grid gap-4 grid-cols-2 lg:grid-cols-4">
|
||||
@@ -121,23 +122,22 @@ export function StyleReportPanel() {
|
||||
{data.anatomy.sections.length === 0 ? (
|
||||
<p className="text-ink-muted text-sm">אין נתונים על מבנה</p>
|
||||
) : (
|
||||
<ul className="space-y-2.5">
|
||||
{data.anatomy.sections.map((s) => {
|
||||
<ul className="space-y-3.5">
|
||||
{data.anatomy.sections.map((s, i) => {
|
||||
const pct = Math.round(s.pct * 100);
|
||||
const fill = ANATOMY_COLORS[i % ANATOMY_COLORS.length];
|
||||
return (
|
||||
<li key={s.type} className="space-y-1">
|
||||
<div className="flex items-center justify-between text-[0.78rem]">
|
||||
<span className="text-ink-soft font-medium">
|
||||
{s.label}
|
||||
</span>
|
||||
<span className="text-ink-muted tabular-nums">
|
||||
<li key={s.type} className="space-y-1.5">
|
||||
<div className="flex items-center justify-between text-[0.81rem]">
|
||||
<span className="text-ink-soft">{s.label}</span>
|
||||
<span className="text-navy font-semibold tabular-nums">
|
||||
{pct}% · {s.avg_chars.toLocaleString()} תווים
|
||||
</span>
|
||||
</div>
|
||||
<div className="h-2 rounded bg-rule-soft overflow-hidden">
|
||||
<div className="h-2.5 rounded-full bg-rule-soft overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-gradient-to-l from-gold to-gold-deep"
|
||||
style={{ width: `${pct}%` }}
|
||||
className="h-full rounded-full"
|
||||
style={{ width: `${pct}%`, backgroundColor: fill }}
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
@@ -149,50 +149,92 @@ export function StyleReportPanel() {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Signature phrases */}
|
||||
<Card className="bg-surface border-rule shadow-sm">
|
||||
<CardContent className="px-6 py-5">
|
||||
<h3 className="text-navy text-lg mb-1">ביטויי חתימה</h3>
|
||||
{data.signature_phrases.headline && (
|
||||
<p className="text-[0.78rem] text-gold-deep mb-4">
|
||||
{data.signature_phrases.headline}
|
||||
</p>
|
||||
)}
|
||||
{data.signature_phrases.items.length === 0 ? (
|
||||
<p className="text-ink-muted text-sm">אין ביטויים שחולצו עדיין</p>
|
||||
) : (
|
||||
<ol className="space-y-2">
|
||||
{data.signature_phrases.items.slice(0, 12).map((p, i) => (
|
||||
<li
|
||||
key={`${p.type}-${i}`}
|
||||
className="flex items-start gap-3 rounded border border-rule bg-parchment/40 px-3 py-2"
|
||||
>
|
||||
<span className="text-[0.7rem] text-ink-muted tabular-nums shrink-0 mt-0.5">
|
||||
#{i + 1}
|
||||
</span>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-ink leading-relaxed text-sm">{p.text}</p>
|
||||
{p.context && (
|
||||
<p className="text-[0.7rem] text-ink-muted mt-0.5">
|
||||
{p.context}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<span
|
||||
className="
|
||||
shrink-0 text-[0.72rem] rounded-full
|
||||
bg-gold-wash text-gold-deep border border-gold/40
|
||||
px-2 py-0.5 tabular-nums
|
||||
"
|
||||
{/* Signature phrases + curator stat — two columns (mockup 12) */}
|
||||
<div className="grid gap-6 lg:grid-cols-2 items-start">
|
||||
<Card className="bg-surface border-rule shadow-sm">
|
||||
<CardContent className="px-6 py-5">
|
||||
<h3 className="text-navy text-lg mb-1">ביטויי חתימה</h3>
|
||||
{data.signature_phrases.headline && (
|
||||
<p className="text-[0.78rem] text-gold-deep mb-3">
|
||||
{data.signature_phrases.headline}
|
||||
</p>
|
||||
)}
|
||||
{data.signature_phrases.items.length === 0 ? (
|
||||
<p className="text-ink-muted text-sm">אין ביטויים שחולצו עדיין</p>
|
||||
) : (
|
||||
<ol>
|
||||
{data.signature_phrases.items.slice(0, 12).map((p, i) => (
|
||||
<li
|
||||
key={`${p.type}-${i}`}
|
||||
className="flex items-baseline gap-2.5 py-2.5 border-b border-rule-soft last:border-b-0"
|
||||
>
|
||||
×{p.frequency}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
<span className="w-5 shrink-0 text-gold-deep font-bold tabular-nums text-sm">
|
||||
{i + 1}
|
||||
</span>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-ink-soft leading-relaxed text-[0.85rem] m-0">
|
||||
{p.text}
|
||||
</p>
|
||||
{p.context && (
|
||||
<p className="text-[0.7rem] text-ink-muted mt-0.5 m-0">
|
||||
{p.context}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<span className="shrink-0 text-[0.72rem] font-semibold rounded-full bg-gold-wash text-gold-deep border border-rule px-2.5 py-0.5 tabular-nums whitespace-nowrap">
|
||||
×{p.frequency}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Curator — surfaced style findings (INV-LRN1 writer gate) */}
|
||||
<Card className="bg-surface border-rule shadow-sm">
|
||||
<CardContent className="px-6 py-5 flex flex-col gap-4">
|
||||
<h3 className="text-navy text-lg m-0">אוצֵר — ממצאי-סגנון</h3>
|
||||
<div className="flex items-center gap-4 rounded-lg border border-success bg-success-bg px-[18px] py-3.5">
|
||||
<span className="text-success font-bold text-[1.75rem] leading-none tabular-nums">
|
||||
{curator.data ? curator.data.findings_approved : "—"}
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<b className="text-navy text-sm font-semibold block">
|
||||
ממצאים מאושרים (זורמים לכותב)
|
||||
</b>
|
||||
<span className="text-ink-muted text-[0.78rem]">
|
||||
אושרו ע״י היו״ר · review_status=approved
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-3.5">
|
||||
<div className="flex-1 rounded-lg border border-rule bg-warn-bg px-3.5 py-3">
|
||||
<div className="text-warn font-bold text-[1.35rem] tabular-nums leading-none">
|
||||
{curator.data
|
||||
? Math.max(
|
||||
0,
|
||||
curator.data.total_findings -
|
||||
curator.data.findings_approved,
|
||||
)
|
||||
: "—"}
|
||||
</div>
|
||||
<div className="text-[0.78rem] text-ink-soft mt-1">לא-מאושרים</div>
|
||||
</div>
|
||||
<div className="flex-1 rounded-lg border border-rule bg-rule-soft px-3.5 py-3">
|
||||
<div className="text-ink-muted font-bold text-[1.35rem] tabular-nums leading-none">
|
||||
{curator.data ? curator.data.total_findings : "—"}
|
||||
</div>
|
||||
<div className="text-[0.78rem] text-ink-soft mt-1">סך ממצאים</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-[0.72rem] text-ink-muted leading-relaxed m-0">
|
||||
רק ממצא מאושר זורם לכותב (INV-LRN1). ממתינים ונדחים אינם משפיעים על
|
||||
הטיוטות.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user