Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

05 — Screen Inventory (Search Module)

Every screen of the Search module, its intent, route, composition, states, permissions, platform behavior and events. Authoritative components in 00-shared/03; this file enumerates which ones each screen uses with module specifics. Backend source: src/modules/search/**.


Legend

States = idle / loading / success / empty / error(offline, server, invalid) / disabled / permission. Analytics events follow {module}.{screen}.{action} (proposed; SDK open — 00-shared/10 §8).


1. Global Search Bar (in-shell control, every authenticated screen)

FieldDetail
PurposeCapture the query that drives the single search endpoint
Entrypresent on all shell screens; focused state → /search
Exitsubmit → /search?q=…; cancel → back to previous screen
InputAppTextField-based SearchBarField (module component, 07 §1): hint "Search students, books, announcements…", clear button, optional scan icon (forward-looking)
Behaviordebounced 300 ms (proposed); results update in place while typing; submit commits exact query
Permissionsearch (permissions.constants.ts:93); without it the bar is hidden
Statesidle, typing (IME composing), loading (inline spinner, no layout jump), disabled (permission), offline (banner)
KeyboardTextInputType.text, textInputAction.search, autocorrect off (names/IDs)
a11ysemantics hint "Search the whole school"; clear button labeled; live-region on result count
Analyticssearch.bar.focus, search.bar.submit, search.bar.clear (proposed)
Motionfocus underline m-fast; results fade/slide m-base (00-shared/08)

2. Search Results Screen (/search) — the module's only full screen

FieldDetail
PurposeShow relevance-ranked results grouped by entity type; jump to any entity
Entryfrom search bar submit; deep link ?q= (forward-looking)
Exittap result → owner module detail route; back → shell
SourceGET /api/v1/search?q&entityType&page&limit — flat SearchResult[] + PaginationMeta (search.service.ts:10-16,59)
Groupsclient-side grouping by entityType (search.service.ts:11); group headers with counts (count = rows on page, not total — see QA-14)
LoadingAppSkeleton list; keep previous results + dim while typing new query (avoid flicker)
EmptyAppEmptyState "No results for “q”" + clear CTA (server returns data: []search.service.ts:28-30)
ErrorAppErrorState with retry; note: server auto-falls back to regex internally (search.service.ts:35-41), so client errors are rare
Paginationinfinite scroll (page+1 on scroll end); meta.hasNext gate (pagination-query.dto.ts:41-55)
Pull-to-refreshRefreshIndicator re-runs current query (fresh index read)
a11ygroup headers as headings; per-row semantics label "{title}, {entityType}, {description}"
Motiongroup insert/remove m-base; row tap ripple
Analyticssearch.results.shown(count,type), search.result.tap(entityType), search.results.empty, search.seeall.tap(type) (proposed)

3. See-All Drill-Down (/search?type=<entityType>)

FieldDetail
PurposeBrowse all matches of one entity type with pagination
Sourcesame endpoint, entityType set (search-query.dto.ts:11-14)
Groupingno groups — flat list of one type; app bar shows type label + result count
Empty"No {type} found for “q”"
Caveatserver filters the fetched page only (search.service.ts:44-49) — drill-down paging stays correct per page, but cross-page type totals are approximations; QA-14
Exitback → /search (query preserved in cubit state)

4. Zero-State / Landing (/search with empty query)

FieldDetail
PurposeExplain the surface before any query
Sourcenone — client-only; server returns data: [] for blank q (search.service.ts:28-30)
Contenticon, "Search across your school", example chips ("Student name", "Admission no.", "Book title", "Announcement") — tap chip fills bar
Statesonly idle + offline
Analyticssearch.landing.chip.tap(topic) (proposed)

5. Recent Searches panel (forward-looking)

FieldDetail
PurposeQuick re-run of past queries (client-side persistence only — ledger B5)
Sourcenone — device storage; no backend history endpoint
Notekeep dormant; single-tap re-run; clear-all action

6. Scan-to-Search sheet (forward-looking)

QR/barcode capture filling q — no backend QR support (ledger B4); see 03 J8.


Shared components used

AppTextField, AppButton, AppChips, AppAvatar, AppListTile, AppSnackbar, AppSkeleton, AppEmptyState, AppErrorState, AppOfflineBanner, AppSpinner, AppTag. Module-specific: SearchBarField, SearchResultTile, SearchGroupHeader, SearchResultSkeleton — defined in 07_Component_Library.md.

Analytics events (proposed)

search.bar.{focus,submit,clear}, search.landing.chip.tap, search.results.{shown,tap,empty,seeall}, search.error.{server,offline} (all proposed).

Keyboard, landscape, tablet, desktop

  • Portrait: bar top, results scroll below.
  • Tablet/desktop: results in two-column grid groups; keyboard shortcuts / focuses search (desktop), Esc clears.
  • Keyboard avoidance + resizeToAvoidBottomInset (shared baseline).