fix: Categories UI - click to view, not all expanded at once
This commit is contained in:
@@ -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">
|
||||||
|
<div className="flex flex-wrap gap-3">
|
||||||
{CATEGORIES.map((cat) => (
|
{CATEGORIES.map((cat) => (
|
||||||
<div key={cat.id} className="bg-slate-800 rounded-xl border border-slate-700 overflow-hidden">
|
|
||||||
<div className="p-4 border-b border-slate-700 bg-slate-700/50">
|
|
||||||
<h3 className="font-semibold text-lg">{cat.name}</h3>
|
|
||||||
<p className="text-sm text-slate-400">{categorySkills[cat.id]?.length || 0} skills</p>
|
|
||||||
</div>
|
|
||||||
<div className="max-h-48 overflow-y-auto">
|
|
||||||
{(categorySkills[cat.id] || []).map((skill) => {
|
|
||||||
const installed = isInstalled(skill.slug);
|
|
||||||
return (
|
|
||||||
<button
|
<button
|
||||||
key={skill.slug}
|
key={cat.id}
|
||||||
onClick={() => setSelectedSkill(skill)}
|
onClick={() => {
|
||||||
className={`w-full text-left p-3 border-b border-slate-700 hover:bg-slate-700 transition ${
|
setCategoryView(cat.id);
|
||||||
selectedSkill?.slug === skill.slug ? "bg-slate-700" : ""
|
setSkills(categorySkills[cat.id] || []);
|
||||||
} ${installed ? "border-l-4 border-l-green-500" : ""}`}
|
}}
|
||||||
|
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]"
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<span className="text-2xl">{cat.icon}</span>
|
||||||
<div>
|
<span className="font-medium text-white">{cat.name}</span>
|
||||||
<div className="font-medium text-white">{skill.name}</div>
|
<span className="text-xs text-slate-400">{categorySkills[cat.id]?.length || 0} skills</span>
|
||||||
<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>
|
</button>
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</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>
|
||||||
|
|||||||
Reference in New Issue
Block a user