CarboAny / src /components /agents /DelegateTaskModal.tsx
Esketch's picture
deploy: [P4] Strangler Pattern API Adapter Release (Orphan Clean Build v2)
daaf9d7
Raw
History Blame Contribute Delete
4.25 kB
import { useState } from 'react';
import type { HarnessAgent } from '../../types';
interface DelegateTaskModalProps {
agents: HarnessAgent[];
onClose: () => void;
onDelegate: (agentId: string, title: string, description: string) => void;
}
export default function DelegateTaskModal({
agents,
onClose,
onDelegate,
}: DelegateTaskModalProps) {
const [agentId, setAgentId] = useState(agents[0]?.id ?? '');
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!title.trim()) return;
onDelegate(agentId, title.trim(), description.trim());
};
return (
<div className="fixed inset-0 z-50 flex items-center justify-center">
<div
className="absolute inset-0 bg-ink-black/20 z-0"
onClick={onClose}
onKeyDown={(e) => { if (e.key === 'Escape') onClose(); }}
role="button"
tabIndex={-1}
aria-label="Close modal"
/>
<div className="relative z-10 bg-paper-white border border-border-default w-full max-w-lg mx-4 rounded-xl shadow-lg overflow-hidden">
<div className="px-6 py-4 border-b border-border-default">
<h3 className="text-base font-bold text-ink-black">
μ—μ΄μ „νŠΈμ— νƒœμŠ€ν¬ μœ„μž„
</h3>
</div>
<form onSubmit={handleSubmit} className="p-6 space-y-5">
<div>
<label
htmlFor="agent-select"
className="block text-xs font-semibold text-ink-dark mb-1.5"
>
λŒ€μƒ μ—μ΄μ „νŠΈ
</label>
<select
id="agent-select"
value={agentId}
onChange={(e) => setAgentId(e.target.value)}
className="w-full border border-border-default bg-paper-white px-3 py-2 text-sm text-ink-black focus:outline-none focus:border-accent-teal"
>
{agents.map((a) => (
<option key={a.id} value={a.id}>
{a.name}
</option>
))}
</select>
</div>
<div>
<label
htmlFor="task-title"
className="block text-xs font-semibold text-ink-dark mb-1.5"
>
νƒœμŠ€ν¬ 제λͺ©
</label>
<input
id="task-title"
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="예: (μ£Ό)κ·Έλ¦°μ—λ„ˆμ§€ 2026-Q2 데이터 검증"
className="w-full border border-border-default bg-paper-white px-3 py-2 text-sm text-ink-black placeholder:text-ink-light focus:outline-none focus:border-accent-teal"
/>
</div>
<div>
<label
htmlFor="task-desc"
className="block text-xs font-semibold text-ink-dark mb-1.5"
>
상세 μ„€λͺ… (선택)
</label>
<textarea
id="task-desc"
value={description}
onChange={(e) => setDescription(e.target.value)}
rows={3}
placeholder="μ—μ΄μ „νŠΈμ—κ²Œ 전달할 μΆ”κ°€ 지침을 μž…λ ₯ν•˜μ„Έμš”."
className="w-full border border-border-default bg-paper-white px-3 py-2 text-sm text-ink-black placeholder:text-ink-light focus:outline-none focus:border-accent-teal resize-none"
/>
</div>
<div className="flex justify-end gap-3 pt-2">
<button
type="button"
onClick={onClose}
className="px-4 py-2 text-sm text-ink-medium border border-border-default rounded-md hover:border-border-strong transition-colors"
>
μ·¨μ†Œ
</button>
<button
type="submit"
disabled={!title.trim()}
className="px-4 py-2 text-sm font-semibold text-white bg-accent-teal hover:bg-accent-teal/90 rounded-md disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
>
μœ„μž„ν•˜κΈ°
</button>
</div>
</form>
</div>
</div>
);
}