'use client'; import * as React from 'react'; import Fuse from 'fuse.js'; import { Search } from 'lucide-react'; import { cn } from '@/lib/utils/cn'; import { Input } from '@/components/ui/Input'; import { Card } from '@/components/ui/Card'; import type { ConversionFormat } from '@/types/conversion'; export interface FormatSelectorProps { formats: ConversionFormat[]; selectedFormat?: ConversionFormat; onFormatSelect: (format: ConversionFormat) => void; label?: string; disabled?: boolean; } export function FormatSelector({ formats, selectedFormat, onFormatSelect, label = 'Select format', disabled = false, }: FormatSelectorProps) { const [searchQuery, setSearchQuery] = React.useState(''); const [filteredFormats, setFilteredFormats] = React.useState(formats); // Set up Fuse.js for fuzzy search const fuse = React.useMemo(() => { return new Fuse(formats, { keys: ['name', 'extension', 'description'], threshold: 0.3, includeScore: true, }); }, [formats]); // Filter formats based on search query React.useEffect(() => { if (!searchQuery.trim()) { setFilteredFormats(formats); return; } const results = fuse.search(searchQuery); setFilteredFormats(results.map((result) => result.item)); }, [searchQuery, formats, fuse]); // Group formats by category const groupedFormats = React.useMemo(() => { const groups: Record = {}; filteredFormats.forEach((format) => { if (!groups[format.category]) { groups[format.category] = []; } groups[format.category].push(format); }); return groups; }, [filteredFormats]); return (
{/* Search input */}
setSearchQuery(e.target.value)} disabled={disabled} className="pl-10" />
{/* Format list */} {Object.entries(groupedFormats).length === 0 ? (
No formats found matching "{searchQuery}"
) : (
{Object.entries(groupedFormats).map(([category, categoryFormats]) => (

{category}

{categoryFormats.map((format) => ( ))}
))}
)}
{/* Selected format display */} {selectedFormat && (
Selected: {selectedFormat.name} (. {selectedFormat.extension})
)}
); }