import React, { useState } from 'react';
import SessionModal from './SessionModal';
import { useContextMenu } from '../hooks/useContextMenu';
import { renameSession, deleteSession } from '../api/orchestration';
export default function SessionList({ sessions, activeSession, onSelectSession, onNewChat, isOpen, onToggle, onSessionsChange }) {
const [modalSession, setModalSession] = useState(null);
const [hoveredId, setHoveredId] = useState(null);
const { menu, open: openMenu, close: closeMenu } = useContextMenu();
const [modalMode, setModalMode] = useState('settings');
function formatDate(ts) {
if (!ts) return '';
const date = new Date(ts * 1000);
const now = new Date();
const diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));
if (diffDays === 0) return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
if (diffDays === 1) return 'Yesterday';
if (diffDays < 7) return date.toLocaleDateString([], { weekday: 'long' });
return date.toLocaleDateString([], { month: 'short', day: 'numeric' });
}
function getPreview(session) {
if (session.isNew) return 'New conversation';
return session.name || session.external_id;
}
async function handleRename(session, name) {
try {
await renameSession(session.external_id, name);
onSessionsChange();
} catch (err) {
console.error('[SessionList] Rename failed:', err.message);
}
}
async function handleDelete(session) {
try {
await deleteSession(session.external_id);
onSessionsChange();
} catch (err) {
console.error('[SessionList] Delete failed:', err.message);
}
}
return (
<>
{/* Header */}
{isOpen && Conversations}
{/* New chat button */}
{/* Session list */}
{isOpen && sessions.map(session => {
const isActive = activeSession?.external_id === session.external_id;
const isHovered = hoveredId === session.external_id;
return (
setHoveredId(session.external_id)}
onMouseLeave={() => setHoveredId(null)}
onContextMenu={e => !session.isNew && openMenu(e, session)}
style={{
position: 'relative',
display: 'flex',
alignItems: 'stretch',
background: isActive ? 'var(--bg-elevated)' : isHovered ? 'var(--bg-elevated)' : 'transparent',
borderLeft: isActive ? '2px solid var(--accent)' : '2px solid transparent',
transition: 'background 0.1s',
}}
>
{/* Session select button — no action icons inside */}
{/* Action icons — outside the button, alongside it */}
{isHovered && !session.isNew && (
)}
);
})}
{isOpen && sessions.length === 0 && (
No conversations yet
)}
{/* Context menu */}
{menu && (
e.stopPropagation()}
style={{
position: 'fixed',
top: menu.y,
left: menu.x,
background: 'var(--bg-elevated)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)',
padding: '4px',
zIndex: 50,
minWidth: '140px',
}}
>
)}
{/* Rename modal */}
{modalSession && (
setModalSession(null)}
/>
)}
>
);
}