Adds SQLite FTS5 search index with BM25 ranking across product title, category, variant attributes, and description. Search modal now has live results with thumbnails, prices, and click-to-navigate. Index rebuilds automatically after each provider sync. Also fixes Access syntax on Product/ProductImage structs (Map.get instead of bracket notation) which was causing crashes when real products were loaded from the database. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
50 lines
1.2 KiB
Elixir
50 lines
1.2 KiB
Elixir
defmodule SimpleshopThemeWeb.SearchHook do
|
|
@moduledoc """
|
|
LiveView on_mount hook for product search.
|
|
|
|
Mounted in the public_shop live_session to give all shop LiveViews
|
|
search state and shared event handlers via attach_hook.
|
|
|
|
Handles these events:
|
|
- `search` - run FTS5 search with debounced query
|
|
- `clear_search` - reset search state
|
|
"""
|
|
|
|
import Phoenix.Component, only: [assign: 3]
|
|
import Phoenix.LiveView, only: [attach_hook: 4]
|
|
|
|
alias SimpleshopTheme.Search
|
|
|
|
def on_mount(:mount_search, _params, _session, socket) do
|
|
socket =
|
|
socket
|
|
|> assign(:search_query, "")
|
|
|> assign(:search_results, [])
|
|
|> attach_hook(:search_events, :handle_event, &handle_search_event/3)
|
|
|
|
{:cont, socket}
|
|
end
|
|
|
|
defp handle_search_event("search", %{"value" => query}, socket) do
|
|
results = Search.search(query)
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:search_query, query)
|
|
|> assign(:search_results, results)
|
|
|
|
{:halt, socket}
|
|
end
|
|
|
|
defp handle_search_event("clear_search", _params, socket) do
|
|
socket =
|
|
socket
|
|
|> assign(:search_query, "")
|
|
|> assign(:search_results, [])
|
|
|
|
{:halt, socket}
|
|
end
|
|
|
|
defp handle_search_event(_event, _params, socket), do: {:cont, socket}
|
|
end
|