Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | "use client"; /** * @file EvolutionLogsTable.tsx * جدول عرض Evolution Logs مع فلترة ذكية ودعم ملاحظات 📌 */ import React, { useMemo, useState } from "react"; import { getEvolutionLogs, clearEvolutionLogs, } from "@/lib/evolution/history.collector"; export const EvolutionLogsTable: React.FC = () => { const [filter, setFilter] = useState<"" | "Integrate" | "Reform" | "Reset">( "" ); const logs = getEvolutionLogs(); const filtered = useMemo( () => (filter ? logs.filter((l) => l.trend === filter) : logs), [filter, logs] ); return ( <div className="rounded-2xl border border-[hsl(var(--border))/50] bg-[hsl(var(--card))/80] p-4"> <div className="flex items-center justify-between mb-3"> <h3 className="text-[hsl(var(--primary))] font-semibold"> Evolution Logs </h3> <div className="flex gap-2 items-center"> <select value={filter} onChange={(e) => setFilter(e.target.value as any)} className="bg-[hsl(var(--muted))] border border-[hsl(var(--border))/60] rounded-md px-2 py-1 text-sm text-[hsl(var(--foreground))]" > <option value="">All</option> <option value="Integrate">Integrate</option> <option value="Reform">Reform</option> <option value="Reset">Reset</option> </select> <button className="text-xs px-2 py-1 rounded-md border border-[hsl(var(--border))/60] hover:bg-white/5" onClick={() => { if (confirm("Clear all evolution logs?")) clearEvolutionLogs(); location.reload(); }} > Clear </button> </div> </div> <div className="overflow-auto max-h-72 rounded-md border border-[hsl(var(--border))/40]"> <table className="w-full text-sm"> <thead className="bg-[hsl(var(--muted))/50] sticky top-0"> <tr className="text-left text-[hsl(var(--muted-foreground))]"> <th className="px-3 py-2">Time</th> <th className="px-3 py-2">Trend</th> <th className="px-3 py-2">Confidence</th> <th className="px-3 py-2">Δ Rate</th> <th className="px-3 py-2">Notes</th> </tr> </thead> <tbody> {filtered.length === 0 ? ( <tr> <td colSpan={5} className="px-3 py-4 text-center text-[hsl(var(--muted-foreground))]" > No logs yet. </td> </tr> ) : ( filtered.map((l) => ( <tr key={l.id} className="border-t border-[hsl(var(--border))/30] hover:bg-[hsl(var(--muted))/20] transition" > <td className="px-3 py-2 text-[hsl(var(--foreground))]/90"> {new Date(l.timestamp).toLocaleString()} </td> <td className="px-3 py-2 font-medium" style={{ color: l.trend === "Integrate" ? "#00ff88" : l.trend === "Reform" ? "#f4d03f" : "#ff4d4f", }} > {l.trend} </td> <td className="px-3 py-2"> {(l.confidence * 100).toFixed(1)}% </td> <td className="px-3 py-2">{l.changeRate.toFixed(2)}%</td> <td className="px-3 py-2 text-sm"> {l.notes?.includes("📌") ? ( <span className="text-amber-400 font-medium"> {l.notes} </span> ) : ( <span className="text-[hsl(var(--muted-foreground))]"> {l.notes || "-"} </span> )} </td> </tr> )) )} </tbody> </table> </div> </div> ); }; |