fix: Categories UI - click to view, not all expanded at once

This commit is contained in:
2026-03-24 18:45:53 +01:00
parent 2ee9b22cec
commit 28c6682f11
+37 -37
View File
@@ -48,6 +48,7 @@ export default function ClawHubMarketplace() {
const [skillDetails, setSkillDetails] = useState<{description?: string; triggers?: string} | null>(null); const [skillDetails, setSkillDetails] = useState<{description?: string; triggers?: string} | null>(null);
const [selectedAgents, setSelectedAgents] = useState<string[]>(["horus"]); const [selectedAgents, setSelectedAgents] = useState<string[]>(["horus"]);
const [view, setView] = useState<"popular" | "categories" | "search">("popular"); const [view, setView] = useState<"popular" | "categories" | "search">("popular");
const [categoryView, setCategoryView] = useState<string | null>(null);
const [action, setAction] = useState<"install" | "delete" | "sync" | "push" | null>(null); const [action, setAction] = useState<"install" | "delete" | "sync" | "push" | null>(null);
const [output, setOutput] = useState(""); const [output, setOutput] = useState("");
const [installedSkills, setInstalledSkills] = useState<Record<string, string[]>>({}); const [installedSkills, setInstalledSkills] = useState<Record<string, string[]>>({});
@@ -359,51 +360,50 @@ export default function ClawHubMarketplace() {
</div> </div>
{/* Categories View */} {/* Categories View */}
{view === "categories" && ( {view === "categories" && !categoryView && (
<div className="space-y-6"> <div className="mb-6">
{CATEGORIES.map((cat) => ( <div className="flex flex-wrap gap-3">
<div key={cat.id} className="bg-slate-800 rounded-xl border border-slate-700 overflow-hidden"> {CATEGORIES.map((cat) => (
<div className="p-4 border-b border-slate-700 bg-slate-700/50"> <button
<h3 className="font-semibold text-lg">{cat.name}</h3> key={cat.id}
<p className="text-sm text-slate-400">{categorySkills[cat.id]?.length || 0} skills</p> onClick={() => {
</div> setCategoryView(cat.id);
<div className="max-h-48 overflow-y-auto"> setSkills(categorySkills[cat.id] || []);
{(categorySkills[cat.id] || []).map((skill) => { }}
const installed = isInstalled(skill.slug); className="bg-slate-800 hover:bg-slate-700 border border-slate-700 hover:border-slate-600 rounded-xl px-6 py-4 flex flex-col items-center gap-2 transition min-w-[140px]"
return ( >
<button <span className="text-2xl">{cat.icon}</span>
key={skill.slug} <span className="font-medium text-white">{cat.name}</span>
onClick={() => setSelectedSkill(skill)} <span className="text-xs text-slate-400">{categorySkills[cat.id]?.length || 0} skills</span>
className={`w-full text-left p-3 border-b border-slate-700 hover:bg-slate-700 transition ${ </button>
selectedSkill?.slug === skill.slug ? "bg-slate-700" : "" ))}
} ${installed ? "border-l-4 border-l-green-500" : ""}`} </div>
>
<div className="flex items-center justify-between">
<div>
<div className="font-medium text-white">{skill.name}</div>
<div className="text-xs text-slate-400">@{skill.slug}</div>
</div>
<span className="text-xs bg-slate-600 px-2 py-0.5 rounded">
{skill.score?.toFixed(2)}
</span>
</div>
</button>
);
})}
</div>
</div>
))}
</div> </div>
)} )}
{/* Popular/Search View */} {view === "categories" && categoryView && (
{(view === "popular" || view === "search") && ( <div className="mb-4">
<button
onClick={() => setCategoryView(null)}
className="text-slate-400 hover:text-white flex items-center gap-2 mb-4"
>
Back to Categories
</button>
<div className="flex items-center gap-3">
<span className="text-2xl">{CATEGORIES.find(c => c.id === categoryView)?.icon}</span>
<h2 className="text-xl font-bold">{CATEGORIES.find(c => c.id === categoryView)?.name}</h2>
</div>
</div>
)}
{/* Popular/Search/Category View */}
{(view === "popular" || view === "search" || (view === "categories" && categoryView)) && (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Skills List */} {/* Skills List */}
<div className="bg-slate-800 rounded-xl border border-slate-700 overflow-hidden"> <div className="bg-slate-800 rounded-xl border border-slate-700 overflow-hidden">
<div className="p-4 border-b border-slate-700 bg-slate-800"> <div className="p-4 border-b border-slate-700 bg-slate-800">
<h2 className="font-semibold text-lg"> <h2 className="font-semibold text-lg">
{view === "popular" ? "🔥 Popular Skills" : "Search Results"} {view === "popular" ? "🔥 Popular Skills" : view === "categories" ? CATEGORIES.find(c => c.id === categoryView)?.name || "Category" : "Search Results"}
</h2> </h2>
<p className="text-sm text-slate-400">{skills.length} skills found</p> <p className="text-sm text-slate-400">{skills.length} skills found</p>
</div> </div>