Workshop / src /components /workshop /ModelSlotCard.tsx
00000tt's picture
Overhaul Workshop: LoRA pipeline configurator dashboard + publish engine
8edd759
Raw
History Blame Contribute Delete
1.86 kB
import { Bot, ChevronDown, Cpu } from 'lucide-react'
import { useState } from 'react'
interface ModelSlotCardProps {
slotLabel: string
options: string[]
value: string
onChange: (v: string) => void
}
function ModelSlotCard({ slotLabel, options, value, onChange }: ModelSlotCardProps) {
const [open, setOpen] = useState(false)
return (
<div className="bg-[#191919] border border-[#2E2E2E] rounded-xl p-4 flex-1 min-w-[220px]">
<div className="flex items-center gap-2 text-[#8B8B8B] text-xs font-medium uppercase tracking-wide mb-3">
<Cpu size={14} />
{slotLabel}
</div>
<div className="relative">
<button
onClick={() => setOpen(!open)}
className="w-full flex items-center justify-between gap-2 bg-[#0F0F0F] border border-[#2E2E2E] rounded-lg px-3 py-2.5 text-left hover:border-[#FF9D00] transition-colors"
>
<span className="flex items-center gap-2 text-sm text-white truncate">
<Bot size={16} className="text-[#FF9D00] flex-shrink-0" />
{value}
</span>
<ChevronDown size={16} className={`text-[#8B8B8B] flex-shrink-0 transition-transform ${open ? 'rotate-180' : ''}`} />
</button>
{open && (
<div className="absolute z-10 top-full left-0 right-0 mt-1 bg-[#0F0F0F] border border-[#2E2E2E] rounded-lg overflow-hidden shadow-xl">
{options.map(opt => (
<button
key={opt}
onClick={() => { onChange(opt); setOpen(false) }}
className={`w-full text-left px-3 py-2 text-sm hover:bg-[#242424] transition-colors ${opt === value ? 'text-[#FF9D00]' : 'text-white'}`}
>
{opt}
</button>
))}
</div>
)}
</div>
</div>
)
}
export default ModelSlotCard