| 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> |
| ); |
| } |
|
|