import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["overlay", "content", "queryInput", "vectorSearchToggle", "searchButton", "results"] static values = { searchUrl: String, resultsUrl: String } connect() { // Set default URLs if not provided if (!this.searchUrlValue) { this.searchUrlValue = "/search" } if (!this.resultsUrlValue) { this.resultsUrlValue = "/search" } // Add keyboard shortcuts this.boundKeydown = this.handleKeydown.bind(this) document.addEventListener('keydown', this.boundKeydown) } disconnect() { document.removeEventListener('keydown', this.boundKeydown) } open() { this.overlayTarget.classList.remove('hidden') this.queryInputTarget.focus() document.body.style.overflow = 'hidden' // Show suggestions when modal opens this.showSuggestions() } close() { this.overlayTarget.classList.add('hidden') this.queryInputTarget.value = '' this.resultsTarget.innerHTML = '' document.body.style.overflow = '' } async search(event) { event.preventDefault() const query = this.queryInputTarget.value.trim() if (!query) return const useVectorSearch = this.vectorSearchToggleTarget.checked const contentType = document.querySelector('input[name="content_type"]:checked')?.value || 'all' // Disable search button and show loading state this.searchButtonTarget.disabled = true this.searchButtonTarget.textContent = 'Searching...' try { // Build search parameters const params = new URLSearchParams({ search: query, page: 1 }) if (useVectorSearch) { params.append('use_vector_search', 'true') // For now, we'll use a placeholder embedding - in production this would come from a semantic embedding service const placeholderEmbedding = Array(1536).fill(0.1) // 1536-dimensional placeholder params.append('embedding', JSON.stringify(placeholderEmbedding)) } else { // Explicitly disable vector search params.append('use_vector_search', 'false') } // Add content type filter if (contentType && contentType !== 'all') { params.append('content_type', contentType) } // Make AJAX request to search endpoint const response = await fetch(`${this.searchUrlValue}?${params.toString()}`, { headers: { 'Accept': 'text/html', 'X-Requested-With': 'XMLHttpRequest' } }) if (response.ok) { const html = await response.text() this.resultsTarget.innerHTML = html // Show suggestions if no results const noResults = this.resultsTarget.querySelector('.text-center.text-gray-500') if (noResults) { this.showSuggestions() } else { this.hideSuggestions() } } else { const errorData = await response.json().catch(() => ({ error: `Search failed: ${response.status}` })) throw new Error(errorData.error || `Search failed: ${response.status}`) } } catch (error) { console.error('Search error:', error) this.resultsTarget.innerHTML = `
Search failed
Please try again later.