simpleshop_theme/docs/plans/search.md
jamey edcbc596e3 add LIKE substring fallback to search and update plan statuses
FTS5 prefix matching misses mid-word substrings (e.g. "ebook" in
"notebook"). When FTS5 returns zero results, fall back to LIKE
query on title and category with proper wildcard escaping. 4 new
tests, 757 total.

Also marks completed plan files (search, admin-redesign,
setup-wizard, products-context) with correct status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 09:09:10 +00:00

2.6 KiB

Plan: Implement product search in search modal

Status: Complete (037cd16, 57c3ba0)

Overview

The search modal UI shell exists but has zero functionality — no event bindings, no backend search, no results rendering. This plan adds live search across all products.

Approach

Small catalog (print-on-demand, < 100 products) — search PreviewData.products() in memory. No DB full-text search needed.

Product maps have: .name, .category, .description, .slug, .price, .image_url, .image_id

Changes

1. CartHook — add search assigns + event handler

File: lib/simpleshop_theme_web/cart_hook.ex

  • Init assigns in on_mount: search_results: [], search_query: ""
  • Handle "search" event (from phx-keyup):
    • Empty/blank query → assign search_results: [], search_query: ""
    • Non-empty → filter PreviewData.products() by name/category/description (case-insensitive substring match), take 6, assign results
  • Handle "close_search" event → clear query + results + hide modal via JS

2. shop_layout + search_modal — add search attrs and UI

File: lib/simpleshop_theme_web/components/shop_components/layout.ex

shop_layout:

  • Add optional attrs: search_results (default []), search_query (default "")
  • Pass them to <.search_modal>

search_modal:

  • Add search_results (list, default []) and search_query (string, default "") attrs
  • Add name="query", phx-keyup="search", phx-debounce="200", value={@search_query} to the input
  • On close button + backdrop click: also push "close_search" event
  • Results section below input:
    • Each result: link to /products/{slug} with product name, category, formatted price
    • "No results found" when query non-empty but no matches
    • Hint text only shown when no query
  • Click on result: navigate to product, close modal (JS.hide + close_search event)

3. Page templates — thread search assigns

All 8 files in lib/simpleshop_theme_web/components/page_templates/

Add two lines to each <.shop_layout> call:

search_results={assigns[:search_results] || []}
search_query={assigns[:search_query] || ""}

Same pattern as cart_drawer_open and cart_status.

Files to modify

  1. lib/simpleshop_theme_web/cart_hook.ex
  2. lib/simpleshop_theme_web/components/shop_components/layout.ex (shop_layout + search_modal)
  3. All 8 page templates in lib/simpleshop_theme_web/components/page_templates/

Verification

  • Browser: open search modal on multiple pages, type queries, verify results appear and link correctly
  • mix test — all existing tests pass