diff --git a/src/components/swarm/archetype-picker.tsx b/src/components/swarm/archetype-picker.tsx new file mode 100644 index 0000000..8d95bd5 --- /dev/null +++ b/src/components/swarm/archetype-picker.tsx @@ -0,0 +1,131 @@ +"use client"; + +import React from 'react'; +import { X, Blocks, Check, Pencil, Plus } from 'lucide-react'; +import type { AgentArchetype } from '../../lib/types-swarm'; +import { getArchetypeDisplayChar } from '../../lib/utils'; + +interface ArchetypePickerProps { + archetypes: AgentArchetype[]; + isOpen: boolean; + onClose: () => void; + onSelect: (archetype: AgentArchetype) => void; + onEdit: (archetypeId: string) => void; + onCreateNew: () => void; +} + +export function ArchetypePicker({ + archetypes, + isOpen, + onClose, + onSelect, + onEdit, + onCreateNew +}: ArchetypePickerProps) { + if (!isOpen) return null; + + const handleBackdropClick = (e: React.MouseEvent) => { + if (e.target === e.currentTarget) { + onClose(); + } + }; + + const handleSelect = (archetype: AgentArchetype) => { + onSelect(archetype); + onClose(); + }; + + return ( +
+
+
+
+ +

+ Select Archetype +

+
+ +
+ +
+ {archetypes.length === 0 ? ( +
+ +

No archetypes available

+

Create one to get started

+
+ ) : ( +
+ {archetypes.map((archetype) => { + const displayChar = getArchetypeDisplayChar(archetype); + return ( +
+
+
+ {displayChar} +
+
+

+ {archetype.name} +

+

+ {archetype.description || 'No description'} +

+
+
+ +
+ + +
+
+ ); + })} +
+ )} +
+ +
+ +
+
+
+ ); +} diff --git a/src/components/swarm/template-picker.tsx b/src/components/swarm/template-picker.tsx new file mode 100644 index 0000000..1c736d0 --- /dev/null +++ b/src/components/swarm/template-picker.tsx @@ -0,0 +1,153 @@ +"use client"; + +import React from 'react'; +import { X, Check, Pencil, Plus, Users } from 'lucide-react'; +import type { SwarmTemplate } from '../../lib/types-swarm'; +import { getTemplateDisplayChar, getTemplateColor } from '../../lib/utils'; + +interface TemplatePickerProps { + templates: SwarmTemplate[]; + isOpen: boolean; + onClose: () => void; + onSelect: (template: SwarmTemplate) => void; + onEdit: (templateId: string) => void; + onCreateNew: () => void; +} + +export function TemplatePicker({ + templates, + isOpen, + onClose, + onSelect, + onEdit, + onCreateNew +}: TemplatePickerProps) { + if (!isOpen) return null; + + const handleBackdropClick = (e: React.MouseEvent) => { + if (e.target === e.currentTarget) { + onClose(); + } + }; + + const handleSelect = (template: SwarmTemplate) => { + onSelect(template); + onClose(); + }; + + const handleEdit = (e: React.MouseEvent, templateId: string) => { + e.stopPropagation(); + onEdit(templateId); + }; + + const getTotalTeamSize = (template: SwarmTemplate): number => { + return template.team.reduce((acc, member) => acc + member.count, 0); + }; + + return ( +
+
+ +
+

+ Select Template +

+ +
+ +
+ {templates.length === 0 ? ( +
+

No templates available

+

Create a template to get started

+
+ ) : ( +
+ {templates.map((template) => { + const displayChar = getTemplateDisplayChar(template); + const color = getTemplateColor(template); + const teamSize = getTotalTeamSize(template); + + return ( +
handleSelect(template)} + > +
+
+ {displayChar} +
+
+

+ {template.name} +

+ {template.isBuiltIn && ( + + Built-in + + )} +
+
+ +

+ {template.description} +

+ +
+ + {teamSize} agent{teamSize !== 1 ? 's' : ''} +
+ +
+ + +
+
+ ); + })} +
+ )} +
+ +
+ +
+ +
+
+ ); +}