# Onboarding UX v2

Status: Complete

Supersedes the original onboarding-ux plan. Based on usability testing session (March 2026) covering the setup wizard, launch checklist, email provider setup, and general onboarding flow.

## Vision

A non-technical seller should be able to go from zero to a live shop without confusion or frustration. The setup should feel like one cohesive journey, not a scavenger hunt through admin pages. Every step should explain *why* it's needed, be forgiving of mistakes, and never leave the user stranded.

## Current flow

1. **Setup wizard** (`lib/berrypod_web/live/setup/onboarding.ex`): 3 cards — admin account, provider API key, Stripe connection. Gated by secret in prod, auto-login after account creation.
2. **Dashboard checklist** (`lib/berrypod_web/live/admin/dashboard.ex`): 5 items with progress bar. Visible when `site_live` is false and not dismissed.
3. **Coming soon page**: blocks public access before launch.
4. **Setup status** (`lib/berrypod/setup.ex`): `setup_status/0` returns booleans for each milestone.

## What changes

### A. Simplify initial setup to account creation only

The first screen should be dead simple and low-friction: email, password (with confirmation field), shop name. That's it. No provider keys, no Stripe.

- Live validation on all fields (email format, password strength/match, shop name not blank)
- Note under shop name: "You can change this later"
- On submit: create account, log in, redirect to the guided setup flow

Email/password correction after this point is just normal admin account settings — no special "go back to setup" needed.

**Files:** `lib/berrypod_web/live/setup/onboarding.ex`, possibly `lib/berrypod_web/live/admin/settings.ex`

### B. Guided setup flow with progress bar

After account creation, the user enters a single multi-step guided journey. This replaces the current approach of separate admin pages.

**Intro screen** — before any steps, briefly explain what Berrypod does and why you need each thing:

> "Berrypod connects your print-on-demand products to your own online shop. To get fully set up, you'll need three things:
>
> - A **print provider** account (like Printify or Printful) to make and ship your products
> - A **Stripe** account to accept payments from customers
> - An **email provider** account so your shop can send order confirmations and shipping updates"

Then the steps with a clear progress bar at the top. Each step shows: step number, title, whether it can be skipped, estimated time.

**Steps:**
1. **Connect print provider** — allow connecting multiple providers (not forced to pick just one). "Skip for now" available.
2. **Connect Stripe for payments** — "Skip for now" available.
3. **Set up email provider** — "Skip for now" available.

Each step embeds the same settings UI components that live in the admin pages (shared, not duplicated). The guided flow adds extra context and hand-holding around them.

On completion (or after skipping all): redirect to dashboard with clear status messaging.

**Key UX decisions:**
- Progress bar visible at all times, showing completed/current/upcoming steps
- Each step has a "Skip for now" with a brief, non-naggy note about what won't work without it
- External service links (create Printify account, etc.) open in new tabs with external-link icon and aria label
- Users can go back to previous steps to correct mistakes
- If revisiting (e.g. after closing browser), detect existing state via `Setup.setup_status/0` and resume from the first incomplete step

**Files:** `lib/berrypod_web/live/setup/onboarding.ex`, `lib/berrypod/setup.ex`, new shared components

### C. Forgiving API key validation

API key entry should be as forgiving as possible:

- Auto-strip leading/trailing whitespace on paste and submit
- Validate format where known:
  - Printify: 36-character UUID format
  - Printful: specific prefix/length
  - Stripe: must start with `sk_live_` or `sk_test_`
  - Email providers: provider-specific format checks
- Specific, helpful error messages: "This looks too short — Printify API keys are usually 36 characters" rather than generic "Invalid"
- Validate on blur for fast feedback, not just on submit
- Link to where to find the key: "Find your Printify API key at Settings > Connections"

**Files:** `lib/berrypod_web/live/setup/onboarding.ex`, `lib/berrypod_web/live/admin/providers.ex`, validation logic in contexts

### D. Email provider setup UX — done

Reworked the email provider selection and configuration. Changes across two sessions:

**Session 1 (commit dd659e4):**
- Recommended pick (Brevo) highlighted with badge
- Two groups: "Also sends newsletters" vs "Transactional only"
- One-liner per provider with free tier info
- Self-hosted/SMTP in collapsible "Advanced" section
- Guided flow after selection with config fields
- Send test email button with async delivery
- Removed masked key display
- Default from address auto-set from admin email
- No-JS support via controller POST fallback
- 17 audit fixes (a11y, error handling, UX)

**Session 2 (uncommitted):**
- Dropped 4 transactional-only providers (Resend, Postmark, Mailgun, MailPace) — all are transactional-only and not useful for a shop that needs newsletters. 6 adapters remain: Brevo, SendGrid, Mailjet, MailerSend + SMTP, Postal
- Removed "Popular providers" heading and description (unnecessary with fewer providers)
- Fixed no-JS provider switching: noscript submit button always visible with dynamic text
- Fixed no-JS radio highlight: replaced server-applied `card-radio-card-selected` class with pure CSS `:has(:checked)` selector
- Cleaned up key validation (removed 4 provider clauses, removed 2 known prefixes)
- Updated all related tests (adapters, key validation, email settings LiveView, controller, mailer)

**Files:** `lib/berrypod_web/live/admin/email_settings.ex`, `lib/berrypod/mailer/adapters.ex`, `lib/berrypod/key_validation.ex`, `assets/css/admin/components.css`, `lib/berrypod_web/controllers/email_settings_controller.ex`

### E. Contextual prompts for skipped steps

When a step is skipped, surface the need where it matters — once per context, never as global nags:

- **Products page** (no print provider): empty state explaining why products are empty, with link to connect a provider
- **Cart/checkout** (no Stripe): checkout button disabled with explanation and link to connect Stripe
- **Order detail** (no email provider): note saying "Order confirmation emails aren't being sent. Set up an email provider to send them automatically."
- **Dashboard checklist**: always shows outstanding items regardless of skips

Principle: explain what's missing, link to the fix, one instance per context.

**Files:** `lib/berrypod_web/live/admin/dashboard.ex`, `lib/berrypod_web/live/shop/` (various), `lib/berrypod_web/components/`

### F. Dashboard checklist and messaging

Rework the dashboard checklist to match the guided setup flow:

- **Before setup complete:** "Your admin account has been created. Continue the full setup below." with checklist of outstanding items
- **After all steps done and site live:** "Your shop is live! Ready to go"
- Checklist item names match the setup wizard step names exactly (no mismatches)
- Each checklist item links to its admin settings page (for when they return outside the wizard)
- Help/FAQ links next to items involving API keys or complicated config
- Collapsible rather than dismissable (can always get it back)
- Shipping setup and shop settings as additional checklist items (carried forward from v1 plan)

**Files:** `lib/berrypod_web/live/admin/dashboard.ex`, `lib/berrypod/setup.ex`

### G. Coming soon page fixes

- Fix logo displaying oddly to the side
- Add a subtle "Admin login" link (footer or corner)

**Files:** `lib/berrypod_web/live/shop/coming_soon.ex`, associated template

### H. External links UX

All links to external services throughout the app get:
- `target="_blank"` + `rel="noopener noreferrer"`
- Small external-link icon
- Aria label indicating it opens in a new window

**Files:** templates throughout `lib/berrypod_web/`

### I. Input styling — WCAG compliance

Increase input field border contrast to meet WCAG AA (3:1 minimum for UI components), aim for AAA. Clear, visible field edges in all contexts.

**Files:** `assets/css/admin/components.css`, `assets/css/shop/` CSS files

## Task breakdown

| # | Task | Est | Status |
|---|------|-----|--------|
| A | Simplify initial setup to account creation only | 1.5h | done |
| B | Guided setup flow with progress bar | 4h | done |
| C | Forgiving API key validation | 1.5h | done |
| D | Email provider setup UX rework | 2h | done |
| E | Contextual prompts for skipped steps | 2h | done |
| F | Dashboard checklist and messaging rework | 2h | done |
| G | Coming soon page fixes (logo + admin link) | 30m | done |
| H | External links UX (new tabs, icons, aria) | 1h | done |
| I | Input styling — WCAG compliance | 1h | done |

Total estimate: ~15.5h

## Suggested order

1. **A** first — simplify the entry point
2. **B** — the big piece, the guided flow
3. **C** — validation improvements (can be done alongside B)
4. **D** — email provider UX (part of the guided flow)
5. **F** — dashboard checklist rework (depends on the flow being defined)
6. **E** — contextual prompts (depends on knowing what's skippable)
7. **G, H, I** — smaller fixes, can be done any time
