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:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
@@ -115,84 +115,124 @@ export function ContentChecklistsPanel() {
|
||||
);
|
||||
}
|
||||
|
||||
const itemCount = current
|
||||
? current.draft.split("\n").filter((l) => /^\s*-\s*\[/.test(l)).length
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* Tab selector */}
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
{items.map((item) => (
|
||||
<Button
|
||||
key={item.key}
|
||||
size="sm"
|
||||
variant={active === item.key ? "default" : "outline"}
|
||||
onClick={() => { setActive(item.key); setPreview(false); }}
|
||||
className="text-xs"
|
||||
>
|
||||
{item.label}
|
||||
{item.isOverride && (
|
||||
<Badge variant="secondary" className="text-[9px] mr-1.5 px-1">
|
||||
מותאם
|
||||
</Badge>
|
||||
)}
|
||||
</Button>
|
||||
))}
|
||||
<div className="space-y-[18px]">
|
||||
{/* Type buttons — gold active (mockup 13) */}
|
||||
<div className="flex gap-2.5 flex-wrap">
|
||||
{items.map((item) => {
|
||||
const isActive = active === item.key;
|
||||
return (
|
||||
<button
|
||||
key={item.key}
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setActive(item.key);
|
||||
setPreview(false);
|
||||
}}
|
||||
className={
|
||||
isActive
|
||||
? "rounded-lg border border-gold bg-gold px-4 py-2 text-[0.84rem] font-semibold text-white"
|
||||
: "rounded-lg border border-rule bg-surface px-4 py-2 text-[0.84rem] font-medium text-ink-soft hover:border-gold/50"
|
||||
}
|
||||
>
|
||||
{item.label}
|
||||
{item.isOverride && (
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className={`text-[9px] ms-1.5 px-1 ${isActive ? "bg-white/20 text-white" : ""}`}
|
||||
>
|
||||
מותאם
|
||||
</Badge>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Editor / Preview */}
|
||||
{/* "חל על:" explainer band — gold-wash (mockup 13) */}
|
||||
{current && CHECKLIST_APPLIES[current.key] && (
|
||||
<div className="flex items-baseline gap-2 rounded-lg border border-rule bg-gold-wash px-4 py-2.5 text-[0.84rem] text-ink-soft">
|
||||
<b className="text-gold-deep font-semibold whitespace-nowrap">חל על:</b>
|
||||
<span>{CHECKLIST_APPLIES[current.key]}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Editor — framed card with header chip + parchment editor + footer */}
|
||||
{current && (
|
||||
<Card className="border-rule">
|
||||
<CardContent className="px-5 py-4 space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="min-w-0">
|
||||
<h3 className="text-sm font-semibold text-navy">{current.label}</h3>
|
||||
{CHECKLIST_APPLIES[current.key] && (
|
||||
<p className="text-[0.72rem] text-ink-muted mt-0.5">
|
||||
חל על: {CHECKLIST_APPLIES[current.key]}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => setPreview(!preview)}
|
||||
className="text-xs shrink-0"
|
||||
>
|
||||
{preview ? <EyeOff className="w-3.5 h-3.5 ml-1" /> : <Eye className="w-3.5 h-3.5 ml-1" />}
|
||||
{preview ? "עריכה" : "תצוגה מקדימה"}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{preview ? (
|
||||
<div className="border border-rule rounded-md p-4 bg-sand-soft/30 max-h-[500px] overflow-y-auto">
|
||||
<Markdown content={current.draft} />
|
||||
</div>
|
||||
) : (
|
||||
<Textarea
|
||||
value={current.draft}
|
||||
onChange={(e) => updateDraft(e.target.value)}
|
||||
className="min-h-[400px] font-mono text-sm leading-relaxed"
|
||||
dir="rtl"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Button size="sm" disabled={!current.dirty || update.isPending} onClick={handleSave}>
|
||||
{update.isPending ? <Loader2 className="w-3 h-3 animate-spin ml-1" /> : <Save className="w-3 h-3 ml-1" />}
|
||||
שמור
|
||||
</Button>
|
||||
{current.isOverride && (
|
||||
<Button size="sm" variant="outline" disabled={reset.isPending} onClick={handleReset}>
|
||||
<RotateCcw className="w-3 h-3 ml-1" />
|
||||
איפוס לברירת מחדל
|
||||
</Button>
|
||||
<Card className="border-rule shadow-sm overflow-hidden p-0 gap-0">
|
||||
<div className="flex items-center gap-2.5 px-[18px] py-3.5 border-b border-rule-soft">
|
||||
<h2 className="text-[0.95rem] font-semibold text-navy m-0">
|
||||
צ׳קליסט תוכן — {current.label}
|
||||
</h2>
|
||||
<span
|
||||
className={`ms-auto rounded-full text-xs font-semibold px-2.5 py-0.5 ${
|
||||
current.isOverride
|
||||
? "bg-gold-wash text-gold-deep border border-rule"
|
||||
: "bg-info-bg text-info"
|
||||
}`}
|
||||
>
|
||||
{current.isOverride ? "מותאם" : "ידני"}
|
||||
</span>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => setPreview(!preview)}
|
||||
className="text-xs shrink-0 h-7"
|
||||
>
|
||||
{preview ? (
|
||||
<EyeOff className="w-3.5 h-3.5 ms-1" />
|
||||
) : (
|
||||
<Eye className="w-3.5 h-3.5 ms-1" />
|
||||
)}
|
||||
<Badge
|
||||
variant={current.isOverride ? "default" : "secondary"}
|
||||
className="text-[10px] mr-auto"
|
||||
>
|
||||
{current.isOverride ? "מותאם" : "ברירת מחדל"}
|
||||
</Badge>
|
||||
{preview ? "עריכה" : "תצוגה מקדימה"}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{preview ? (
|
||||
<div className="p-[18px] bg-parchment max-h-[500px] overflow-y-auto border-b border-rule-soft">
|
||||
<Markdown content={current.draft} />
|
||||
</div>
|
||||
</CardContent>
|
||||
) : (
|
||||
<Textarea
|
||||
value={current.draft}
|
||||
onChange={(e) => updateDraft(e.target.value)}
|
||||
className="min-h-[340px] rounded-none border-0 border-b border-rule-soft bg-parchment font-mono text-[0.84rem] leading-[1.95] text-ink-soft focus-visible:ring-0 resize-y"
|
||||
dir="rtl"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-2.5 px-[18px] py-3.5">
|
||||
<Button
|
||||
disabled={!current.dirty || update.isPending}
|
||||
onClick={handleSave}
|
||||
className="bg-gold text-white hover:bg-gold-deep"
|
||||
>
|
||||
{update.isPending ? (
|
||||
<Loader2 className="w-3.5 h-3.5 animate-spin ms-1" />
|
||||
) : (
|
||||
<Save className="w-3.5 h-3.5 ms-1" />
|
||||
)}
|
||||
שמור
|
||||
</Button>
|
||||
{current.isOverride && (
|
||||
<Button
|
||||
variant="outline"
|
||||
disabled={reset.isPending}
|
||||
onClick={handleReset}
|
||||
className="border-rule text-navy"
|
||||
>
|
||||
<RotateCcw className="w-3.5 h-3.5 ms-1" />
|
||||
אפס לברירת-מחדל
|
||||
</Button>
|
||||
)}
|
||||
<span className="ms-auto text-[0.78rem] text-ink-muted tabular-nums">
|
||||
{itemCount} פריטים
|
||||
</span>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user