510 lines
27 KiB
Markdown
510 lines
27 KiB
Markdown
# Extrudex — Homepage (Main Hub) UI/UX Specification
|
||
|
||
> **Author:** Sketch (Design Lead)
|
||
> **Date:** April 20, 2026
|
||
> **Version:** 1.0
|
||
> **Status:** Ready for Review → Implementation Handoff
|
||
|
||
---
|
||
|
||
## 1. Objective
|
||
|
||
**Who is it for?**
|
||
Workshop operators and print managers who interact with Extrudex primarily on a Raspberry Pi 5 kiosk touchscreen (arm's length, greasy hands, ambient workshop lighting) and secondarily via a mobile PWA browser for remote monitoring.
|
||
|
||
**What task are they completing?**
|
||
The Homepage serves as the **command center** — the single screen where a user can, at a glance:
|
||
|
||
1. **Assess the fleet** — See the real-time status of every printer (printing, idle, paused, error, offline).
|
||
2. **Spot problems fast** — Instantly identify which machines need attention (errors, paused jobs, low filament).
|
||
3. **Take action** — Navigate to a specific printer, spool, or print job with minimal taps.
|
||
4. **Monitor inventory** — Get a quick read on filament stock levels and recent consumption.
|
||
5. **Recent activity** — See the last few completed or failed prints for situational awareness.
|
||
|
||
**Success metric:** A user walking past the kiosk can determine fleet health in under 2 seconds without touching the screen.
|
||
|
||
---
|
||
|
||
## 2. Screen Inventory
|
||
|
||
The Homepage/Main Hub is a **single screen** that serves as the root of the navigation tree. It does not itself contain sub-screens, but it is the gateway to:
|
||
|
||
| Destination Screen | Triggered By | Priority |
|
||
|---|---|---|
|
||
| **Printer Detail** | Tapping any printer card | Primary |
|
||
| **Spool Inventory** | Nav tab "Spools" | Primary |
|
||
| **Print Jobs** | Nav tab "Prints" | Primary |
|
||
| **Materials DB** | Nav tab "Materials" | Secondary |
|
||
| **Settings** | Nav tab "Settings" | Secondary |
|
||
| **Quick Scan** | Floating action button (FAB) | Primary |
|
||
|
||
The Homepage itself contains these **in-page sections** (not separate screens):
|
||
|
||
1. **Status Summary Bar** — Fleet-wide health at a glance
|
||
2. **Printer Fleet Grid** — Live status cards for each printer
|
||
3. **Filament Stock Snapshot** — Inventory overview with low-stock alerts
|
||
4. **Recent Activity Feed** — Last 5 print events
|
||
|
||
---
|
||
|
||
## 3. Layout Specification
|
||
|
||
### Page Title
|
||
**"Extrudex"** — Always visible in the top app bar. No subtitle needed; this is the root screen.
|
||
|
||
### Navigation Structure
|
||
|
||
**Primary Navigation: Bottom Navigation Bar (Mobile/Kiosk)**
|
||
Material Design 3 bottom navigation with 5 destinations:
|
||
|
||
| Tab | Icon (Material Symbols) | Label | Badge? |
|
||
|---|---|---|---|
|
||
| **Hub** | `dashboard` | Hub | — (active by default) |
|
||
| **Printers** | `print` | Printers | Error count badge |
|
||
| **Spools** | `inventory_2` | Spools | Low-stock badge |
|
||
| **Prints** | `receipt_long` | Prints | — |
|
||
| **Settings** | `settings` | Settings | — |
|
||
|
||
**Rationale for bottom nav:**
|
||
- Touch-first: bottom nav is the easiest reach zone on a touchscreen kiosk or phone.
|
||
- 5 tabs is the MD3 maximum — keeps things scannable.
|
||
- "Hub" is the homepage; the other four are top-level destinations.
|
||
- Badges on Printers/Spools draw attention to problems without requiring navigation.
|
||
|
||
**Desktop/Navigation Rail (Future)**
|
||
On wider screens (browser dashboard), the bottom nav converts to a Material 3 Navigation Rail on the left edge with the same 5 destinations. This is a responsive transformation, not a separate navigation system.
|
||
|
||
### Main Sections (Top to Bottom)
|
||
|
||
#### A. Top App Bar
|
||
- **Leading:** Extrudex logo mark (gear icon + "EXTRUDEX" in Inter Bold)
|
||
- **Trailing:**
|
||
- Connection status indicator (green dot = SignalR connected, red dot = disconnected)
|
||
- Clock (kiosk mode — always visible so users know the time without looking at their phone)
|
||
- **Style:** MD3 medium top app bar, `surface` color background, no elevation (flat)
|
||
- **Height:** 64px kiosk / 56px mobile
|
||
|
||
#### B. Status Summary Bar
|
||
A horizontal strip below the app bar showing fleet-wide metrics in a single row:
|
||
|
||
| Metric | Format | Color Logic |
|
||
|---|---|---|
|
||
| Printers Active | `4 / 7` | Text only, neutral |
|
||
| Printers in Error | `1` | Red if > 0, hidden if 0 |
|
||
| Low Filament Spools | `2` | Yellow if > 0, hidden if 0 |
|
||
| Prints Today | `12` | Neutral |
|
||
|
||
- **Layout:** Horizontal flex row, evenly spaced, each metric in a compact chip/badge
|
||
- **Kiosk override:** Larger font (20px), more spacing between metrics
|
||
- **Mobile:** Compact chips with icons, horizontally scrollable if overflow
|
||
- **Tap behavior:** Tapping "Printers in Error" navigates to Printers tab filtered to errors. Tapping "Low Filament" navigates to Spools tab filtered to low stock.
|
||
|
||
#### C. Printer Fleet Grid
|
||
The **heart of the homepage**. A responsive grid of printer status cards.
|
||
|
||
**Card Layout (each printer):**
|
||
|
||
```
|
||
┌─────────────────────────────┐
|
||
│ [Status Dot] Printer Name │ ← Header row
|
||
│─────────────────────────────│
|
||
│ Current Job: Benchy #3 │ ← Job name or "Idle"
|
||
│ [████████░░] 72% │ ← Progress bar + percentage
|
||
│ Filament: PLA Silk │ ← Active material
|
||
│ Remaining: ~142g │ ← Spool remaining
|
||
│ ETA: 0h 23m │ ← Time remaining
|
||
│─────────────────────────────│
|
||
│ [View Detail →] │ ← Tap target / CTA
|
||
└─────────────────────────────┘
|
||
```
|
||
|
||
**Status Dot Colors:**
|
||
- 🟢 Green (`#4ADE70` kiosk / `#16A34A` light) — Printing / Active
|
||
- 🟡 Yellow (`#FACC15` kiosk / `#CA8A04` light) — Paused
|
||
- 🔴 Red (`#F87171` kiosk / `#DC2626` light) — Error / Failed
|
||
- ⚪ Gray (`#64748B`) — Idle / Offline
|
||
|
||
**Grid Behavior:**
|
||
- Kiosk (800×480 Pi 5): 2 columns, 3–4 rows (scrollable)
|
||
- Tablet (768px+): 3 columns
|
||
- Mobile (< 480px): 1 column, list view
|
||
|
||
**Card Dimensions:**
|
||
- Kiosk: Full-width within column, min-height 180px
|
||
- Mobile: Full-width, min-height 140px, slightly denser
|
||
|
||
**Important States:**
|
||
- **Printing (active):** Progress bar animates, card has subtle left-border accent in green
|
||
- **Paused:** Yellow left border, progress bar frozen, "PAUSED" badge overlaid
|
||
- **Error:** Red left border, card background shifts to `error-container` token, error message shown
|
||
- **Idle:** Gray left border, dimmed progress area, "Ready" label
|
||
- **Offline:** Fully dimmed card, "OFFLINE" badge, no real-time data
|
||
|
||
#### D. Filament Stock Snapshot
|
||
A compact section showing inventory health:
|
||
|
||
**Layout:** Horizontal scrolling row of small cards or a mini-list
|
||
|
||
```
|
||
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||
│ PLA │ │ PETG │ │ TPU │
|
||
│ ████████░░ 80% │ │ ████░░░░░ 40% │ │ ██░░░░░░░ 20% │
|
||
│ 23 spools │ │ 8 spools │ │ 3 spools ⚠️ │
|
||
└──────────────────┘ └──────────────────┘ └──────────────────┘
|
||
```
|
||
|
||
- Each card shows: Material base name, stock percentage bar, spool count
|
||
- Cards with < 25% stock get a `⚠️` warning indicator and yellow-tinted background
|
||
- **Kiosk:** 2–3 cards visible, swipe to see more
|
||
- **Mobile:** Horizontal scroll carousel
|
||
- **Tap:** Navigates to Spools tab filtered by that material
|
||
|
||
#### E. Recent Activity Feed
|
||
The last 5 print events in a compact list:
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────┐
|
||
│ ✓ Benchy #3 · PLA Silk · 23g · 0h45m │
|
||
│ ✓ Gear Set v2 · PETG Basic · 87g · 2h12m │
|
||
│ ✗ Phone Case · TPU Basic · — · Failed │
|
||
│ ✓ Calibration · PLA Basic · 4g · 0h05m │
|
||
│ ✓ Bracket x4 · ASA Matte · 156g · 4h30m │
|
||
└────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
- Each row: Status icon, job name, material, weight used, duration
|
||
- Failed prints show `✗` in red with "Failed" label
|
||
- **Kiosk:** Larger text, comfortable row height (56px)
|
||
- **Mobile:** Standard list density (48px rows)
|
||
- **Tap a row:** Navigates to that print's detail view
|
||
- **"View All" link:** At bottom, navigates to Prints tab
|
||
|
||
### Primary CTA
|
||
**Floating Action Button (FAB):** "Quick Scan" — a prominent FAB in the bottom-right corner with a `qr_code_scanner` icon. This triggers the barcode/USB scanner workflow for spool check-in/check-out.
|
||
|
||
- Kiosk: Extended FAB with label "Scan" + icon, 56×56px minimum
|
||
- Mobile: Standard FAB, icon only, 56×56px
|
||
- Positioned above the bottom nav, with 16px margin from edges
|
||
|
||
### Secondary Actions
|
||
- Tap any printer card → Printer Detail
|
||
- Tap any stock card → Spools filtered
|
||
- Tap any activity row → Print detail
|
||
- Tap error/low badges in summary bar → Filtered navigation
|
||
|
||
### Key Components (MD3)
|
||
|
||
| Component | Usage | Notes |
|
||
|---|---|---|
|
||
| Bottom Navigation | Primary nav | 5 destinations |
|
||
| Top App Bar (Medium) | App header | Logo + status + clock |
|
||
| Cards (Elevated) | Printer status | Real-time content |
|
||
| Cards (Filled/outlined) | Filament stock | Compact, scrollable |
|
||
| List | Activity feed | 3-line items |
|
||
| FAB (Extended/Regular) | Quick Scan | Always accessible |
|
||
| Badge | Nav tabs, status | Error count, low stock |
|
||
| Linear Progress Indicator | Print progress | On printer cards |
|
||
| Chip | Status summary | Compact metrics |
|
||
|
||
### Important States
|
||
|
||
| State | Visual Treatment |
|
||
|---|---|
|
||
| Loading (initial) | Skeleton screens for printer cards, shimmer animation |
|
||
| SignalR disconnected | Red dot in app bar, banner: "Live updates paused — reconnecting..." |
|
||
| No printers registered | Empty state illustration + "Add your first printer" CTA |
|
||
| No spools registered | Stock section shows "No inventory — add spools to start tracking" |
|
||
| All printers idle | Fleet grid shows all gray cards, summary bar shows "0 active" |
|
||
| Critical error (printer) | Card pulses red border once, then steady red left border |
|
||
|
||
---
|
||
|
||
## 4. UX Rationale
|
||
|
||
### Why This Layout Supports the Task
|
||
|
||
1. **Fleet health at a glance:** The Status Summary Bar + Printer Fleet Grid are visible immediately on load. No scrolling required on kiosk to see if something is wrong. Color-coded status dots and left-border accents make the visual scan instantaneous.
|
||
|
||
2. **Progressive detail:** The homepage gives you "enough" — status, progress, material. You only tap into a printer card when you need details (temps, G-code, history). This avoids information overload while keeping critical data surface-level.
|
||
|
||
3. **Inventory awareness without navigation:** The Filament Stock Snapshot means operators don't need to leave the homepage to know if they're running low. The warning state (yellow + ⚠️) is visible without interpreting numbers.
|
||
|
||
4. **Activity context:** The Recent Activity Feed gives "what just happened" situational awareness — useful when returning to the kiosk after being away. It answers "did that print finish?" without requiring navigation.
|
||
|
||
5. **Scan-first workflow:** The FAB for Quick Scan is always accessible from the homepage, which is the most common action for spool check-in during workshop operations. Placed bottom-right — the natural resting thumb zone.
|
||
|
||
### Hierarchy (What matters most → least)
|
||
|
||
1. **Printer errors** (red, draws the eye immediately)
|
||
2. **Active printers with progress** (green accent, animated progress bars)
|
||
3. **Paused printers** (yellow accent, needs attention)
|
||
4. **Low filament warnings** (yellow indicators in stock section)
|
||
5. **Idle printers** (gray, calm, no action needed)
|
||
6. **Recent activity** (informational, below the fold on mobile)
|
||
|
||
### Tradeoffs
|
||
|
||
| Decision | Benefit | Cost | Mitigation |
|
||
|---|---|---|---|
|
||
| Bottom nav over side nav | Touch-friendly, MD3 standard, always visible | Takes screen space at bottom | Acceptable on touch-first device |
|
||
| Cards over table | Glanceable, status-colorable, touch-friendly | Less dense (can't see 7 printers at once) | Grid layout maximizes visible count; scroll for 6+ printers |
|
||
| Summary bar metrics | Fleet health without scrolling | Adds cognitive load if too many metrics | Keep to 4 max, hide zero-value metrics |
|
||
| Horizontal scroll for stock cards | Saves vertical space, works well for 3–6 materials | Hidden cards require swipe | First 3 most-used materials visible; swipe for rest |
|
||
| FAB for scan | Always accessible, one-tap | Covers content behind it | Standard FAB behavior; scrolls away on mobile |
|
||
| No sidebar on kiosk | Maximizes kiosk screen real estate | No persistent deep-nav | Bottom nav is sufficient for 5 top-level destinations |
|
||
|
||
---
|
||
|
||
## 5. Visual Direction
|
||
|
||
### Tone
|
||
**Modern Industrial/Maker** — Dark mode by default on kiosk. Professional workshop vibe. High contrast. Think: a CNC control panel, not a social media app. The aesthetic should feel like a tool you trust, not an app you browse.
|
||
|
||
### Dark Mode Palette (Kiosk Default)
|
||
|
||
| Token | Value | Usage |
|
||
|---|---|---|
|
||
| `md.sys.color.background` | `#0F172A` | Page background |
|
||
| `md.sys.color.surface` | `#1E293B` | Card backgrounds, nav bar |
|
||
| `md.sys.color.surface-container` | `#334155` | Elevated cards, containers |
|
||
| `md.sys.color.surface-container-high` | `#475569` | Hover/pressed states |
|
||
| `md.sys.color.primary` | `#60A5FA` | Primary actions, links, active tab |
|
||
| `md.sys.color.on-primary` | `#0F172A` | Text on primary |
|
||
| `md.sys.color.primary-container` | `#1E3A5F` | Subtle primary tinted containers |
|
||
| `md.sys.color.error` | `#F87171` | Error states, failed prints |
|
||
| `md.sys.color.error-container` | `#450A0A` | Error card backgrounds |
|
||
| `md.sys.color.on-error` | `#FFFFFF` | Text on error |
|
||
| `md.sys.color.on-surface` | `#F1F5F9` | Primary text |
|
||
| `md.sys.color.on-surface-variant` | `#94A3B8` | Secondary text |
|
||
| `md.sys.color.outline` | `#334155` | Borders, dividers |
|
||
| `md.sys.color.outline-variant` | `#1E293B` | Subtle borders |
|
||
|
||
### Light Mode Palette (Dashboard/Future)
|
||
|
||
| Token | Value | Usage |
|
||
|---|---|---|
|
||
| `md.sys.color.background` | `#F8FAFC` | Page background |
|
||
| `md.sys.color.surface` | `#FFFFFF` | Card backgrounds |
|
||
| `md.sys.color.primary` | `#2563EB` | Primary actions |
|
||
| `md.sys.color.on-surface` | `#0F172A` | Primary text |
|
||
| `md.sys.color.on-surface-variant` | `#475569` | Secondary text |
|
||
|
||
### Typography
|
||
|
||
| Role | Font | Weight | Size (Kiosk) | Size (Mobile) |
|
||
|---|---|---|---|---|
|
||
| App Title | Inter | Bold | 22px | 20px |
|
||
| Card Title (Printer Name) | Inter | SemiBold | 20px | 18px |
|
||
| Section Heading | Inter | SemiBold | 18px | 16px |
|
||
| Body Text | Inter | Regular | 18px | 16px |
|
||
| Metric Value | Inter | Bold | 28px | 24px |
|
||
| Metric Label | Inter | Medium | 14px | 12px |
|
||
| Mono Values (weight, time, %) | JetBrains Mono | Medium | 18px | 16px |
|
||
| Caption / Timestamp | Inter | Regular | 14px | 12px |
|
||
|
||
**Rationale for oversized metrics:** The kiosk is viewed at arm's length or further. A 28px bold metric is legible from 3–4 feet away. Monospace for numeric values ensures columns align and feels "instrument-like."
|
||
|
||
### Spacing / Density
|
||
|
||
| Token | Kiosk | Mobile |
|
||
|---|---|---|
|
||
| Page padding | 24px | 16px |
|
||
| Card padding | 20px | 16px |
|
||
| Grid gap | 16px | 12px |
|
||
| Section gap | 32px | 24px |
|
||
| Row height (lists) | 56px | 48px |
|
||
| FAB margin from edge | 16px | 16px |
|
||
| Touch target minimum | 48px | 44px |
|
||
|
||
### Component Behavior
|
||
|
||
- **Printer cards:** Update in real-time via SignalR. Progress bar animates smoothly (CSS transition 300ms). Status changes trigger a brief highlight flash (200ms background shift) to draw attention.
|
||
- **Bottom nav:** Active tab has `primary` color icon + label. Inactive tabs use `on-surface-variant`. Badges are small circles positioned at the icon's top-right.
|
||
- **FAB:** Elevated with shadow-3. On tap, ripple effect. Extended label appears on kiosk (wider screen), icon-only on mobile.
|
||
- **Status summary bar:** Metric chips are non-scrolling on kiosk (fits in one row at 800px width), horizontally scrolling on mobile if needed.
|
||
- **Activity feed:** List items have subtle divider lines (`outline-variant`). Failed items have `error-container` background tint.
|
||
- **Skeleton loading:** Cards show shimmer placeholder during initial load (1.5s max before content appears).
|
||
|
||
### Color Usage Guidelines
|
||
|
||
1. **Color is information, not decoration.** Every colored element must communicate state.
|
||
2. **Red = immediate attention.** Only use for errors, failures, disconnections. Never for decoration.
|
||
3. **Yellow = needs attention soon.** Paused printers, low filament, warnings.
|
||
4. **Green = operating normally.** Active printing, completed, connected.
|
||
5. **Blue = interactive.** Links, buttons, active navigation, primary CTAs.
|
||
6. **Gray = neutral/idle.** Offline printers, inactive states, secondary info.
|
||
7. **Never use color alone to convey meaning.** Always pair with icon + text label (accessibility).
|
||
|
||
---
|
||
|
||
## 6. Responsiveness
|
||
|
||
### Breakpoints
|
||
|
||
| Breakpoint | Width | Layout |
|
||
|---|---|---|
|
||
| Kiosk | 480–800px (Pi 5 typical: 800×480) | 2-col grid, bottom nav, extended FAB |
|
||
| Mobile (compact) | < 480px | 1-col list, bottom nav, standard FAB |
|
||
| Tablet | 768–1024px | 3-col grid, bottom nav, extended FAB |
|
||
| Desktop | 1024px+ | 3-col grid, nav rail, extended FAB |
|
||
|
||
### Layout Changes by Device
|
||
|
||
#### Pi 5 Kiosk (800×480, Landscape)
|
||
- **Top app bar:** 64px height, clock always visible
|
||
- **Status summary:** 4 metrics in a single row (fits 800px)
|
||
- **Printer grid:** 2 columns × N rows, scrollable vertically
|
||
- **Stock snapshot:** 3 cards visible, no scroll needed (most common materials first)
|
||
- **Activity feed:** 3 rows visible, "View All" link
|
||
- **Bottom nav:** Full 5 tabs
|
||
- **FAB:** Extended with "Scan" label
|
||
|
||
#### Mobile PWA (< 480px, Portrait)
|
||
- **Top app bar:** 56px height, no clock (use phone clock)
|
||
- **Status summary:** 2–3 metrics visible, horizontal scroll for more
|
||
- **Printer grid:** 1 column list view (cards become horizontal list items)
|
||
- **Stock snapshot:** Horizontal carousel, 2 cards visible
|
||
- **Activity feed:** 3–5 rows, compact density
|
||
- **Bottom nav:** 5 tabs (may collapse labels on very narrow screens)
|
||
- **FAB:** Icon only, standard 56px
|
||
|
||
#### Tablet / Desktop Browser
|
||
- **Bottom nav → Navigation Rail** (left side, 80px wide)
|
||
- **Printer grid:** 3 columns
|
||
- **Stock snapshot:** 4–5 cards visible in row
|
||
- **Activity feed:** 5 rows
|
||
- **Additional whitespace** — dashboard mode can breathe more
|
||
|
||
### Kiosk-Specific Considerations
|
||
|
||
- **No hover states** — all interactions are tap/click only
|
||
- **No tooltips** — information must be visible inline
|
||
- **Larger touch targets** — 48px minimum (4px above MD3 default)
|
||
- **No right-click context menus** — all actions are explicit buttons/links
|
||
- **Screen wake** — kiosk should not sleep; CSS `animation` on a subtle element to prevent screen burn-in (shift a 1px element every 60s)
|
||
- **Overshoot scroll** — prevent pull-to-refresh or browser gestures (PWA `overscroll-behavior: none`)
|
||
|
||
---
|
||
|
||
## 7. Developer Handoff Notes
|
||
|
||
### Reusable Components to Build
|
||
|
||
| Component | Type | Props/Inputs | Notes |
|
||
|---|---|---|---|
|
||
| `<ex-printer-card>` | Standalone | `printer: Printer`, `status: PrinterStatus`, `job?: PrintJob` | Left-border color computed from status. SignalR drives re-renders. |
|
||
| `<ex-status-dot>` | Atom | `status: 'active' \| 'paused' \| 'error' \| 'idle' \| 'offline'` | Small colored circle (12px) with aria-label for accessibility |
|
||
| `<ex-metric-chip>` | Atom | `label: string`, `value: string \| number`, `variant: 'default' \| 'error' \| 'warning'` | Used in Status Summary Bar |
|
||
| `<ex-stock-card>` | Standalone | `material: string`, `percentage: number`, `spoolCount: number`, `lowStock: boolean` | Horizontal scroll child |
|
||
| `<ex-activity-item>` | List Item | `job: PrintEvent` | 3-line list item with status icon |
|
||
| `<ex-progress-bar>` | Atom | `value: number`, `status: PrinterStatus` | MD3 linear progress, color matches status |
|
||
| `<ex-fleet-summary>` | Composite | `printers: Printer[]`, `spools: Spool[]` | Renders metric chips row |
|
||
| `<ex-connection-indicator>` | Atom | `connected: boolean` | Green/red dot in app bar |
|
||
|
||
### Angular Material Components Used
|
||
|
||
- `MatBottomNavigation` (or custom bottom nav — MD3 bottom nav is not yet in Angular Material; implement with `MatTabNav` + custom styling)
|
||
- `MatCard` → Styled with custom dark tokens
|
||
- `MatProgressBar` → Custom color per status
|
||
- `MatFabButton` / `MatMiniFabButton`
|
||
- `MatBadge` → For nav tab badges
|
||
- `MatList` → Activity feed
|
||
- `MatChip` → Status summary metrics
|
||
- `MatIcon` → Material Symbols throughout
|
||
- `MatToolbar` → Top app bar
|
||
|
||
### Interaction Notes
|
||
|
||
1. **SignalR subscriptions:** The homepage must subscribe to `PrinterHub` on mount. Each printer card re-renders on status/progress push events. Unsubscribe on navigate-away.
|
||
2. **Optimistic updates:** Progress bars should animate smoothly — use CSS transitions, not discrete jumps. If SignalR sends a progress update every 5s, interpolate between values.
|
||
3. **FAB scan action:** On tap, immediately focus a hidden text input that captures USB HID barcode scanner output ( scanners type characters + Enter). This is a capture-only input — no keyboard should appear on mobile. Use `<input readonly>` or intercept `keydown` globally.
|
||
4. **Pull-to-refresh:** Disabled on kiosk. On mobile PWA, consider enabling for manual data refresh.
|
||
5. **Navigation:** Use Angular Router with bottom nav tabs bound to routerLinkActive. Highlight active tab. Preserve scroll position when returning to Hub.
|
||
6. **Skeleton screens:** On initial load, show 6 skeleton printer cards (matching grid layout). Use `@angular/material` skeleton patterns or custom shimmer CSS.
|
||
|
||
### Accessibility
|
||
|
||
| Requirement | Implementation |
|
||
|---|---|
|
||
| Screen reader | All status indicators have `aria-label` (e.g., "Printer Elegoo-1: Printing, 72% complete") |
|
||
| Color blindness | Never color-only — always icon + text + color. Status dots have aria-labels |
|
||
| Keyboard nav | Tab order: top bar → summary metrics → printer cards (grid order) → stock → activity → FAB → bottom nav |
|
||
| Focus management | After navigation, focus lands on the page title. After FAB tap, focus returns to FAB |
|
||
| Touch target | 48px minimum on kiosk, 44px minimum on mobile — all interactive elements |
|
||
| Contrast | All text on dark background meets WCAG AA (4.5:1 for body, 3:1 for large text) |
|
||
| Motion | Respect `prefers-reduced-motion` — disable progress bar animation and shimmer if set |
|
||
| Live regions | Printer status changes announced via `aria-live="polite"` on the card region |
|
||
|
||
### Performance Notes
|
||
|
||
- **OnPush change detection** for all components receiving SignalR data
|
||
- **TrackBy** on printer grid `*ngFor` to avoid re-rendering unchanged cards
|
||
- **Virtual scrolling** for activity feed if it grows beyond 20 items (use `@angular/cdk ScrollingModule`)
|
||
- **Lazy load** Spools, Prints, Materials, Settings tabs — only Hub is eager-loaded
|
||
- **Image optimization:** Use inline SVG for status icons, not raster images. Logo should be SVG.
|
||
|
||
### File Structure Suggestion
|
||
|
||
```
|
||
src/app/
|
||
├── pages/
|
||
│ └── hub/
|
||
│ ├── hub.component.ts
|
||
│ ├── hub.component.html
|
||
│ ├── hub.component.scss
|
||
│ └── hub.component.spec.ts
|
||
├── components/
|
||
│ ├── printer-card/
|
||
│ ├── status-dot/
|
||
│ ├── metric-chip/
|
||
│ ├── stock-card/
|
||
│ ├── activity-item/
|
||
│ ├── progress-bar/
|
||
│ ├── fleet-summary/
|
||
│ └── connection-indicator/
|
||
├── layout/
|
||
│ ├── bottom-nav/
|
||
│ ├── top-app-bar/
|
||
│ └── nav-rail/
|
||
└── shared/
|
||
└── tokens/
|
||
└── _extrudex-tokens.scss
|
||
```
|
||
|
||
---
|
||
|
||
## Appendix: Navigation Map
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ EXTRUDEX │
|
||
│ │
|
||
│ ┌─ Hub (Home) ──────────────────────────────────────────┐ │
|
||
│ │ • Fleet Status Grid │ │
|
||
│ │ • Filament Snapshot │ │
|
||
│ │ • Recent Activity │ │
|
||
│ │ • [FAB: Quick Scan] │ │
|
||
│ └────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Printers ────────┐ ┌─ Spools ─────────────────────┐ │
|
||
│ │ Printer List │ │ Spool Inventory │ │
|
||
│ │ → Printer Detail │ │ → Spool Detail │ │
|
||
│ │ → Job History │ │ → Check-in/Check-out │ │
|
||
│ │ → Controls │ │ → Link to Printer │ │
|
||
│ └────────────────────┘ └─────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Prints ──────────┐ ┌─ Settings ───────────────────┐ │
|
||
│ │ Print Job List │ │ System Configuration │ │
|
||
│ │ → Print Detail │ │ Printer Management │ │
|
||
│ │ → COGS Report │ │ User Preferences │ │
|
||
│ └────────────────────┘ └──────────────────────────────┘ │
|
||
│ │
|
||
│ ══════════════════════════════════════════════════════════ │
|
||
│ [Hub] [Printers] [Spools] [Prints] [Settings] │
|
||
│ ══════════════════════════════════════════════════════════ │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
*End of Specification — Ready for Stuart (mockup generation) and Rex (implementation handoff)* |