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 (Rooms Module)

Every screen of the Rooms 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.


Legend

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


1. Room List Screen (/rooms)

FieldDetail
PurposeBrowse, filter, and enter the tenant's room catalog
Entryadmin workspace nav, deep link /rooms
Exittap row → /rooms/:id; FAB → /rooms/new; filter sheet toggle
SourceGET /api/v1/rooms?page&limit (rooms.controller.ts:30-34) — pagination only; no sort/filter/q (OQ-3, rooms.controller.ts:32)
WidgetsAppAppBar "Rooms" + count badge; AppSearchBar (proposed) (client-side filter until API lands); AppChips type/building filters (proposed); RoomCard list (ListView.builder); AppEmptyState; AppSkeleton; AppOfflineBanner; AppFAB "New room" (gated rooms.create); AppErrorState retry
Statesloading (skeleton rows), success (cards), empty ("No rooms yet" + create CTA), error (retry), offline (banner + last-good cache), permission (rooms.read false → no nav entry)
Paginationpage/limit + meta {hasNext} (pagination-query.dto.ts:32-39); infinite scroll; pull-to-refresh (RefreshIndicator)
Permissionsread: rooms.read; create CTA: rooms.create (permissions.constants.ts:50-51) — client-gated (OQ-2)
Analyticsrooms.list.open, rooms.list.filter.{type,building}, rooms.list.search, rooms.list.load_more, rooms.list.refresh (proposed)
Adaptivephone: single column + FAB; tablet/desktop ≥840 dp: master-detail split (list + detail pane, 00-shared/05 §3)

2. Room Detail Screen (/rooms/:id)

FieldDetail
PurposeFull room profile: meta, facilities, actions
EntryRoom List row, deep link studylyon://rooms/:id (forward-looking)
Exitback → List; Edit → /rooms/:id/edit; Delete → confirm dialog → List
SourceGET /api/v1/rooms/:id (rooms.controller.ts:36-40); 404 → "Room not found"
WidgetsAppCard header (name, type icon, code chip); meta grid (type, capacity, building); AppChips facilities; AppListTile section rows; AppButton Edit / Delete (gated); AppSnackbar on mutations
Statesloading, success, error(404/offline/network), deleted (row gone → snackbar)
Permissionsread rooms.read; Edit rooms.update; Delete rooms.delete (client-gated, OQ-2)
ActionsEdit → editor; Delete → typed-confirm dialog (DELETE /api/v1/rooms/:idrooms.controller.ts:48-52); (planned) Book CTA when bookings module lands
FutureQR code card (forward-looking): render room.code as QR for signage; check-in analytics (proposed)
Analyticsrooms.detail.open, rooms.detail.edit, rooms.detail.delete.{start,confirm,cancel} (proposed)
Adaptivetablet/desktop: two-column (info + availability (planned)); sheet editor on narrow

3. Room Editor — Create (/rooms/new) and Edit (/rooms/:id/edit)

FieldDetail
PurposeCreate or update a room document
EntryList FAB (create, gated rooms.create); Detail "Edit" (gated rooms.update)
Exitsave → pop (Detail or List) + snackbar; cancel → discard confirm if dirty
Sourcecreate: POST /api/v1/rooms (rooms.controller.ts:24-28); edit: PATCH /api/v1/rooms/:id (rooms.controller.ts:42-46) — reuses CreateRoomDto, so name+code required even on PATCH (OQ-6, rooms.controller.ts:44)
FormAppTextField name*, code* (with uniqueness hint), capacity (number, (proposed) min 1 — OQ-7), AppDropdown type (RoomType enum, default classroom), AppTextField building, AppChips facilities input
Statesidle, validating (async code check (proposed)), submitting (button), success (pop), error: 400 field errors, 409 duplicate code inline (create only today; update (planned) OQ-1), offline block
Permissionsrooms.create / rooms.update
Analyticsrooms.editor.{create,edit}.{open,submit,success,failure,duplicate} (proposed)
Adaptivephone: single-column scroll + keyboard avoidance; tablet/desktop: centered card ≤ 640 dp

4. Delete Room — confirm dialog

FieldDetail
PurposeConfirm soft delete with explicit room name
SourceDELETE /api/v1/rooms/:id (rooms.controller.ts:48-52); void response (rooms.service.ts:48)
Behaviourtyped-name confirm (matches room.name); loading state on confirm; success → pop to List + snackbar; 404 → "already deleted" snackbar
Gapno in-use guard (OQ-4) — warn copy "room may be referenced by timetables" (planned) server truth
Analyticsrooms.delete.confirm, rooms.delete.cancel (proposed)

Shared components used

AppAppBar, AppSearchBar, AppChips, AppCard, AppListTile, AppTextField, AppDropdown, AppButton, AppFAB, AppSkeleton, AppEmptyState, AppErrorState, AppOfflineBanner, AppSnackbar, AppDialog, AppMenu, RefreshIndicator, AppAvatar/AppIconBadge. Module-specific: RoomCard, RoomTypeIcon, CapacityBadge, FacilityChips — defined in 07_Component_Library.md.

Analytics events (proposed)

rooms.list.{open,filter,search,load_more,refresh}, rooms.detail.{open,edit,delete}, rooms.editor.{open,submit,success,failure,duplicate}, rooms.delete.{confirm,cancel}. Future: rooms.booking.{book,cancel} (planned), rooms.checkin.scan (forward-looking), rooms.analytics.utilization (proposed).

Keyboard, landscape, tablet, desktop

  • Editor: portrait-first; landscape scrolls; tablet/desktop constrain width (≤ 640 dp card).
  • List: master-detail at ≥ 840 dp; desktop hover highlights rows; filter chips wrap.
  • All fields keyboard-avoidance + ScrollView resizeToAvoidBottomInset.