Render all adapter field sections in the form with CSS :has(:checked) controlling visibility. Selecting a provider instantly shows its config fields — no JS, no page reload, no server round-trip needed. - Render all 6 adapter configs with data-adapter attribute - CSS :has(:checked) show/hide rules per adapter in admin stylesheet - Namespace field names per adapter (email[brevo][api_key] etc) - Drop 4 transactional-only providers (Resend, Postmark, Mailgun, MailPace) - Remove noscript "Switch provider" button and controller redirect workaround - Remove configured_adapter hidden input tracking - Hide JS-only test email button for no-JS users via noscript style - LiveView progressively enhances with async save and test email Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9.2 KiB
Onboarding UX v2
Status: In progress
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
- 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. - Dashboard checklist (
lib/berrypod_web/live/admin/dashboard.ex): 5 items with progress bar. Visible whensite_liveis false and not dismissed. - Coming soon page: blocks public access before launch.
- Setup status (
lib/berrypod/setup.ex):setup_status/0returns 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:
- Connect print provider — allow connecting multiple providers (not forced to pick just one). "Skip for now" available.
- Connect Stripe for payments — "Skip for now" available.
- 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/0and 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_orsk_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-selectedclass 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 | planned |
| B | Guided setup flow with progress bar | 4h | planned |
| C | Forgiving API key validation | 1.5h | planned |
| D | Email provider setup UX rework | 2h | done |
| E | Contextual prompts for skipped steps | 2h | done |
| F | Dashboard checklist and messaging rework | 2h | planned |
| G | Coming soon page fixes (logo + admin link) | 30m | planned |
| H | External links UX (new tabs, icons, aria) | 1h | planned |
| I | Input styling — WCAG compliance | 1h | planned |
Total estimate: ~15.5h
Suggested order
- A first — simplify the entry point
- B — the big piece, the guided flow
- C — validation improvements (can be done alongside B)
- D — email provider UX (part of the guided flow)
- F — dashboard checklist rework (depends on the flow being defined)
- E — contextual prompts (depends on knowing what's skippable)
- G, H, I — smaller fixes, can be done any time