import React, { useState, useEffect } from 'react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuSeparator, } from '@/components/ui/dropdown-menu' import { Bookmark, BookmarkPlus, Search, Filter, Trash2, Edit2, Star, Clock, Tag, FolderOpen } from 'lucide-react' import { AdvancedFilters } from '@/types' interface SearchPreset { id: string name: string description?: string query: string filters: AdvancedFilters category: string project: string sortBy: string sortOrder: 'asc' | 'desc' created: string lastUsed: string useCount: number icon: string } interface SearchPresetsProps { currentQuery: string currentFilters: AdvancedFilters currentCategory: string currentProject: string currentSortBy: string currentSortOrder: 'asc' | 'desc' onApplyPreset: (preset: SearchPreset) => void className?: string } export function SearchPresets({ currentQuery, currentFilters, currentCategory, currentProject, currentSortBy, currentSortOrder, onApplyPreset, className = '' }: SearchPresetsProps) { const [presets, setPresets] = useState([]) const [showSaveDialog, setShowSaveDialog] = useState(false) const [editingPreset, setEditingPreset] = useState(null) const [newPresetName, setNewPresetName] = useState('') const [newPresetDescription, setNewPresetDescription] = useState('') const [newPresetIcon, setNewPresetIcon] = useState('🔍') // Load presets from localStorage on mount useEffect(() => { const savedPresets = localStorage.getItem('search-presets') if (savedPresets) { try { const parsed = JSON.parse(savedPresets) setPresets(parsed) } catch (error) { console.error('Failed to load search presets:', error) } } else { // Create default presets const defaultPresets: SearchPreset[] = [ { id: 'recent-code', name: 'Recent Code', description: 'Recent code-related memories', query: '', filters: { hasCode: true }, category: 'code', project: 'all', sortBy: 'timestamp', sortOrder: 'desc', created: new Date().toISOString(), lastUsed: new Date().toISOString(), useCount: 0, icon: '💻' }, { id: 'work-meetings', name: 'Work Meetings', description: 'Work-related meetings and discussions', query: 'meeting', filters: {}, category: 'work', project: 'all', sortBy: 'timestamp', sortOrder: 'desc', created: new Date().toISOString(), lastUsed: new Date().toISOString(), useCount: 0, icon: '💼' }, { id: 'high-priority', name: 'High Priority', description: 'High priority memories and tasks', query: '', filters: { priority: 'high' }, category: 'all', project: 'all', sortBy: 'priority', sortOrder: 'desc', created: new Date().toISOString(), lastUsed: new Date().toISOString(), useCount: 0, icon: '⚡' }, { id: 'personal-notes', name: 'Personal Notes', description: 'Personal thoughts and notes', query: '', filters: {}, category: 'personal', project: 'all', sortBy: 'timestamp', sortOrder: 'desc', created: new Date().toISOString(), lastUsed: new Date().toISOString(), useCount: 0, icon: '📝' } ] setPresets(defaultPresets) localStorage.setItem('search-presets', JSON.stringify(defaultPresets)) } }, []) // Save presets to localStorage whenever they change useEffect(() => { if (presets.length > 0) { localStorage.setItem('search-presets', JSON.stringify(presets)) } }, [presets]) const saveCurrentAsPreset = () => { if (!newPresetName.trim()) return const newPreset: SearchPreset = { id: Date.now().toString(), name: newPresetName.trim(), description: newPresetDescription.trim() || undefined, query: currentQuery, filters: currentFilters, category: currentCategory, project: currentProject, sortBy: currentSortBy, sortOrder: currentSortOrder, created: new Date().toISOString(), lastUsed: new Date().toISOString(), useCount: 0, icon: newPresetIcon } setPresets(prev => [...prev, newPreset]) setNewPresetName('') setNewPresetDescription('') setNewPresetIcon('🔍') setShowSaveDialog(false) } const updatePreset = () => { if (!editingPreset || !newPresetName.trim()) return const updatedPreset = { ...editingPreset, name: newPresetName.trim(), description: newPresetDescription.trim() || undefined, icon: newPresetIcon } setPresets(prev => prev.map(p => p.id === editingPreset.id ? updatedPreset : p)) setEditingPreset(null) setNewPresetName('') setNewPresetDescription('') setNewPresetIcon('🔍') setShowSaveDialog(false) } const deletePreset = (presetId: string) => { if (confirm('Are you sure you want to delete this preset?')) { setPresets(prev => prev.filter(p => p.id !== presetId)) } } const applyPreset = (preset: SearchPreset) => { // Update usage stats const updatedPreset = { ...preset, lastUsed: new Date().toISOString(), useCount: preset.useCount + 1 } setPresets(prev => prev.map(p => p.id === preset.id ? updatedPreset : p)) onApplyPreset(updatedPreset) } const startEdit = (preset: SearchPreset) => { setEditingPreset(preset) setNewPresetName(preset.name) setNewPresetDescription(preset.description || '') setNewPresetIcon(preset.icon) setShowSaveDialog(true) } const getPresetSummary = (preset: SearchPreset): string => { const parts: string[] = [] if (preset.query) parts.push(`"${preset.query}"`) if (preset.category !== 'all') parts.push(`${preset.category}`) if (preset.project !== 'all') parts.push(`📁 ${preset.project}`) if (Object.keys(preset.filters).length > 0) { parts.push(`${Object.keys(preset.filters).length} filter(s)`) } return parts.length > 0 ? parts.join(' • ') : 'No filters' } const getMostUsedPresets = () => { return [...presets] .sort((a, b) => b.useCount - a.useCount) .slice(0, 3) } const getRecentPresets = () => { return [...presets] .sort((a, b) => new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime()) .slice(0, 3) } const commonIcons = ['🔍', '💻', '💼', '📝', '📊', '⚡', '🎯', '📚', '💬', '🏷️', '📁', '⭐'] return (
{/* Quick Access to Most Used Presets */} {getMostUsedPresets().slice(0, 2).map((preset) => ( ))} {/* Main Presets Dropdown */} {/* Most Used Section */}
Most Used
{getMostUsedPresets().map((preset) => ( applyPreset(preset)} className="flex items-center justify-between p-2 cursor-pointer hover:bg-gray-700" >
{preset.icon}
{preset.name}
{getPresetSummary(preset)}
{preset.useCount}
))}
{/* Recent Section */}
Recently Used
{getRecentPresets().map((preset) => ( applyPreset(preset)} className="flex items-center justify-between p-2 cursor-pointer hover:bg-gray-700" >
{preset.icon}
{preset.name}
{getPresetSummary(preset)}
{new Date(preset.lastUsed).toLocaleDateString()}
))}
{/* Save Current Search */} setShowSaveDialog(true)} className="p-2 cursor-pointer hover:bg-gray-700"> Save Current Search
{/* Save/Edit Preset Dialog */} {editingPreset ? 'Edit Preset' : 'Save Search Preset'}
setNewPresetName(e.target.value)} placeholder="My Saved Search" className="bg-gray-700 border-gray-600 text-white" />
setNewPresetDescription(e.target.value)} placeholder="Brief description of this search..." className="bg-gray-700 border-gray-600 text-white" />
{commonIcons.map((icon) => ( ))}
{!editingPreset && (
Current Search Settings:
{currentQuery &&
Query: "{currentQuery}"
} {currentCategory !== 'all' &&
Category: {currentCategory}
} {currentProject !== 'all' &&
Project: {currentProject}
} {Object.keys(currentFilters).length > 0 && (
Filters: {Object.keys(currentFilters).length} active
)}
Sort: {currentSortBy} ({currentSortOrder})
)}
) }