import React, { useState, useEffect } from 'react'; import { fetchSessionSummaries } from '../api/orchestration'; import ReactMarkdown from 'react-markdown'; export default function SummaryView({ activeSession, onBack }) { const [summaries, setSummaries] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [expanded, setExpanded] = useState(null); useEffect(() => { if (!activeSession || activeSession.isNew) { setLoading(false); return; } setLoading(true); fetchSessionSummaries(activeSession.external_id) .then(data => setSummaries(Array.isArray(data) ? data : [])) .catch(err => setError(err.message)) .finally(() => setLoading(false)); }, [activeSession]); function formatTimestamp(ts) { if (!ts) return '—'; return new Date(ts * 1000).toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', }); } return (
{/* Header */}
Session Memory {summaries.length} summar{summaries.length !== 1 ? 'ies' : 'y'}
{/* Session name pill */} {activeSession && (
{activeSession.name || activeSession.external_id}
)} {/* Content */}
{loading &&

Loading…

} {error &&

{error}

} {!loading && !activeSession && (

No active session.

)} {!loading && activeSession && summaries.length === 0 && (

No summaries yet for this session.

Summaries generate automatically once a session accumulates enough conversation.

)} {summaries.map(summary => (
{/* Card header */}
setExpanded(expanded === summary.id ? null : summary.id)} style={{ display: 'flex', alignItems: 'center', gap: '10px', padding: '10px 14px', cursor: 'pointer' }} > Episodes {summary.episode_range} {formatTimestamp(summary.created_at)} {expanded === summary.id ? '▲' : '▼'}
{/* Expanded content */} {expanded === summary.id && (
(

{children}

), }}> {summary.content}
{summary.token_count > 0 && (

{summary.token_count.toLocaleString()} tokens covered

)}
)}
))}
); }