Spaces:
Sleeping
Sleeping
| import { Plus, Trash2 } from "lucide-react"; | |
| import type { Analysis } from "@/services/orchestrationApi"; | |
| import { EmptyState, LoadingState } from "./AnalysisStates"; | |
| import { cx, formatDateTime } from "./utils"; | |
| interface AnalysisSidebarProps { | |
| analyses: Analysis[]; | |
| activeId?: string; | |
| loading: boolean; | |
| onNew: () => void; | |
| onSelect: (analysis: Analysis) => void; | |
| onDelete: (analysis: Analysis) => void; | |
| } | |
| export function AnalysisSidebar({ analyses, activeId, loading, onNew, onSelect, onDelete }: AnalysisSidebarProps) { | |
| return ( | |
| <aside className="flex h-full w-full flex-col border-r border-slate-200 bg-white lg:w-72"> | |
| <div className="border-b border-slate-200 p-4"> | |
| <button | |
| type="button" | |
| aria-label="Create new analysis" | |
| onClick={onNew} | |
| className="flex w-full items-center justify-center gap-2 rounded-md bg-emerald-600 px-3 py-2 text-sm font-medium text-white hover:bg-emerald-700" | |
| > | |
| <Plus className="h-4 w-4" /> | |
| New Analysis | |
| </button> | |
| </div> | |
| <div className="min-h-0 flex-1 overflow-y-auto p-3"> | |
| {loading ? ( | |
| <LoadingState label="Loading analyses" /> | |
| ) : analyses.length === 0 ? ( | |
| <EmptyState title="No analyses yet" description="Create one after your knowledge sources are ready." /> | |
| ) : ( | |
| <div className="space-y-2"> | |
| {analyses.map((analysis) => ( | |
| <button | |
| key={analysis.id} | |
| type="button" | |
| onClick={() => onSelect(analysis)} | |
| className={cx( | |
| "group flex w-full flex-col rounded-lg border p-3 text-left transition", | |
| activeId === analysis.id ? "border-emerald-200 bg-emerald-50" : "border-slate-200 bg-white hover:bg-slate-50" | |
| )} | |
| > | |
| <span className="flex items-start justify-between gap-2"> | |
| <span className="min-w-0 flex-1 truncate text-sm font-medium text-slate-900">{analysis.analysis_title}</span> | |
| <span | |
| role="button" | |
| tabIndex={0} | |
| aria-label="Delete analysis" | |
| onClick={(event) => { | |
| event.stopPropagation(); | |
| onDelete(analysis); | |
| }} | |
| className="rounded p-1 text-slate-400 opacity-0 hover:bg-red-50 hover:text-red-600 group-hover:opacity-100" | |
| > | |
| <Trash2 className="h-3.5 w-3.5" /> | |
| </span> | |
| </span> | |
| <span className="mt-1 line-clamp-2 text-xs leading-5 text-slate-500">{analysis.objective}</span> | |
| <span className="mt-2 text-[11px] text-slate-400">{formatDateTime(analysis.updated_at || analysis.created_at)}</span> | |
| </button> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| </aside> | |
| ); | |
| } | |