Files
Extrudex/design/03-smart-intake-workflow.md
cubecraft-agents[bot] 230c3b295d initial commit
2026-04-25 18:51:05 +00:00

41 KiB
Raw Blame History

Smart Intake Workflow — Screen Specification

Screen ID: FIL-003
Source of Truth: Material Design 3
Tone: Modern Industrial/Maker
Theme: Dark Mode, High-Contrast
Last Updated: 2026-04-20


1. Objective

Design the primary filament intake experience — the "Smart Intake" workflow — optimized for both the kiosk (USB barcode scanner + touchscreen) and the mobile PWA (device camera + touch). This is the most critical user flow in Extrudex: every new spool enters the system through this workflow.

The workflow follows a strict 3-state linear progression:

SCAN ──→ IDENTIFY ──→ UPDATE ──→ ✓ Complete

Users must be able to:

  • Scan: Capture a barcode/QR code via camera (mobile) or USB scanner (kiosk).
  • Identify: Confirm or correct the scanned spool's identity (material, brand, color).
  • Update: Set initial weight and status, assign a location, and complete intake.

The workflow must feel fast, confident, and forgiving — operators process many spools in a session and can't afford friction or ambiguity at any step.


2. Screen Inventory

Shared Across All States

Element MD3 Component Notes
Top App Bar md-top-app-bar (small) Title + close/dismiss
Step Indicator Custom linear stepper 3 dots/steps with active state
Bottom Sheet md-bottom-sheet Contextual info/errors on mobile

Scan State (State 1 of 3)

Element MD3 Component Notes
Camera Viewport Custom + video element Full-bleed camera with scanning overlay
Viewport Frame Custom overlay Animated scanning rectangle
Scan Result Chip md-chip (assist) Shows last scanned code
Manual Entry Link md-text-button Fallback for unreadable codes
USB Scanner Badge md-chip (status) Kiosk only — "Scanner Connected ✓"

Identification State (State 2 of 3)

Element MD3 Component Notes
Spool Identity Card md-card (filled) Material, brand, color display
Confidence Indicator Custom bar Match confidence (High/Medium/Low/Unknown)
Material Selector md-dropdown-select If multiple matches or no match
Brand Selector md-dropdown-select Brand selection
Color Picker Custom swatch grid Filament color selection
Finish + Modifier md-chip-set (choice) Material finish and modifier
"Confirm" Button md-filled-button Primary CTA — proceed to Update
"Rescan" Button md-outlined-button Go back to Scan state

Update State (State 3 of 3)

Element MD3 Component Notes
Weight Input md-filled-text-field + stepper Grams input with +/- buttons
Location Selector md-dropdown-select Assign to AMS slot or shelf
Status Toggle md-chip-set (choice) Available / In Use
QR Preview md-card Generated QR code preview
"Complete Intake" Button md-filled-button Primary CTA — finalize
"Print Label" Toggle md-switch Auto-print QR label on completion
Summary Card md-card (outlined) Final summary before submission

3. Layout Specification

Shared Layout

Top App Bar (56dp mobile / 64dp kiosk)

  • Leading: Close (✕) → returns to Inventory List with unsaved-work confirmation if mid-flow
  • Title: "Smart Intake" (all states)
  • Trailing: None (deliberate — no distractions during intake)

Step Indicator (40dp, below App Bar)

  ● ───── ○ ───── ○
  Scan   Identify  Update
  • 3-step linear indicator
  • Active step: primary filled circle + primary connecting line
  • Completed step: primary filled circle + checkmark icon
  • Future step: outline circle + outlineVariant connecting line
  • Labels: labelSmall below each dot
  • Animation: Line fills with primary color as each step completes (300ms ease-out)

STATE 1: SCAN

Title: "Scan Spool"

Layout — Mobile (Camera-based)

┌──────────────────────────────────┐
│  ✕   Smart Intake                │
│──────────────────────────────────│
│  ● ──── ○ ──── ○                │
│  Scan  Identify  Update          │
│──────────────────────────────────│
│                                  │
│  ┌──────────────────────────┐    │
│  │                          │    │
│  │    ┌────────────────┐    │    │
│  │    │  ╔════════════╗│    │    │
│  │    │  ║  VIEWPORT   ║│    │    │
│  │    │  ║  FRAME      ║│    │    │
│  │    │  ║  (animated) ║│    │    │
│  │    │  ╚════════════╝│    │    │
│  │    │                  │    │    │
│  │    │  ▲ Align barcode │    │    │
│  │    │  within frame     │    │    │
│  │    └────────────────┘    │    │
│  │                          │    │
│  │      LIVE CAMERA FEED    │    │
│  │                          │    │
│  └──────────────────────────┘    │
│                                  │
│  [Last scan: 8901234567890]     │
│                                  │
│  Can't scan? Enter manually     │
│                                  │
└──────────────────────────────────┘
  • Camera viewport: Full-bleed video feed with 16:9 or 4:3 aspect ratio
  • Scanning frame: Animated rectangle (200dp × 120dp) centered in viewport
    • Corner brackets: primary color, 24dp corner length, 3dp stroke
    • Scan line: Horizontal primary line that sweeps top-to-bottom repeatedly (2s cycle)
    • On successful scan: Frame flashes success color (green) + brief haptic (mobile)
  • Instruction text: Below frame, bodyMedium, onSurfaceVariant
  • Scan result chip: Appears below camera when a code is detected
    • Shows scanned code value in monospace
    • Auto-advances to Identification state after 1.5s (with option to cancel)
  • Manual entry link: Text button below camera area for fallback

Layout — Kiosk (USB Scanner-based)

┌──────┬──────────────────────────────────────────────┐
│ NAV  │  ✕   Smart Intake                             │
│ RAIL │──────────────────────────────────────────────│
│      │  ● ──── ○ ──── ○                            │
│      │  Scan  Identify  Update                      │
│      │──────────────────────────────────────────────│
│      │                                              │
│      │         ┌──────────────────────┐             │
│      │         │                      │             │
│      │         │   📷 SCANNER READY    │             │
│      │         │                      │             │
│      │         │   USB Scanner: ✓      │             │
│      │         │                      │             │
│      │         │   Scan a barcode or  │             │
│      │         │   QR code now...      │             │
│      │         │                      │             │
│      │         │   ═══════════════     │             │
│      │         │   (pulse animation)  │             │
│      │         │                      │             │
│      │         └──────────────────────┘             │
│      │                                              │
│      │  Or: [Enter Barcode Manually]                │
│      │                                              │
└──────┴──────────────────────────────────────────────┘
  • No camera on kiosk — USB HID barcode scanner is the primary input
  • Scanner status card: Shows connected/disconnected state
    • Connected: success icon + "Scanner Connected ✓"
    • Disconnected: error icon + "Scanner Not Found" + "Troubleshoot" button
  • Pulse animation: A horizontal line that pulses primary to indicate "waiting for scan"
  • On scan: The scanned code appears in a chip, auto-advances to Identification
  • Manual entry: Full keyboard (virtual) for typing barcode numbers

Scan State Elements

Element Description
Primary CTA None (scanning is automatic) — the camera/scanner IS the CTA
Secondary Actions Manual entry, close/dismiss
Key Components Camera viewport, scanning frame animation, scanner status (kiosk), scan result chip
States See below
State Visual
Initializing camera Shimmer loading in viewport + "Starting camera…" label
Ready (waiting for scan) Live feed + animated scan line + "Align barcode within frame"
Scanning (code detected) Frame flashes green + scan result chip appears + "Identified!" text
No match found Frame flashes yellow + chip + "Unknown barcode" → still advances to Identify (manual)
Camera denied Error card: "Camera access denied" + "Enter manually" button + permission settings link
Scanner disconnected (kiosk) Error card: "Scanner not detected" + "Reconnect scanner" + "Enter manually"
Multiple codes detected Shows list of detected codes as selectable chips → user picks correct one

STATE 2: IDENTIFY

Title: "Identify Spool"

Layout (Both platforms)

┌──────────────────────────────────┐
│  ✕   Smart Intake                │
│──────────────────────────────────│
│  ✓ ────● ──── ○                │
│  Scan  Identify  Update          │
│──────────────────────────────────│
│                                  │
│  ┌──────────────────────────┐    │
│  │ Scanned: 8901234567890   │    │
│  │ Match: HIGH CONFIDENCE   │    │
│  │ ▓▓▓▓▓▓▓▓▓▓▓▓░░ 92%     │    │
│  └──────────────────────────┘    │
│                                  │
│  Material                        │
│  ┌──────────────────────────┐    │
│  │ PLA Basic               ▾│    │
│  └──────────────────────────┘    │
│                                  │
│  Brand                           │
│  ┌──────────────────────────┐    │
│  │ Bambu Lab               ▾│    │
│  └──────────────────────────┘    │
│                                  │
│  Color                           │
│  ● ● ● ● ● ● ● ● ● [Custom]    │
│  Bla Red Blu Grn Yel Org Pur Wh │
│                                  │
│  Finish        Modifier          │
│  [Basic][Matte][Silk]  [None]   │
│                                  │
│           [Rescan] [Confirm →]   │
│                                  │
└──────────────────────────────────┘

Confidence Indicator

A horizontal bar showing match confidence from the barcode lookup:

Confidence Visual Color Behavior
High (≥80%) Full green bar success Pre-fills all fields; user just confirms
Medium (40-79%) Yellow bar warning Pre-fills material/brand; color may need correction
Low (<40%) Orange bar Custom orange Pre-fills partial; more fields need manual input
Unknown (0%) Red bar error "Barcode not found" — all fields manual

Material Selector

  • mat-select dropdown with searchable options
  • Options sourced from normalized taxonomy (MaterialBase list)
  • If confidence is High: pre-selected, field is in confirmed state (slight green tint)
  • If confidence is Low/Unknown: field is empty, highlighted for input

Brand Selector

  • mat-select dropdown with common brands
  • Searchable with "Other…" option that allows free-text entry

Color Picker

  • Swatch grid: 2 rows of circular color swatches (24dp each)
  • Common colors: Black, White, Red, Blue, Green, Yellow, Orange, Purple, Grey, Brown, Pink, Transparent
  • Tap swatch → selected (ring indicator)
  • "Custom" option → opens free-text color name input
  • Selected color stored as both name + hex value

Finish + Modifier Chips

  • Finish (required): mat-chip-listbox with single-select
    • Options: Basic, Matte, Silk, Sparkle, Metallic, Translucent
    • Default: "Basic"
  • Modifier (optional): mat-chip-listbox with single-select
    • Options: None, Carbon Fiber, Wood Fill, Glow-in-Dark, Marble, Gradient
    • Default: "None"

Identify State Elements

Element Description
Primary CTA "Confirm" filled button → advances to Update state
Secondary Actions "Rescan" outlined button → returns to Scan state
Key Components Confidence bar, Material dropdown, Brand dropdown, Color picker grid, Finish chips, Modifier chips
Validation Material and Brand are required. Color is required. Confirm button disabled until all required fields filled.

STATE 3: UPDATE

Title: "Update Spool"

Layout (Both platforms)

┌──────────────────────────────────┐
│  ✕   Smart Intake                │
│──────────────────────────────────│
│  ✓ ────✓ ──── ●                │
│  Scan  Identify  Update          │
│──────────────────────────────────│
│                                  │
│  Initial Weight                  │
│  ┌──────────────────────────┐    │
│  │ [-]  1000  [+]  grams    │    │
│  └──────────────────────────┘    │
│  Quick: [250] [500] [750] [1000] │
│                                  │
│  Assign Location                 │
│  ┌──────────────────────────┐    │
│  │ Select location...      ▾│    │
│  └──────────────────────────┘    │
│                                  │
│  Status                          │
│  [● Available] [○ In Use]       │
│                                  │
│  ┌──────────────────────────┐    │
│  │  Summary                  │    │
│  │  PLA Basic - Matte Black  │    │
│  │  Bambu Lab • 1000g       │    │
│  │  AMS 2, Slot A3 • Avail  │    │
│  │  ID: EXT-2026-PLA-0043   │    │
│  │                           │    │
│  │  ┌──────┐  Print Label   │    │
│  │  │ QR   │  [═══●═══] ON  │    │
│  │  │Preview│                 │    │
│  │  └──────┘                 │    │
│  └──────────────────────────┘    │
│                                  │
│  [◀ Back]  [✓ Complete Intake]  │
│                                  │
└──────────────────────────────────┘

Weight Input

  • Stepper control: Number input flanked by and + buttons
    • Step size: 50g (adjustable via long-press to 10g/100g)
    • Minimum: 50g, Maximum: 5000g
    • Direct numeric keyboard input also available
  • Quick-select chips: Common spool sizes (250g, 500g, 750g, 1000g) — tap to set weight instantly
    • Active chip: primaryContainer fill
    • On kiosk: Larger chips (48dp height) for easy tapping
  • Unit label: "grams" suffix, non-editable, onSurfaceVariant

Location Selector

  • mat-select dropdown organized hierarchically:
    • AMS Units → Slot A1, A2, A3, A4
    • External Holders → Shelf B1, B2, B3
    • Unassigned (default)
  • Only shows available (unoccupied) locations
  • Selected location shows printer/host info as hint text

Status Toggle

  • mat-chip-listbox single-select:
    • Available (default): Green tonal chip + "Available" label
    • In Use: Blue tonal chip + "In Use" label
  • Most new spools are "Available" on intake — this is the safe default

Summary Card

  • Outlined card showing all intake details for final review:
    • Material name, brand, weight, location, status, tracking ID
    • QR code preview (small, 80dp) — auto-generated from tracking ID
    • "Print Label" toggle switch (default: ON on kiosk, OFF on mobile)
      • When ON: Bluetooth thermal printer will produce label after completion
      • Kiosk default ON because label printer is always connected
      • Mobile default OFF because printer may not be available

Update State Elements

Element Description
Primary CTA "Complete Intake" filled button → finalizes spool creation
Secondary Actions "Back" outlined button → returns to Identify state
Key Components Weight stepper, Quick-select chips, Location dropdown, Status toggle, Summary card, Print label switch, QR preview
Validation Weight is required (>0). Location is optional. Confirm button always enabled once weight is set.

Completion Flow

  1. User taps "Complete Intake"
  2. API call creates spool record
  3. If "Print Label" is ON: send QR to thermal printer
  4. Success state: Step indicator animates all 3 steps complete + confetti-free success animation + "Spool Added ✓" snackbar
  5. Two options appear:
    • "Add Another Spool" → resets to Scan state (fastest path for batch intake)
    • "View Spool" → navigates to Spool Detail View for the newly created spool
  6. Auto-return to Inventory List after 10s if no action taken (kiosk only — prevents abandoned sessions)

States

State Visual
Default All fields at defaults, "Complete Intake" enabled once weight is set
Weight invalid Error text "Enter a weight between 50g and 5000g", button disabled
Location unavailable Dropdown shows "No available locations" + "Add as Unassigned" option
Submitting "Complete Intake" shows mat-spinner inline, disabled. Other elements non-interactive.
Success Green check animation, "Spool Added ✓", two option buttons
Error (API) Error snackbar + "Retry" action button. Form state preserved.
Error (Printer) Success still shows, but printer error snackbar: "Label print failed — reprint from spool detail"

4. UX Rationale

Scan State

  1. Camera-first on mobile. The phone's camera is the fastest barcode scanner available. No typing, no selecting — just point and scan. The animated viewport frame provides clear guidance on where to aim.

  2. USB scanner-first on kiosk. The kiosk doesn't need a camera — the USB HID scanner is faster and more reliable than camera-based scanning. The "Scanner Ready" state gives immediate confidence that the hardware is working.

  3. Auto-advance after scan. When a barcode is detected, the system should advance automatically. The 1.5s delay lets the user see what was scanned, but doesn't require a manual "next" tap. Speed matters when processing 20 spools in a row.

  4. Manual entry always available. Barcodes get damaged. Camera angles are sometimes wrong. The manual fallback prevents workflow dead-ends.

Identification State

  1. Confidence indicator reduces anxiety. When a barcode is scanned, the user needs to know: "Did the system recognize this?" The confidence bar answers this instantly. High confidence → "just confirm." Low confidence → "you'll need to fill in details." This sets expectations.

  2. Pre-fill everything possible. If the barcode matches a known product (UPC database or previous spools), pre-fill material, brand, and color. The user should confirm, not construct. Every pre-filled field is saved time.

  3. Color as swatches, not dropdown. Filament color is visual — selecting from a text dropdown ("Red" vs "Crimson" vs "Scarlet") is ambiguous. Circular swatches are unambiguous and faster to scan.

  4. Finish/Modifier as chips. These are small, mutually exclusive option sets. Chips are more glanceable and tappable than dropdowns for 2-6 options.

Update State

  1. Weight stepper + quick-select. Operators know spool weights (they're standard sizes). Quick-select chips (250g, 500g, 750g, 1000g) cover 90% of cases in a single tap. The stepper handles the remaining 10% where weight is non-standard.

  2. Location as optional. New spools may not be immediately assigned to a printer. Forcing location assignment would create friction — some operators prefer to intake first, assign later.

  3. Summary card for confidence. Before committing, the user sees everything in one place. This is the "receipt" pattern — it catches errors before they become data problems. The QR preview is especially important: operators verify the physical label will match.

  4. "Add Another" as primary post-completion action. In a batch intake session (which is common), the operator wants to immediately scan the next spool. "Add Another" should be the most prominent post-completion option.

  5. Print label default differs by platform. On kiosk, the thermal printer is connected and labels are expected. On mobile, the printer may be remote. The defaults reflect reality.


5. Visual Direction

Typography (MD3 Type Scale)

Role Token Size Weight Line Height
App Bar Title titleLarge 22sp 400 28sp
Step Labels labelSmall 11sp 500 16sp
Section Headers titleSmall 14sp 500 20sp
Field Labels bodyMedium 14sp 400 20sp
Field Values bodyLarge 16sp 400 24sp
Weight Display headlineMedium 28sp 400 36sp
Confidence Label labelLarge 14sp 500 20sp
Confidence % titleMedium 16sp 500 24sp
Scanned Code labelMedium (monospace) 12sp 500 16sp
Summary Lines bodyMedium 14sp 400 20sp
Tracking ID labelMedium (monospace) 12sp 500 16sp
CTA Button labelLarge 14sp 500 20sp
Instruction Text bodyMedium 14sp 400 20sp
Quick-Select Chip labelLarge 14sp 500 20sp

Spacing (MD3 8dp grid)

Element Spacing
App Bar padding 16dp horizontal, 12dp vertical
Step indicator padding 24dp horizontal, 12dp vertical
Camera viewport Full-bleed (0dp margin), 16dp rounded corners, overflow hidden
Section gap 16dp vertical
Field label to input 8dp
Color swatch grid gap 12dp
Quick-select chip gap 8dp
Weight stepper internal 12dp between elements
Summary card padding 16dp
Button row gap 12dp
Bottom padding (before nav bar) 16dp (mobile) / 0dp (kiosk — no bottom nav)

Color (MD3 Dark Theme — "Industrial Maker")

Same base palette as FIL-001 and FIL-002. Screen-specific additions:

Role Token Value (Dark) Usage
Camera Viewport BG surfaceContainerHighest #36343B Camera area background (before camera starts)
Scan Frame primary #A8CEDA Animated scanning rectangle
Scan Success Flash Custom success #8BD0A0 Flash on successful scan
Confidence High Custom success #8BD0A0 High confidence bar
Confidence High Container Custom successContainer #00522E High confidence bar background
Confidence Medium Custom warning #FFD580 Medium confidence bar
Confidence Medium Container Custom warningContainer #5D4200 Medium confidence bar background
Confidence Low Custom orange #FFB784 Low confidence bar
Confidence Low Container Custom orange container #5D3A00 Low confidence bar background
Confidence Unknown error #F2B8B5 Unknown/no match bar
Confidence Unknown Container errorContainer #8C1D18 Unknown bar background
Pre-filled Field Tint primaryContainer #004D63 Subtle green-blue tint on pre-filled inputs
Quick-Select Active primaryContainer #004D63 Active chip fill
Scanner Connected Custom success #8BD0A0 Kiosk scanner status
Scanner Disconnected error #F2B8B5 Kiosk scanner status

Scan Frame Animation

The scanning rectangle uses a sweep line animation:

  • Horizontal line travels from top to bottom of the frame over 2 seconds
  • Line color: primary (#A8CEDA) with 40% opacity
  • Line width: 2dp
  • Frame corner brackets: 3dp stroke, primary color
  • On code detected: Frame corners pulse green (#8BD0A0) once, scan line stops

6. Responsiveness

Kiosk (800×480) — Scan State

┌──────┬──────────────────────────────────────────────┐
│ NAV  │  ✕   Smart Intake                             │
│ RAIL │──────────────────────────────────────────────│
│      │  ● ──── ○ ──── ○                            │
│      │  Scan  Identify  Update                      │
│      │──────────────────────────────────────────────│
│      │                                              │
│      │    ┌──────────────────────────────────┐      │
│      │    │                                  │      │
│      │    │     📷  SCANNER CONNECTED ✓      │      │
│      │    │                                  │      │
│      │    │     Scan a barcode or QR code... │      │
│      │    │                                  │      │
│      │    │     ═══════════════════          │      │
│      │    │     (pulsing line)               │      │
│      │    │                                  │      │
│      │    └──────────────────────────────────┘      │
│      │                                              │
│      │    Or: [Enter Barcode Manually]              │
│      │                                              │
└──────┴──────────────────────────────────────────────┘

Kiosk (800×480) — Identify State

┌──────┬──────────────────────────────────────────────┐
│ NAV  │  ✕   Smart Intake                             │
│ RAIL │──────────────────────────────────────────────│
│      │  ✓ ────● ──── ○                            │
│      │  Scan  Identify  Update                      │
│      │──────────────────────────────────────────────│
│      │  Scanned: 8901234567890  HIGH ▓▓▓▓▓▓▓▓ 92% │
│      │──────────────────────────────────────────────│
│      │  Material: [PLA Basic         ▾]             │
│      │  Brand:    [Bambu Lab         ▾]             │
│      │  Color: ● ● ● ● ● ● ● ● ● [C]             │
│      │  Finish: [Basic][Matte][Silk]  Mod: [None]  │
│      │                                              │
│      │        [Rescan]    [Confirm →]                │
└──────┴──────────────────────────────────────────────┘
  • Two-column layout for Material/Brand on kiosk (side by side to save vertical space)
  • Finish/Modifier on same row to save space
  • Color picker horizontal with wrapping

Kiosk (800×480) — Update State

┌──────┬──────────────────────────────────────────────┐
│ NAV  │  ✕   Smart Intake                             │
│ RAIL │──────────────────────────────────────────────│
│      │  ✓ ────✓ ──── ●                            │
│      │  Scan  Identify  Update                      │
│      │──────────────────────────────────────────────│
│      │  Weight: [-] 1000 [+] g                     │
│      │  Quick: [250] [500] [750] [1000]             │
│      │  Location: [AMS 2, Slot A3     ▾]            │
│      │  Status:   [● Available] [○ In Use]          │
│      │──────────────────────────────────────────────│
│      │  ┌──────────────────────────────────┐        │
│      │  │ PLA Basic - Matte Black          │        │
│      │  │ Bambu Lab • 1000g • Slot A3      │        │
│      │  │ EXT-2026-PLA-0043  QR ████       │        │
│      │  │ Print Label [═══●═══] ON          │        │
│      │  └──────────────────────────────────┘        │
│      │                                              │
│      │       [◀ Back]    [✓ Complete Intake]        │
└──────┴──────────────────────────────────────────────┘
  • All content fits above fold on kiosk — no scrolling needed
  • Summary card compact — inline with QR preview
  • Buttons full-width in action row

Mobile PWA (375×812) — Scan State

As shown in Section 3 (full-bleed camera). Key differences:

  • Camera takes ~60% of screen height
  • Step indicator + instruction text in remaining space
  • Scan result chip floats above camera viewport

Mobile PWA (375×812) — Identify State

As shown in Section 3. Key differences:

  • Single column layout — all fields stack vertically
  • Scrollable — Identification form exceeds screen height on small phones
  • Color picker wraps to 2 rows
  • Buttons fixed at bottom (sticky)

Mobile PWA (375×812) — Update State

As shown in Section 3. Key differences:

  • Scrollable content
  • Summary card full-width
  • Buttons fixed at bottom (sticky)

Key Adaptations

Property Kiosk (800×480) Mobile (375×812)
Scan input method USB HID scanner Device camera
Scanner status card Yes (connected/disconnected) No (camera instead)
Camera viewport None Full-bleed, ~60% height
Form layout Two-column where possible Single column, scrollable
Color picker Horizontal with wrapping Horizontal with wrapping (narrower)
Quick-select chips Larger (48dp height) Standard (36dp height)
Print label default ON OFF
Post-completion auto-return 10s → Inventory No auto-return
Bottom navigation No (has rail) Yes (80dp)
Sticky buttons At bottom of content At bottom above nav bar

7. Developer Handoff Notes

Angular Material Components

UI Element Angular Material Component Notes
Top App Bar <mat-toolbar> Simple, non-collapsible. Close button on left.
Step Indicator Custom component 3-dot stepper with animated connecting lines. Use @angular/animations for line fill.
Camera Viewport <video> + overlay <div> Use @angular/cdk/overlay for scanning frame. Camera via navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }).
Scanning Frame Custom overlay SVG or absolute-positioned divs for corner brackets. CSS animation for sweep line.
Confidence Bar Custom component Horizontal bar with dynamic color + width. <div> with [style.width] binding.
Material Selector <mat-select> With <mat-option>. Add matSelectSearch for searchable dropdown.
Brand Selector <mat-select> Same as Material, plus "Other…" option with conditional <input matInput>.
Color Picker Custom component Grid of circular <button> elements. Selected state: ring border.
Finish Chips <mat-chip-listbox> Single-select. mat-chip-option elements.
Modifier Chips <mat-chip-listbox> Single-select. Include "None" as default option.
Weight Stepper Custom component <button mat-icon-button> (/+) flanking <input matInput type="number">.
Quick-Select Chips <mat-chip-listbox> Single-select. Values: 250, 500, 750, 1000.
Location Selector <mat-select> Hierarchical with <mat-optgroup> for AMS/Shelves.
Status Toggle <mat-chip-listbox> Two options: Available, In Use.
Summary Card <mat-card> outlined Read-only display. Binding from form values.
QR Preview qrcode npm package Small preview (80dp). Canvas or SVG rendering.
Print Label Switch <mat-slide-toggle> Default ON (kiosk) / OFF (mobile).
Complete Intake Button <button mat-raised-button> color="primary". Shows <mat-spinner> inline when submitting.
Rescan / Back <button mat-stroked-button> Navigates to previous state.
Success State Custom component Green checkmark animation + option buttons.
Snackbar <mat-snackbar> For success/error messages. Duration: 4s.
Confirmation Dialog <mat-dialog> "Discard intake? Unsaved data will be lost." Cancel / Discard.

Barcode/QR Scanning Implementation

Mobile (Camera):

  • Use @zxing/browser or html5-qrcode library for camera-based barcode detection
  • Configure for: EAN-13, UPC-A, Code-128, QR, Data Matrix
  • Continuous scan mode (not snapshot) for faster detection
  • On detection: debounce 500ms to prevent duplicate reads
  • Vibrate on successful scan (if Vibration API available)

Kiosk (USB HID Scanner):

  • USB HID barcode scanners appear as keyboard input — they type the code + Enter
  • Listen for rapid key sequence ending in Enter on the Scan state
  • Buffer keystrokes; when Enter detected, treat buffered text as scanned code
  • Reset buffer on any pause >100ms between keystrokes
  • Debounce: ignore duplicate codes within 2s window

Interaction Notes

  1. Auto-advance from Scan → Identify: 1.5s delay after successful scan with a cancel affordance (tap scan result chip to cancel auto-advance).
  2. Confidence-based pre-fill: On entering Identify state, call API with scanned code. If match found, pre-fill form fields. Mark pre-filled fields with subtle primaryContainer background tint.
  3. Weight stepper long-press: Long-press on +/- changes step size (50→10 or 50→100). Visual feedback: tooltip showing current step size.
  4. Quick-select chip sync: Tapping a quick-select chip updates the stepper value and vice versa. They're two inputs to the same model.
  5. Form validation (Identify): "Confirm" button is disabled until Material and Color are set. Brand is strongly recommended but not blocking (can be "Unknown").
  6. Form validation (Update): "Complete Intake" button is disabled until Weight > 0.
  7. Discard confirmation: Back/close mid-flow triggers dialog: "Discard intake? This spool won't be saved." Cancel / Discard.
  8. Post-completion "Add Another": Resets all form state, returns to Scan state. Does NOT re-initialize camera (keep it running throughout session for speed).
  9. Printer error handling: If label printing fails, show snackbar but don't block the success state. The spool is already saved; label can be reprinted from Spool Detail.
  10. Camera permission denied: Show clear error with "Open Settings" link. Also show "Enter manually" as fallback.

Accessibility

Requirement Implementation
Step indicator role="progressbar", aria-valuenow="1/2/3", aria-valuemin="1", aria-valuemax="3", aria-label="Step 1 of 3: Scan"
Camera viewport aria-label="Camera view for barcode scanning", role="application", aria-live="polite" for scan result announcements
Scanner status (kiosk) aria-live="polite" — announces "Scanner connected" or "Scanner disconnected"
Scan result aria-live="assertive" — "Barcode 8901234567890 detected"
Confidence bar role="progressbar", aria-valuenow="92", aria-label="Match confidence: 92 percent, High"
Material/Brand selects Standard mat-select accessibility — aria-label, keyboard navigable
Color picker Each swatch: aria-label="Black", role="radio", aria-checked="true/false". Radio group semantics.
Weight stepper aria-label="Weight in grams", role="spinbutton", aria-valuenow, aria-valuemin="50", aria-valuemax="5000"
Quick-select chips role="radiogroup", each chip role="radio", aria-label="500 grams"
Complete Intake button aria-label="Complete spool intake" — changes to "Submitting…" during submission
Close confirmation aria-labelledby dialog title, aria-describedby dialog content. Focus trap.
Motion reduction Disable scan line animation, use static frame. Disable auto-advance (require manual "Next").
Keyboard flow Tab: Close → Step indicator → Content → Buttons. Enter to activate. Escape to dismiss/close.

SignalR Integration

  • After "Complete Intake" API call succeeds, the new spool is pushed to all connected clients via SpoolAdded hub event.
  • The Inventory List (FIL-001) will receive this event and add the spool with highlight animation.
  • If the user navigates to Inventory after intake, the new spool is already in the list — no manual refresh needed.

Performance Notes

  • Camera stream: request 640×480 resolution for barcode scanning (sufficient, saves battery/CPU)
  • Keep camera stream alive across "Add Another" cycles — only initialize once per session
  • Debounce API calls in Identify state: don't call the barcode lookup API more than once per 2s
  • Use OnPush change detection for all Smart Intake components
  • QR preview generation should be non-blocking — render in a requestAnimationFrame callback

Routing

/intake          → Redirect to /intake/scan
/intake/scan     → Scan State
/intake/identify → Identification State
/intake/update   → Update State

Each state is a separate route. This enables:

  • Browser back button works naturally (Update → Identify → Scan)
  • Deep-linking to specific states (e.g., for testing)
  • URL reflects current step (clear for the user and for analytics)