---
estimated_steps: 8
estimated_files: 6
skills_used: []
---

# T02: SortDropdown component, session persistence hook, and integration into 3 pages

1. Create a shared `SortDropdown` component: accepts `options: {value, label}[]`, `value`, `onChange`, `className`. Renders a `<select>` styled consistently with the app's dark theme. Shows the active sort visually.
2. Create a `useSortPreference(defaultSort: string)` hook that reads/writes to `sessionStorage` key `chrysopedia_sort_pref`. Returns `[sort, setSort]`. When setSort is called, it persists to sessionStorage.
3. Add SortDropdown to SearchResults.tsx: options include 'relevance' (default when query active), 'newest', 'oldest', 'alpha', 'creator'. Pass sort param to searchApi().
4. Add SortDropdown to SubTopicPage.tsx: options 'alpha' (default), 'newest', 'oldest', 'creator'. Pass sort to fetchSubTopicTechniques().
5. Add SortDropdown to CreatorDetail.tsx: options 'newest' (default), 'oldest', 'alpha'. Pass sort to fetchTechniques().
6. Update public-client.ts: add `sort` param to `searchApi()`, add `sort` param to `fetchSubTopicTechniques()`.
7. Changing sort resets offset/page to 0 but preserves query and filters.
8. Add CSS for the sort dropdown matching the dark theme.

## Inputs

- `frontend/src/pages/SearchResults.tsx`
- `frontend/src/pages/SubTopicPage.tsx`
- `frontend/src/pages/CreatorDetail.tsx`
- `frontend/src/api/public-client.ts`
- `frontend/src/pages/CreatorsBrowse.tsx`

## Expected Output

- `frontend/src/components/SortDropdown.tsx`
- `frontend/src/hooks/useSortPreference.ts`
- `frontend/src/pages/SearchResults.tsx (with sort)`
- `frontend/src/pages/SubTopicPage.tsx (with sort)`
- `frontend/src/pages/CreatorDetail.tsx (with sort)`
- `frontend/src/api/public-client.ts (sort params)`

## Verification

Browser verification: all 3 pages show sort dropdown, changing sort updates results, navigating away and back preserves sort preference.
