import { useEffect, useState, useCallback } from "react"; import { Link } from "react-router-dom"; import { fetchMemories, getFeedbackApi } from "../api/client.ts"; import type { Feedback } from "@fixonce/shared"; interface FeedbackWithMemoryTitle extends Feedback { memory_title: string; } export function RecentFeedback() { const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filterTag, setFilterTag] = useState(""); const [filterAction, setFilterAction] = useState(""); const loadFeedback = useCallback(async () => { setLoading(true); setError(null); try { // Get recent memories and then fetch feedback for each const memResult = await fetchMemories({ query: "", verbosity: "small", max_results: "50", }); const allFeedback: FeedbackWithMemoryTitle[] = []; for (const memory of memResult.results) { const fb = await getFeedbackApi(memory.id); for (const f of fb) { allFeedback.push({ ...f, memory_title: memory.title }); } } // Sort by date descending allFeedback.sort( (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime(), ); setItems(allFeedback); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load feedback"); } finally { setLoading(false); } }, []); useEffect(() => { void loadFeedback(); }, [loadFeedback]); const filteredItems = items.filter((fb) => { if (filterTag && !fb.tags.includes(filterTag as Feedback["tags"][number])) return false; if (filterAction && fb.suggested_action !== filterAction) return false; return true; }); if (loading) return

Loading feedback...

; return (

Recent Feedback

{error &&

{error}

}

Showing {filteredItems.length} of {items.length} feedback entries

{filteredItems.length > 0 ? ( {filteredItems.map((fb) => ( ))}
Memory Tags Action Comment Date
{fb.memory_title} {fb.tags.join(", ") || "-"} {fb.suggested_action ? ( {fb.suggested_action} ) : ( "-" )} {fb.text ?? "-"} {new Date(fb.created_at).toLocaleString()}
) : (

No feedback entries found.

)}
); } const fieldRow: React.CSSProperties = { display: "flex", flexDirection: "column", gap: "0.25rem", }; const inputStyle: React.CSSProperties = { padding: "0.4rem 0.5rem", border: "1px solid #ccc", borderRadius: "3px", fontSize: "0.9rem", }; const thStyle: React.CSSProperties = { textAlign: "left", padding: "0.5rem", borderBottom: "2px solid #ddd", }; const tdStyle: React.CSSProperties = { padding: "0.5rem", borderBottom: "1px solid #eee", };