// ======================================== // Skills Manager Page // ======================================== // Browse and manage skills library with search/filter import { useState, useMemo } from 'react'; import { useIntl } from 'react-intl'; import { Sparkles, Search, Plus, RefreshCw, Power, PowerOff, Tag, } from 'lucide-react'; import { Card } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@/components/ui/Select'; import { SkillCard } from '@/components/shared/SkillCard'; import { useSkills, useSkillMutations } from '@/hooks'; import type { Skill } from '@/lib/api'; import { cn } from '@/lib/utils'; // ========== Skill Grid Component ========== interface SkillGridProps { skills: Skill[]; isLoading: boolean; onToggle: (skill: Skill, enabled: boolean) => void; onClick: (skill: Skill) => void; isToggling: boolean; compact?: boolean; } function SkillGrid({ skills, isLoading, onToggle, onClick, isToggling, compact }: SkillGridProps) { const { formatMessage } = useIntl(); if (isLoading) { return (
{[1, 2, 3, 4, 5, 6].map((i) => (
))}
); } if (skills.length === 0) { return (

{formatMessage({ id: 'skills.emptyState.title' })}

{formatMessage({ id: 'skills.emptyState.message' })}

); } return (
{skills.map((skill) => ( ))}
); } // ========== Main Page Component ========== export function SkillsManagerPage() { const { formatMessage } = useIntl(); const [searchQuery, setSearchQuery] = useState(''); const [categoryFilter, setCategoryFilter] = useState('all'); const [sourceFilter, setSourceFilter] = useState('all'); const [enabledFilter, setEnabledFilter] = useState<'all' | 'enabled' | 'disabled'>('all'); const [viewMode, setViewMode] = useState<'grid' | 'compact'>('grid'); const { skills, categories, totalCount, enabledCount, isLoading, isFetching, refetch, } = useSkills({ filter: { search: searchQuery || undefined, category: categoryFilter !== 'all' ? categoryFilter : undefined, source: sourceFilter !== 'all' ? sourceFilter as Skill['source'] : undefined, enabledOnly: enabledFilter === 'enabled', }, }); const { toggleSkill, isToggling } = useSkillMutations(); // Filter skills based on enabled filter const filteredSkills = useMemo(() => { if (enabledFilter === 'disabled') { return skills.filter((s) => !s.enabled); } return skills; }, [skills, enabledFilter]); const handleToggle = async (skill: Skill, enabled: boolean) => { await toggleSkill(skill.name, enabled); }; return (
{/* Page Header */}

{formatMessage({ id: 'skills.title' })}

{formatMessage({ id: 'skills.description' })}

{/* Stats Cards */}
{totalCount}

{formatMessage({ id: 'common.stats.totalSkills' })}

{enabledCount}

{formatMessage({ id: 'skills.state.enabled' })}

{totalCount - enabledCount}

{formatMessage({ id: 'skills.state.disabled' })}

{categories.length}

{formatMessage({ id: 'skills.card.category' })}

{/* Filters and Search */}
setSearchQuery(e.target.value)} className="pl-9" />
{/* Quick Filters */}
{/* Skills Grid */} {}} isToggling={isToggling} compact={viewMode === 'compact'} />
); } export default SkillsManagerPage;