Remove onboarding flow and progressive disclosure #51

Closed
opened 2026-08-15 13:35:23 +02:00 by myrmidex · 2 comments
Owner

A counter at zero is the normal case, not an unconfigured app. The onboarding gate currently makes those two states indistinguishable.

The bug this fixes

dashboard.tsx:55 gates the whole dashboard behind:

setNeedsOnboarding(totalQuantity === 0 || milestonesCount === 0);

So a counter legitimately sitting at 0 gets thrown back into the setup wizard. With milestones gone (#49) this condition is broken anyway.

Scope

Onboarding:

  • components/Onboarding/OnboardingFlow.tsx (177), components/Onboarding/CreateTrackerStep.tsx (113)
  • needsOnboarding state and handleOnboardingComplete

A tracker is created on demand with sensible defaults (count = 0) instead of via a wizard. Label and unit become editable later, not setup gates.

Progressive disclosure:

  • showProgressBar / showStatsBox / activeForm — three booleans deciding what's visible, plus the activeForm && showProgressBar && showStatsBox gate at dashboard.tsx:191
  • The style={{ display: … }} mount-but-hide pattern
  • components/Display/InlineForm.tsx → replaced by a single dialog

Fetch waterfall:

  • The identical 25-line three-endpoint Promise.all block duplicated at dashboard.tsx:29-55 and :96-122
  • TerminalSpinner on initial load

Data comes in as Inertia props from Inertia::render('dashboard', ['count' => …]). This removes the round-trip-after-paint that makes the app feel slow, and is the same one-shot render model Livewire uses — so #52 becomes a near-mechanical swap.

Acceptance criteria

  • Dashboard renders immediately with no spinner and no post-paint fetch
  • A count of 0 displays as 0 and never triggers a setup screen
  • dashboard.tsx is under ~50 lines
  • Lint clean
A counter at zero is the normal case, not an unconfigured app. The onboarding gate currently makes those two states indistinguishable. ## The bug this fixes `dashboard.tsx:55` gates the whole dashboard behind: ```ts setNeedsOnboarding(totalQuantity === 0 || milestonesCount === 0); ``` So a counter legitimately sitting at 0 gets thrown back into the setup wizard. With milestones gone (#49) this condition is broken anyway. ## Scope **Onboarding:** - `components/Onboarding/OnboardingFlow.tsx` (177), `components/Onboarding/CreateTrackerStep.tsx` (113) - `needsOnboarding` state and `handleOnboardingComplete` A tracker is created on demand with sensible defaults (`count = 0`) instead of via a wizard. Label and unit become editable later, not setup gates. **Progressive disclosure:** - `showProgressBar` / `showStatsBox` / `activeForm` — three booleans deciding what's visible, plus the `activeForm && showProgressBar && showStatsBox` gate at `dashboard.tsx:191` - The `style={{ display: … }}` mount-but-hide pattern - `components/Display/InlineForm.tsx` → replaced by a single dialog **Fetch waterfall:** - The identical 25-line three-endpoint `Promise.all` block duplicated at `dashboard.tsx:29-55` and `:96-122` - `TerminalSpinner` on initial load Data comes in as Inertia props from `Inertia::render('dashboard', ['count' => …])`. This removes the round-trip-after-paint that makes the app feel slow, and is the same one-shot render model Livewire uses — so #52 becomes a near-mechanical swap. ## Acceptance criteria - [ ] Dashboard renders immediately with no spinner and no post-paint fetch - [ ] A count of 0 displays as `0` and never triggers a setup screen - [ ] `dashboard.tsx` is under ~50 lines - [ ] Lint clean
myrmidex added this to the (deleted) milestone 2026-08-15 13:35:23 +02:00
myrmidex added the
enhancement
label 2026-08-15 13:35:23 +02:00
myrmidex self-assigned this 2026-08-15 13:35:23 +02:00
myrmidex modified the milestone from (deleted) to v0.4.0 2026-08-15 13:42:25 +02:00
Author
Owner

Scope revised — pulled forward, ahead of #48/#50

Original ticket removed onboarding entirely on the reasoning that a counter at zero is the normal case. Revised after UI verification of #47: a first-run screen stays, trimmed to a single input for the starting value.

Rationale: "I've already read 47 books, start me there" is a real need, and an increment dialog alone doesn't communicate that on first run.

First-run becomes

┌────────────────────────┐
│  > STARTING VALUE      │
│  [ 0            ]      │
│  [INITIALIZE]          │
└────────────────────────┘

Shown only when no tracker exists. After that, the counter — permanently.

Removed

  • CreateTrackerStep label + unit inputs → tracker created with defaults
  • AddEntryForm date input → starting value only
  • The milestone step entirely (AddMilestoneForm from onboarding)
  • OnboardingFlow's step chrome: step selector, [STATUS] n/2 STEPS COMPLETE, [REQ]/[✓] badges, step-completion state machine
  • The totalQuantity === 0 || milestonesCount === 0 gate at dashboard.tsx:55 → replaced by "does a tracker exist"

Known rework cost

Running this before #50 means the input writes an entries row against the existing ledger. #50 replaces that with trackers.count. Accepted deliberately — the screen is wanted now.

Superseded criteria

The original "counter of 0 never triggers a setup screen" still holds, but for a different reason: the gate becomes tracker-existence, not value-based. A tracker with count 0 shows the counter, not onboarding.

## Scope revised — pulled forward, ahead of #48/#50 Original ticket removed onboarding entirely on the reasoning that a counter at zero is the normal case. Revised after UI verification of #47: a first-run screen **stays**, trimmed to a single input for the starting value. Rationale: "I've already read 47 books, start me there" is a real need, and an increment dialog alone doesn't communicate that on first run. ### First-run becomes ``` ┌────────────────────────┐ │ > STARTING VALUE │ │ [ 0 ] │ │ [INITIALIZE] │ └────────────────────────┘ ``` Shown only when no tracker exists. After that, the counter — permanently. ### Removed - `CreateTrackerStep` label + unit inputs → tracker created with defaults - `AddEntryForm` date input → starting value only - The milestone step entirely (`AddMilestoneForm` from onboarding) - `OnboardingFlow`'s step chrome: step selector, `[STATUS] n/2 STEPS COMPLETE`, `[REQ]`/`[✓]` badges, step-completion state machine - The `totalQuantity === 0 || milestonesCount === 0` gate at `dashboard.tsx:55` → replaced by "does a tracker exist" ### Known rework cost Running this before #50 means the input writes an `entries` row against the existing ledger. #50 replaces that with `trackers.count`. Accepted deliberately — the screen is wanted now. ### Superseded criteria The original "counter of 0 never triggers a setup screen" still holds, but for a different reason: the gate becomes tracker-existence, not value-based. A tracker with count 0 shows the counter, not onboarding.
Author
Owner

Closed by #52 — remaining criteria satisfied by construction

This ticket was partially done in 8ce8a20 (onboarding trimmed to a single starting-value input, gate changed to tracker existence). Two criteria were left outstanding:

  • "Dashboard renders immediately with no spinner and no post-paint fetch" — Livewire renders server-side. GET / returns the count in the initial HTML; TerminalSpinner and the Promise.all fetch waterfall were deleted with the rest of resources/js/.
  • "dashboard.tsx is under ~50 lines" — moot. dashboard.tsx no longer exists; the equivalent is a Blade view rendered by a single Livewire component.

The progressive-disclosure chain (showProgressBar / showStatsBox / activeForm, the style={{display}} pattern, the triple-gated form) was removed earlier by #49 when StatsBox and ProgressBar were deleted.

Nothing left to do here.

## Closed by #52 — remaining criteria satisfied by construction This ticket was partially done in `8ce8a20` (onboarding trimmed to a single starting-value input, gate changed to tracker existence). Two criteria were left outstanding: - [x] **"Dashboard renders immediately with no spinner and no post-paint fetch"** — Livewire renders server-side. `GET /` returns the count in the initial HTML; `TerminalSpinner` and the `Promise.all` fetch waterfall were deleted with the rest of `resources/js/`. - [x] **"`dashboard.tsx` is under ~50 lines"** — moot. `dashboard.tsx` no longer exists; the equivalent is a Blade view rendered by a single Livewire component. The progressive-disclosure chain (`showProgressBar` / `showStatsBox` / `activeForm`, the `style={{display}}` pattern, the triple-gated form) was removed earlier by #49 when `StatsBox` and `ProgressBar` were deleted. Nothing left to do here.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lvl0/incr#51
No description provided.