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

Every client screen for the Exams module. Screens S1–S8 derive from implemented endpoints; "state" columns list the states each screen must handle (see 06_Screen_Specifications.md for detail). Tokens referenced: Sp (00-shared/02 §3), Ty (§2), El (§5), R (§4), Mo (§6). Analytics events are (proposed) per 00-shared/10_QA_Baseline.md §8.

IDScreenPurposeRoutePrimary widgetsStatesPermissions (target (planned))A11y focusAnimationsAnalytics (proposed)
S1Exams ListBrowse all exams of the tenant (paginated); entry point to planning & publish/examsAppBar, RefreshIndicator, ListView.builder of ExamCard, AppFAB.extended "New exam", AppFilterChip row (status/type), AppPaginationBarInitial/loading (skeleton), success (list), empty (no exams), error (5xx + requestId), offline (banner + cache), pagination (loading-more, last-page)exam.readScreen reader reads status badges (never color-only), focus order filter→list→FAB, touch target ≥48 dpFade-in rows Mo.fast; pull-to-refresh spinner; FAB hero transitionexam.list_view, exam.row_tap, exam.create_start
S2Exam DetailExam header + schedule (subject slots) + coverage + actions (edit/delete/add subject/publish)/exams/:examIdAppBar + AppMenu, header card (ExamHeaderCard), segmented control Schedule/Coverage, slot ListView (ExamSubjectCard), action bar FilledButton "Add subject", PublishButtonLoading, success, empty (no slots), error 404 (exam removed), offline (cached header + stale slots), publish-in-progressexam.read (actions: exam.update/exam.publish/exam.delete)Status changes announced via Semantics(liveRegion); publish button labeled with exam nameHeader fade/slide Mo.base; segmented control Mo.fast; publish progress spinner; slot list stagger Mo.fastexam.detail_view, exam.publish_tap
S3Marks EntryEnter/correct marks for one subject slot (class roster)/exams/:examId/slots/:slotId/marksSlotHeaderCard (subject, class, date/time, max/pass marks), roster ListView of MarksRow, MarksTextField per row, coverage bar (MarksSummaryBar), save-per-rowLoading (roster+marks), success, empty (roster empty), error 404 (slot removed → pop to detail), per-row saving, per-row failed, offline queue pendingexam.markNumeric keyboard friendly, per-row semantics label "{student}, {marks}/{max}", error announcementsRow save: check animation Mo.fast; failed row shake Mo.shake; coverage bar animates widthmarks_entry_open, marks_saved, marks_row_failed, marks_coverage
S4Add Subject SlotAdd one class+subject+date+time+marks slot to an exam/exams/:examId/slots/newForm page: AppDropdown (subject, class), AppDatePicker, two AppTextField time inputs, two numeric fields (max/pass marks)Form validation (inline errors), submitting (spinner), success → pop, conflict warning (overlap detected)exam.updateForm fields labeled, error summaries announced, date picker a11ySubmit button spinner; error inline slide Mo.fastexam_slot_add_start, exam_slot_add_submit, exam_slot_add_conflict_warned
S5Publish Confirm (dialog)Final gate before POST /examinations/:id/publish; shows coverage summaryoverlay on /exams/:examIdAppDialog (warning icon, coverage recap, FilledButton "Publish" / TextButton "Cancel")Initial (summary), submitting (spinner, non-dismissable), success → pop + badge update, error (404/5xx)exam.publishDialog focus trap, Escape cancels, confirm requires explicit tapDialog scale-in Mo.base; success check Mo.fastexam_publish_confirm, exam_publish_success, exam_publish_failure
S6Student Results (mine)Read-only marks list for a student/resultsAppBar, list of ResultRowCard grouped by exam, RefreshIndicatorLoading, success, empty ("No results yet"), error, offlineresult.readMarks read as {subject} {marks}/{max}Row stagger Mo.fastresults_view
S7Report CardPer-student, per-exam aggregate: subject table, totals, percentage, overall grade/results/:examId/report-cardReportCardHeader (exam, generatedAt), subject table (ReportCardTable), totals card, GradeBadge (overall), remarks columnLoading, success, empty (404 "No subjects scheduled"), errorresult.readTable header announced; grade badge label includes letter + thresholdTable rows fade Mo.fast; grade badge pop Mo.basereport_card_view, report_card_share
S8 / S8aCreate / Edit ExamForm to create (POST /examinations) or edit (PATCH /examinations/:id)/exams/new · /exams/:examId/editForm: AppDropdown (academic year, type), AppTextField name, two AppDatePicker; edit mode adds status read-only chipValidation, submitting, success → pop to detail, error 400 field / 404 (edit deleted exam)exam.create / exam.updateSame as S4Same as S4exam_form_submit, exam_form_error

Cross-screen notes

  • Shared empty/loading/error widgets: AppSkeleton, AppEmptyState, AppErrorState, AppOfflineBanner from 00-shared/03 — no module-specific rebuilds.
  • Status badges (S1/S2): draft, active, completed, published (examination.schema.ts:28-33) — one shared ExamStatusBadge component (see 07).
  • Type chips (S1/S2/S8): midterm, final, unit_test, quarterly, other (examination.schema.ts:15-20).
  • Published = terminal in UI (OQ-5): after published, S2 hides Publish, Edit (status), Delete actions; S3 allows reads but marks edits are flagged.
  • Offline: S1/S2/S6/S7 read from last-good cache; S3 queues mark writes (module offline queue, 13_State_Management.md §4); S4/S8/S5 are online-only.
  • Deep links studylyon://exams/:id etc. — (forward-looking).