# 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/berrypod_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/berrypod_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/berrypod_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/berrypod_web/cart_hook.ex`
2. `lib/berrypod_web/components/shop_components/layout.ex` (shop_layout + search_modal)
3. All 8 page templates in `lib/berrypod_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
