import { useMemo } from 'react'; import Fuse from 'fuse.js'; import { Skill } from '@/types/skills'; export interface SearchOptions { query: string; category?: string; skills: Skill[]; } export function useSearch({ query, category, skills }: SearchOptions) { const fuse = useMemo(() => { return new Fuse(skills, { keys: [ { name: 'name', weight: 0.4 }, { name: 'description', weight: 0.3 }, { name: 'keywords', weight: 0.2 }, { name: 'category', weight: 0.1 }, ], threshold: 0.3, includeScore: true, minMatchCharLength: 2, }); }, [skills]); const filteredSkills = useMemo(() => { let results = skills; // Apply category filter first if (category && category !== 'all') { results = results.filter(skill => skill.category.toLowerCase() === category.toLowerCase() ); } // Apply search query if (query.trim()) { const fuseResults = fuse.search(query); const fuseMatchedIds = new Set(fuseResults.map(r => r.item.id)); // Sort results by relevance (fuse score) while maintaining category filter results = results.filter(skill => fuseMatchedIds.has(skill.id)); results.sort((a, b) => { const aScore = fuseResults.find(r => r.item.id === a.id)?.score ?? 1; const bScore = fuseResults.find(r => r.item.id === b.id)?.score ?? 1; return aScore - bScore; }); } return results; }, [query, category, skills, fuse]); return { skills: filteredSkills, total: filteredSkills.length, hasQuery: !!query.trim(), }; }