59 lines
2.4 KiB
TypeScript
59 lines
2.4 KiB
TypeScript
import { Link } from 'react-router';
|
|
import { MessageSquare, Trash2 } from 'lucide-react';
|
|
import { Widget } from '@/components/Widget';
|
|
import { useChatSessions } from '@/state/useChatSessions';
|
|
|
|
export const ChatHistory = () => {
|
|
const { sessions, deleteSession } = useChatSessions();
|
|
|
|
return (
|
|
<Widget title="Chat History">
|
|
<div className="px-4 pb-3 max-h-72 overflow-y-auto">
|
|
{sessions.length === 0 ? (
|
|
<p className="text-xs text-duck-dark/40 py-4 text-center">No sessions yet</p>
|
|
) : (
|
|
<ul className="space-y-0.5">
|
|
{sessions.map((session) => (
|
|
<li
|
|
key={`${session.provider}-${session.id}`}
|
|
className="flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-duck-dark/5 group"
|
|
>
|
|
<Link
|
|
to={session.provider === 'claude' ? `/chat/${session.id}` : `/chat/opencode/${session.id}`}
|
|
className="flex items-center gap-2 flex-1 min-w-0"
|
|
>
|
|
<MessageSquare className="h-4 w-4 shrink-0 text-duck-teal/60" />
|
|
<div className="min-w-0 flex-1">
|
|
<span className="text-sm text-duck-dark truncate block">{session.title}</span>
|
|
<span className="text-xs text-duck-dark/40 truncate block">
|
|
{new Date(session.createdAt).toLocaleDateString(undefined, {
|
|
month: 'short',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
})}
|
|
<span
|
|
className={`ml-1.5 font-medium ${
|
|
session.provider === 'claude' ? 'text-duck-teal' : 'text-duck-orange'
|
|
}`}
|
|
>
|
|
{session.provider === 'claude' ? 'Claude' : 'OpenCode'}
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</Link>
|
|
<button
|
|
onClick={() => deleteSession(session.provider, session.id)}
|
|
className="shrink-0 p-1 rounded text-duck-dark/20 md:opacity-0 md:group-hover:opacity-100 hover:text-red-500 transition-opacity cursor-pointer"
|
|
>
|
|
<Trash2 className="h-3.5 w-3.5" />
|
|
</button>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
</Widget>
|
|
);
|
|
};
|