Henry O'Neal, @decentranaut
Frontend Platform • DevEx • Solutions Architecture
Case Study

Training Pilot Platform

Mobile-first training portal (dashboard deep-links + workflow execution)

I led delivery for a pilot-ready training portal built in Blazor WebAssembly (.NET/C#). The goal was operational reliability: a stable dashboard surface, clear navigation, and a repeatable workflow that holds up on mobile. I owned milestone scope, acceptance criteria, stakeholder reviews, and the UI contracts that kept implementation consistent.

This write-up describes the production build at a pattern level. The embedded demo is a clean-room recreation that mirrors the UX contracts using Next.js, without reproducing proprietary training logic.

Quick actions
Build specs
Stack
Production: Blazor WebAssembly (.NET/C#).
Demo: Next.js (App Router) + TypeScript + Tailwind.
Navigation model
Stable dashboard route with query-selected sections (example: ?s=workout) to avoid route sprawl.
Blazor patterns
NavigationManager deep links, LocationChanged handling, store-driven UI refresh, IDisposable cleanup.
Quality gates
Mobile-first layout discipline, predictable states, and repeatable flows that survive real usage (not just screenshots).
Outcome

A browser-based pilot platform that supports real users, role-separated workflows, and repeatable training flows without app store distribution.

My role

Delivery lead and frontend architect. I set the delivery plan, broke scope into milestones, wrote acceptance criteria, and ran review loops. I translated requirements into implementable component contracts and enforced mobile-first constraints through QA.

Highlights

Stable dashboard deep links, composable panel architecture, and workflow sequencing that stays usable under real conditions.

Try it
Open the demo and evaluate the contracts
Click through the dashboard and workflow links. The goal is consistent navigation, stable layout, and predictable state.
Overview

The delivery win was the structure: a stable shell that could scale, plus workflow steps that stayed usable on a phone. The dashboard is one route with query-selected sections. Each section is a panel with a clear contract and safe defaults.

  • Stable dashboard route with deep-linkable sections (query-param driven)
  • Training workflow that works on mobile: preview, pre-step, workout, summary
  • Reusable UI primitives (cards, pills, spacing, button patterns) to prevent UI drift
  • Backend-ready seams: safe defaults and predictable update paths
Example
Deep-link the dashboard state
Open the same dashboard shell, but land directly in a specific section.
Clean-room excerpt: query-selected section
// clean-room pattern (simplified)
const section = (searchParams.get("s") ?? "workout").toLowerCase();

switch (section) {
  case "vitals": return <VitalsPanel />;
  case "meals":  return <MealsPanel />;
  default:       return <WorkoutPanel />;
}

Starting Point

Before the pilot, workflow state lived in spreadsheets and human memory. The product problem was not visual polish. It was operational reliability: reduce manual coordination, create a predictable navigation model, and make key steps completable on mobile.

What had to stop
  • Manual tracking as the only source of truth
  • Workflow dependency on trainer memory
  • Desktop-first layouts that collapse on mobile
What had to exist
  • Clear next action and minimal decision load
  • Role separation (trainer vs client vs admin)
  • Structured capture that produces usable outputs

Forward-looking note: the most realistic place for in-workout controls is the trainer surface (running a client). The client surface should stay lightweight: schedule, readiness inputs, and post-session capture. The demo includes workflow sequencing to prove UI contracts; the trainer build will own the execution controls.


What Shipped

The pilot shipped as a coherent system, not a pile of screens. That meant stable layout primitives, predictable navigation, and a workflow that stays simple under real usage.

Stable dashboard surface

One route, query-selected sections, and composable panels. This kept URLs shareable and prevented route sprawl as features grew.

Workflow sequencing

Preview, pre-step, workout, summary. The sequencing reduces decision load and keeps state transitions explicit.

UI primitives and guardrails

Reusable cards, pills, spacing rules, and button patterns. Panels render safely when data is missing and avoid dead-end states.

Backend-ready seams

UI state is modeled with safe defaults and clear boundaries so placeholder data can be replaced without a layout rewrite.

Try it
Workflow proof
This is the cleanest proof that the UX holds up end-to-end on mobile.

Milestones & Delivery

Delivery was run through gated milestones. Each gate ended in a testable artifact with explicit pass/fail criteria, so stakeholders could validate progress without developer intervention. That reduced rework and kept scope controlled.

What a gate validated
  • Access and routing: users can enter and reach the dashboard reliably
  • Deep links: sections are selectable by URL and remain stable on refresh
  • Workflow: sequencing is completable on mobile without layout breaks
  • State safety: missing data renders with safe defaults, not broken panels
What I enforced
  • Mobile-first build order: phone constraints first, then scale up
  • Reusable primitives over one-off CSS
  • Stable routing conventions and predictable navigation rules
  • Acceptance criteria written as implementable UI contracts

Architecture & UX Decisions

The platform value is in structure: stable shells, composable panels, predictable navigation, and UI guardrails. Below are concrete examples of what that means, with short clean-room excerpts.

Stable route + deep links

One stable dashboard route and a query parameter selects the section. This keeps URLs shareable and prevents route sprawl.

Example
Section deep links
Same route, different section state.
Clean-room excerpt: resolve section
// clean-room pattern (simplified)
const s = (searchParams.get("s") ?? "workout").toLowerCase();
const Current = Tabs[s] ?? Tabs.workout;
return <DashboardShell active={<Current />} />;
Composable panels

Each section is its own component with a stable contract. You add a panel without rewriting the shell.

Example
One shell
Stable shell with swappable section panels.
Clean-room excerpt: shell composition
// clean-room pattern (simplified)
export function DashboardShell({ active }) {
  return (
    <Shell>
      <Nav />
      <Main>{active}</Main>
      <RightRail />
    </Shell>
  );
}
Guardrails for missing data

Guardrails mean the UI does not break when values are unknown. It renders stable layout, safe defaults, and clear fallback copy.

Example
Safe defaults
Dummy data, real rules: do not render broken panels.
Clean-room excerpt: fallback values
// clean-room pattern (simplified)
const value = apiValue ?? 0;
const label = apiLabel ?? "Not available yet";
return <StatCard value={value} label={label} />;
Consistent visual language

Primitives are reused to keep the product cohesive. This is maintainability and delivery speed under changing scope.

Proof
Reusable primitives
Shell stays consistent across pages while the embedded demo remains isolated.

Run Demo

This embedded demo is clean-room. It demonstrates UX structure and workflow behavior without proprietary training logic. If you only click one thing, click the workflow links.

Try it
Suggested click path
Dashboard, preview, workout, summary.