Add Search Functionality to Existing App
Implement a real, persistent search feature across the app’s primary data list.
The route
6 steps to Done
- 01
Inspect Existing Data Model and API
Identify where the target data lives and how it is currently fetched.
Preview prompt + verify gate ▾ Hide ▴
1. Open the main repository and locate the file that defines the item data model (e.g., Item.js, schema.sql, or a TypeScript interface). 2. List all fields, their types, and any indexes. 3. Find the client‑side code that retrieves the list (e.g., a fetch call or Axios request). 4. Copy the full URL, request method, headers, and response handling logic. 5. Ensure the snippet includes error handling and state update. 6. Provide a short comment explaining how the data currently populates the UI list.
- ✓ Can you see the full list of fields for the item model?
- ✓ Does the fetch snippet contain the exact URL used in the app?
- 02
Create a Search API Endpoint
Add server‑side logic to filter items based on a query string.
Preview prompt + verify gate ▾ Hide ▴
1. In the Express router file (e.g., routes/items.js), add a new route handler for GET /items/search. 2. Extract the query parameter ?q and sanitize it. 3. Use a parameterized SQL query against the items table to match the name or description fields using ILIKE '%q%'. 4. Return a JSON array of matching items with the same shape as the original /items endpoint. 5. Include proper error handling: return 400 for missing q, 500 for DB errors, and set appropriate Content‑Type header. 6. Update the server export so the new route is registered. 7. Write a brief comment explaining the purpose of the endpoint.
- ✓ Does the new route exist in routes/items.js?
- ✓ Does the handler use a parameterized query against the actual items table?
- 03
Add Search Bar UI Component
Provide a visible input for users to type search queries.
Preview prompt + verify gate ▾ Hide ▴
1. In src/components/, create a new file SearchBar.jsx (or .tsx). 2. Implement a functional component that renders: a text input bound to internal state `query`, and a button labeled 'Search'. 3. Style the input and button using existing Tailwind classes from the app for consistency. 4. Export the component as default. 5. Add PropTypes or TypeScript interface that accepts an onSearch callback prop `(query: string) => void`. 6. Ensure the component does not contain any placeholder text like 'Enter search…' unless that exact placeholder already exists elsewhere in the UI. 7. Write a short comment describing the component’s purpose.
- ✓ Is the component file present in src/components?
- ✓ Does the component accept an onSearch callback prop and update state on input change?
- 04
Integrate Search Bar with Backend Endpoint
Connect the UI to the new /items/search API and display results.
Preview prompt + verify gate ▾ Hide ▴
1. Open src/pages/ItemList.jsx. 2. Import the SearchBar component. 3. Add a state variable `items` (array) and a function `fetchItems(query?)`. 4. If query is undefined, fetch GET /items; if defined, fetch GET /items/search?q=query. 5. Use async/await with proper error handling; update `items` state with the JSON response. 6. Pass a callback to SearchBar as onSearch that calls `fetchItems` with the entered query. 7. Replace the existing static list rendering with a map over `items`. 8. Ensure the UI updates instantly after a search and that the previous list can be restored when the query is cleared. 9. Add a comment describing the new data flow.
- ✓ Does the page import and render SearchBar?
- ✓ When a query is entered, does the network request go to /items/search and update the list?
- 05
Persist Recent Searches Locally
Remember the last three search terms across page reloads.
Preview prompt + verify gate ▾ Hide ▴
1. In SearchBar.jsx, after a successful search, push the query string into a `recentSearches` array stored in localStorage under the key 'recentSearches'. 2. Limit the array to the latest three entries, discarding older ones. 3. On component mount, read the stored array and initialize a state variable `recent`. 4. Render a simple dropdown below the input that lists the recent queries; clicking a dropdown item should invoke onSearch with that term. 5. Ensure all localStorage reads/writes use JSON.stringify/parse and include try/catch for safety. 6. Add comments explaining the persistence logic.
- ✓ After performing a search, does localStorage contain a 'recentSearches' key with the term?
- ✓ Do the recent terms appear in the dropdown and trigger a new search when clicked?
- 06
End‑to‑End Verification and Documentation
Confirm the search works, persists, and document the changes.
Preview prompt + verify gate ▾ Hide ▴
1. Start the development server and open the app in a browser. 2. Verify the SearchBar renders with styling matching the rest of the UI. 3. Type a term that matches known items; press Search. 4. Observe the network tab shows a GET request to /items/search?q=... with a 200 response and correct JSON payload. 5. Confirm the displayed list updates to show only matching items. 6. Refresh the page, open the dropdown, click a recent term, and verify the same process repeats without loss of data. 7. Open the project README and append a bullet under “Changes” summarizing: added /items/search endpoint, new SearchBar component, UI‑backend integration, recent-search persistence. 8. Commit the changes with a clear message. 9. Provide a short PASS/FAIL statement: PASS if all manual checks succeeded, otherwise FAIL with the failing step.
- ✓ Does a real GET /items/search request fire and return correct data?
- ✓ Do recent searches survive a page reload and trigger searches from the dropdown?