Spaces:
Running
Running
File size: 3,589 Bytes
dd87944 | 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 | import React, { useEffect, useState } from "react";
import { http } from "../lib/api";
import { Brain, Trash2, Plus, Sparkles } from "lucide-react";
import { toast } from "sonner";
export default function MemoryPanel() {
const [memories, setMemories] = useState([]);
const [adding, setAdding] = useState(false);
const [newContent, setNewContent] = useState("");
const refresh = async () => {
const r = await http.get("/memories");
setMemories(r.data);
};
useEffect(() => { refresh(); }, []);
const create = async () => {
if (!newContent.trim()) return;
await http.post("/memories", { content: newContent.trim() });
setNewContent("");
setAdding(false);
refresh();
};
const remove = async (id) => {
await http.delete(`/memories/${id}`);
refresh();
toast.success("Mémoire supprimée");
};
return (
<div className="h-full overflow-y-auto scrollbar-thin p-4 space-y-3" data-testid="memory-panel">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Brain size={14} style={{ color: "var(--mode-color)" }} />
<h3 className="font-heading text-sm">Mémoire long-terme</h3>
<span className="text-[10px] text-muted-em">{memories.length}</span>
</div>
<button
data-testid="add-memory-btn"
onClick={() => setAdding(!adding)}
className="p-1 rounded em-hover"
>
<Plus size={14} />
</button>
</div>
{adding && (
<div className="space-y-2 p-3 rounded-xl glass-card">
<textarea
data-testid="memory-input"
value={newContent}
onChange={(e) => setNewContent(e.target.value)}
rows={2}
placeholder="Mémoire"
className="w-full em-input rounded-lg px-3 py-2 text-xs focus:border-purple-500/40 resize-none"
/>
<div className="flex gap-2 justify-end">
<button onClick={() => { setAdding(false); setNewContent(""); }} className="text-xs text-muted-em px-2 py-1">
Annuler
</button>
<button
data-testid="memory-save-btn"
onClick={create}
className="text-xs px-3 py-1 rounded-lg"
style={{ background: "var(--mode-color)", color: "var(--emo-on-mode)" }}
>
Ajouter
</button>
</div>
</div>
)}
{memories.length === 0 && !adding && (
<p className="text-xs text-muted-em text-center pt-8">
Aucune mémoire enregistrée. Émo apprendra de tes conversations automatiquement.
</p>
)}
{memories.map((m) => (
<div
key={m.memory_id}
data-testid={`memory-${m.memory_id}`}
className="group p-3 rounded-xl glass-card text-xs flex items-start gap-2"
>
{m.source === "auto" ? (
<Sparkles size={11} className="mt-0.5 flex-shrink-0" style={{ color: "var(--mode-color)" }} />
) : (
<Brain size={11} className="mt-0.5 flex-shrink-0 opacity-50" />
)}
<p className="flex-1 leading-relaxed text-secondary-em">{m.content}</p>
<button
data-testid={`memory-delete-${m.memory_id}`}
onClick={() => remove(m.memory_id)}
className="opacity-0 group-hover:opacity-100 transition p-0.5 text-muted-em hover:text-red-400"
>
<Trash2 size={11} />
</button>
</div>
))}
</div>
);
}
|