Files
resolutionflow/frontend/src/components/flowpilot/SimilarSessions.tsx
Michael Chihlas 56ff792f8e refactor: migrate FlowPilot components to Design System v4
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 01:56:27 -04:00

96 lines
2.9 KiB
TypeScript

import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { Loader2 } from 'lucide-react'
import { aiSessionsApi } from '@/api'
import type { SimilarSession } from '@/types/ai-session'
import { cn } from '@/lib/utils'
interface SimilarSessionsProps {
sessionId: string
}
export function SimilarSessions({ sessionId }: SimilarSessionsProps) {
const [sessions, setSessions] = useState<SimilarSession[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
let cancelled = false
setLoading(true)
aiSessionsApi
.getSimilar(sessionId, 5)
.then((data) => {
if (!cancelled) setSessions(data)
})
.catch(() => {
// Silently ignore errors — don't clutter the UI
})
.finally(() => {
if (!cancelled) setLoading(false)
})
return () => {
cancelled = true
}
}, [sessionId])
if (loading) {
return (
<div className="flex items-center gap-1.5 py-1">
<Loader2 size={10} className="animate-spin text-[#848b9b]" />
<span className="text-[0.625rem] text-[#848b9b] font-sans text-xs">Loading similar sessions</span>
</div>
)
}
if (sessions.length === 0) {
return null
}
return (
<div className="space-y-2">
<h4 className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-[#848b9b]">
Similar Past Sessions
</h4>
{sessions.map((session) => (
<Link
key={session.id}
to={`/pilot/${session.id}`}
className="card-interactive p-3 block hover:border-[rgba(255,255,255,0.12)] transition-all"
>
<div className="flex items-start justify-between gap-2">
<p className="text-xs text-[#e2e5eb] line-clamp-2">
{session.problem_summary || 'Untitled session'}
</p>
<span className="text-[0.625rem] font-sans text-xs text-[#22d3ee] shrink-0">
{Math.round(session.similarity * 100)}%
</span>
</div>
{session.resolution_summary && (
<p className="text-[0.625rem] text-[#848b9b] mt-1 line-clamp-1">
{session.resolution_summary}
</p>
)}
<div className="flex items-center gap-2 mt-1.5">
{session.problem_domain && (
<span className="text-[0.5rem] font-sans text-xs uppercase tracking-wider text-[#848b9b]/70">
{session.problem_domain}
</span>
)}
<span
className={cn(
'text-[0.5rem] font-sans text-xs uppercase',
session.status === 'resolved'
? 'text-emerald-400'
: session.status === 'escalated'
? 'text-amber-400'
: 'text-[#848b9b]'
)}
>
{session.status}
</span>
</div>
</Link>
))}
</div>
)
}