import { useSystem } from '@idyllic/react';
import type { ResearchSynthesizer } from '../systems/ResearchSynthesizer';
export default function ResearchUI() {
const { sources, synthesis, stage, approval, addSource, removeSource, analyze, approve } = useSystem<ResearchSynthesizer>();
return (
<div className="max-w-4xl mx-auto p-6">
<StageIndicator stage={stage} />
<SourceInput onAdd={addSource} disabled={stage !== 'collecting'} />
<div className="space-y-4 my-6">
{sources.map(source => (
<SourceCard
key={source.id}
source={source}
onRemove={() => removeSource(source.id)}
showAnalysis={stage !== 'collecting'}
/>
))}
</div>
{stage === 'collecting' && sources.length > 0 && (
<button onClick={analyze} className="w-full py-3 bg-blue-600 text-white rounded">
Analyze {sources.length} Sources
</button>
)}
{['synthesizing', 'reviewing', 'complete'].includes(stage) && (
<SynthesisPanel content={synthesis.current} streaming={stage === 'synthesizing'} />
)}
{approval?.pending && (
<ApprovalDialog
onApprove={() => approve(true)}
onReject={() => approve(false)}
/>
)}
{stage === 'complete' && (
<div className="mt-4 p-4 bg-green-50 border border-green-200 rounded">
Research complete and approved.
</div>
)}
</div>
);
}
function StageIndicator({ stage }: { stage: string }) {
const stages = ['collecting', 'analyzing', 'synthesizing', 'reviewing', 'complete'];
const current = stages.indexOf(stage);
return (
<div className="flex gap-2 mb-6">
{stages.map((s, i) => (
<div key={s} className={`flex-1 h-2 rounded ${i <= current ? 'bg-blue-600' : 'bg-gray-200'}`} />
))}
</div>
);
}
function SourceCard({ source, onRemove, showAnalysis }) {
return (
<div className="border rounded p-4">
<div className="flex justify-between mb-2">
<span className="text-sm text-gray-500">Source</span>
<button onClick={onRemove} className="text-red-500 text-sm">Remove</button>
</div>
<p className="text-sm mb-2 line-clamp-3">{source.content}</p>
{showAnalysis && source.analysis.current && (
<div className="mt-3 pt-3 border-t">
<span className="text-sm text-gray-500">Analysis</span>
<p className="text-sm mt-1 whitespace-pre-wrap">{source.analysis.current}</p>
</div>
)}
</div>
);
}
function ApprovalDialog({ onApprove, onReject }) {
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center">
<div className="bg-white rounded-lg p-6 max-w-md">
<h3 className="text-lg font-medium mb-2">Review Synthesis</h3>
<p className="text-gray-600 mb-4">Does this synthesis accurately represent the sources?</p>
<div className="flex gap-3">
<button onClick={onApprove} className="flex-1 py-2 bg-green-600 text-white rounded">Approve</button>
<button onClick={onReject} className="flex-1 py-2 bg-gray-200 rounded">Revise</button>
</div>
</div>
</div>
);
}