File size: 4,252 Bytes
5c98911 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 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>
);
}
|