50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { getLatestReflectionForTask } from '../../api';
|
|
|
|
interface ReflectionBadgeProps {
|
|
taskId: number;
|
|
}
|
|
|
|
/**
|
|
* Shows a "🧠 Learned N things [+ piece edit]" pill when the most recent
|
|
* reflection for this task applied changes. Hidden when:
|
|
* - no reflection exists yet
|
|
* - outcome is 'abstained' or 'failed'
|
|
* - no memory changes AND no piece edit
|
|
*
|
|
* Clicking navigates to Settings > Memory & Learning (?page=settings§ion=memory-learning)
|
|
* anchored at the snapshot via a hash fragment.
|
|
*/
|
|
export function ReflectionBadge({ taskId }: ReflectionBadgeProps) {
|
|
const { data } = useQuery({
|
|
queryKey: ['reflection-for-task', taskId],
|
|
queryFn: () => getLatestReflectionForTask(taskId),
|
|
staleTime: 30_000,
|
|
});
|
|
|
|
if (!data) return null;
|
|
if (data.outcome === 'abstained' || data.outcome === 'failed') return null;
|
|
|
|
const n = data.memoryChanges ?? 0;
|
|
if (n === 0 && !data.pieceEdited) return null;
|
|
|
|
const label = data.pieceEdited
|
|
? `Learned ${n} ${n === 1 ? 'thing' : 'things'} + piece edit`
|
|
: `Learned ${n} ${n === 1 ? 'thing' : 'things'}`;
|
|
|
|
// Navigate to Settings > Memory & Learning, anchored at the snapshot.
|
|
// The app uses query-string-based URL state (no react-router), so we build
|
|
// the URL directly. The hash lets MemoryLearningForm scroll to the snapshot
|
|
// when the section loads.
|
|
const href = `?page=settings§ion=memory-learning#snapshot-${data.snapshotId}`;
|
|
|
|
return (
|
|
<a
|
|
href={href}
|
|
className="inline-flex items-center gap-1 rounded-full bg-amber-50 dark:bg-amber-500/15 px-2 py-0.5 text-xs text-amber-700 dark:text-amber-300 hover:bg-amber-100 dark:hover:bg-amber-500/15"
|
|
>
|
|
🧠 {label}
|
|
</a>
|
|
);
|
|
}
|