update notification overhaul plan
All checks were successful
deploy / deploy (push) Successful in 37s
All checks were successful
deploy / deploy (push) Successful in 37s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c6636cab65
commit
dbcecc7878
@ -6,138 +6,317 @@ Replace floating toast/flash notifications with inline feedback and persistent t
|
|||||||
|
|
||||||
## Current state
|
## Current state
|
||||||
|
|
||||||
Phoenix flash messages shown as floating toasts. 110+ flash messages across 28 files (65 info, 45+ error). Auto-dismiss after a few seconds. Overlay existing UI content.
|
144 `put_flash` calls across the codebase (59 `:info`, 34 `:error`, rest multi-line). Two separate toast implementations:
|
||||||
|
|
||||||
|
- **Admin** (`core_components.ex` → `.admin-toast`): fixed top-right, 20rem wide, click to dismiss via `JS.push("lv:clear-flash")` + `JS.hide`
|
||||||
|
- **Shop** (`shop_components/content.ex` → `.shop-flash`): fixed top-right, theme-aware, CSS slide-in, click anywhere to dismiss
|
||||||
|
|
||||||
|
Both are overlays — fixed-position, outside document flow, disappear on click.
|
||||||
|
|
||||||
|
**Existing inline patterns** already in the codebase:
|
||||||
|
- `<.error>` component — red text below form fields (`.admin-error`) via changeset errors
|
||||||
|
- Static `.admin-alert` boxes — persistent info/error in auth/setup pages
|
||||||
|
- `.admin-checklist-banner` — contextual "back to checklist" banners
|
||||||
|
- `.admin-banner-warning` — full-width warning banner (email settings)
|
||||||
|
|
||||||
|
**Top files by flash count:** settings.ex (17), onboarding.ex (9), campaign_form.ex (9), pages/editor.ex (8), theme/index.ex (6), media.ex (6)
|
||||||
|
|
||||||
## New approach: two layers
|
## New approach: two layers
|
||||||
|
|
||||||
### 1. Inline feedback (primary)
|
### 1. Inline feedback (contextual)
|
||||||
|
|
||||||
Contextual to the field or action. Persistent until the state changes.
|
Feedback next to the field or action that triggered it. Persistent until state changes.
|
||||||
|
|
||||||
- **Success:** green tick/label next to the saved field or action area. E.g. "Saved" next to a settings field after change.
|
- **Success:** green tick + "Saved" label next to save button. Auto-clears after 3s (LiveView only).
|
||||||
- **Error:** red border on the field + error text below it. Stays visible until fixed. Bold, clearly coloured, impossible to miss — same visual weight as validation errors.
|
- **Error:** red border on field + error text below. Stays until fixed. Works identically with and without JS (changeset errors re-render the form).
|
||||||
- **Loading/progress:** subtle indicator while an async action is in-flight (e.g. "Syncing..." next to sync button).
|
- **Loading:** subtle spinner + "Saving..." / "Syncing..." while an async action is in-flight.
|
||||||
|
|
||||||
Best for: form saves, field validation, toggle changes, individual actions.
|
Best for: form saves, field validation, toggle changes, individual actions.
|
||||||
|
|
||||||
### 2. Top banner (page-level confirmations)
|
### 2. Top banner (page-level)
|
||||||
|
|
||||||
For actions that affect the whole page or aren't tied to a specific field.
|
For outcomes not tied to a specific field.
|
||||||
|
|
||||||
- Bold, clearly coloured background: green for success, red for errors, amber for warnings
|
- Full-width coloured bar: green (success), red (error), amber (warning)
|
||||||
- Non-overlapping: pushes content down (not an overlay)
|
- **Document flow** — pushes content down, not an overlay
|
||||||
- **Persistent until manually dismissed** (click to close) — no auto-dismiss, because users may be looking elsewhere
|
- **Persistent until dismissed** (close button). No auto-dismiss.
|
||||||
- Clear close button (x icon)
|
- Positioned at top of content area, below header/nav
|
||||||
- Positioned at top of the content area, below the header/nav
|
|
||||||
|
|
||||||
Best for: "Products synced successfully", "Page saved", "Email provider connected", navigation-result confirmations, operation outcomes.
|
Best for: "Products synced", "Page deleted", auth messages, operation outcomes.
|
||||||
|
|
||||||
### 3. No floating toasts
|
### 3. No floating toasts
|
||||||
|
|
||||||
Remove the floating toast pattern entirely. Between inline feedback and top banners, every use case is covered with better UX.
|
The fixed-position overlay toast pattern is removed entirely.
|
||||||
|
|
||||||
## Migration plan
|
## Progressive enhancement
|
||||||
|
|
||||||
|
| Scenario | No JS (controller POST → redirect) | With JS (LiveView) |
|
||||||
|
|----------|-------------------------------------|---------------------|
|
||||||
|
| Save success | Banner via flash (PRG redirect) | Inline "Saved" tick next to button |
|
||||||
|
| Validation error | Inline field errors (controller re-renders form with changeset) | Inline field errors (LiveView validates on change/submit) |
|
||||||
|
| Page-level outcome | Banner via flash | Banner via flash |
|
||||||
|
| Connection lost | N/A (no WebSocket) | Banner via `phx-disconnected` |
|
||||||
|
|
||||||
|
Banners are the baseline that works everywhere. Inline feedback is a progressive enhancement on top — LiveView pages get richer feedback, but no-JS pages still get inline validation errors via changeset re-rendering and success banners via flash.
|
||||||
|
|
||||||
|
## Component spec
|
||||||
|
|
||||||
|
### `<.banner>` — replaces `<.flash>`
|
||||||
|
|
||||||
|
Reuses the existing flash infrastructure. Migration path: change CSS + move position in layout. Zero LiveView code changes needed — all 144 `put_flash` calls continue working.
|
||||||
|
|
||||||
|
**Layout change** (admin):
|
||||||
|
```heex
|
||||||
|
<%!-- Move from AFTER the layout div (current line 228) to INSIDE .admin-layout-content, above <main> --%>
|
||||||
|
<div class="admin-layout-content">
|
||||||
|
<header class="admin-topbar">...</header>
|
||||||
|
<.flash_group flash={@flash} /> <%!-- NEW POSITION --%>
|
||||||
|
<main class="admin-main">...</main>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Component change** (`core_components.ex`):
|
||||||
|
```heex
|
||||||
|
<%!-- Change wrapper class from .admin-toast (fixed position) to .admin-banner (document flow) --%>
|
||||||
|
<div :if={msg = ...} id={@id} class="admin-banner" ...>
|
||||||
|
<div class={["admin-banner-inner", kind_class(@kind)]}>
|
||||||
|
<icon /> <p>{msg}</p> <close button />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
**CSS** (evolves from existing `.admin-banner-warning`):
|
||||||
|
```css
|
||||||
|
/* replaces .admin-toast (fixed position) */
|
||||||
|
.admin-banner {
|
||||||
|
/* document flow, no position: fixed */
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-banner-inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-banner-info {
|
||||||
|
background: color-mix(in oklch, var(--t-status-info) 12%, var(--t-surface-base));
|
||||||
|
color: var(--t-status-info);
|
||||||
|
border-bottom: 1px solid color-mix(in oklch, var(--t-status-info) 25%, var(--t-surface-base));
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-banner-error {
|
||||||
|
background: color-mix(in oklch, var(--t-status-error) 12%, var(--t-surface-base));
|
||||||
|
color: var(--t-status-error);
|
||||||
|
border-bottom: 1px solid color-mix(in oklch, var(--t-status-error) 25%, var(--t-surface-base));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .admin-banner-warning already exists and matches this pattern */
|
||||||
|
```
|
||||||
|
|
||||||
|
**No-JS**: Works perfectly. Banner is HTML in document flow — displays without JS. Close button uses `phx-click` so without LiveView the banner stays visible (desired — persistent by design). Flash clears naturally on next navigation.
|
||||||
|
|
||||||
|
**Shop layout**: Same treatment — move `<.shop_flash_group>` from fixed overlay to document flow inside the content area.
|
||||||
|
|
||||||
|
### `<.inline_feedback>` — new component
|
||||||
|
|
||||||
|
Lightweight status indicator placed next to a button or form section.
|
||||||
|
|
||||||
|
**Component** (`core_components.ex`):
|
||||||
|
```elixir
|
||||||
|
attr :status, :atom, values: [:idle, :saving, :saved, :error], default: :idle
|
||||||
|
attr :message, :string, default: nil
|
||||||
|
|
||||||
|
def inline_feedback(assigns) do
|
||||||
|
~H"""
|
||||||
|
<span
|
||||||
|
:if={@status != :idle}
|
||||||
|
class={["admin-inline-feedback", "admin-inline-feedback-#{@status}"]}
|
||||||
|
role={@status == :error && "alert"}
|
||||||
|
>
|
||||||
|
<.icon :if={@status == :saving} name="hero-arrow-path" class="size-4 motion-safe:animate-spin" />
|
||||||
|
<.icon :if={@status == :saved} name="hero-check" class="size-4" />
|
||||||
|
<.icon :if={@status == :error} name="hero-exclamation-circle" class="size-4" />
|
||||||
|
<span>{feedback_text(@status, @message)}</span>
|
||||||
|
</span>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp feedback_text(:saving, _), do: "Saving..."
|
||||||
|
defp feedback_text(:saved, nil), do: "Saved"
|
||||||
|
defp feedback_text(:saved, msg), do: msg
|
||||||
|
defp feedback_text(:error, nil), do: "Something went wrong"
|
||||||
|
defp feedback_text(:error, msg), do: msg
|
||||||
|
defp feedback_text(:idle, _), do: nil
|
||||||
|
```
|
||||||
|
|
||||||
|
**CSS**:
|
||||||
|
```css
|
||||||
|
.admin-inline-feedback {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-inline-feedback-saving {
|
||||||
|
color: var(--admin-text-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-inline-feedback-saved {
|
||||||
|
color: var(--t-status-success, oklch(0.55 0.15 145));
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-inline-feedback-error {
|
||||||
|
color: var(--t-status-error);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage pattern** (LiveView):
|
||||||
|
```elixir
|
||||||
|
# Mount
|
||||||
|
assign(socket, save_status: :idle, save_error: nil)
|
||||||
|
|
||||||
|
# Save handler
|
||||||
|
def handle_event("save", params, socket) do
|
||||||
|
case Context.save(params) do
|
||||||
|
{:ok, _} ->
|
||||||
|
Process.send_after(self(), :clear_save_status, 3000)
|
||||||
|
{:noreply, assign(socket, :save_status, :saved)}
|
||||||
|
{:error, reason} ->
|
||||||
|
{:noreply, assign(socket, save_status: :error, save_error: reason)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info(:clear_save_status, socket) do
|
||||||
|
{:noreply, assign(socket, :save_status, :idle)}
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**Template**:
|
||||||
|
```heex
|
||||||
|
<div class="admin-form-actions">
|
||||||
|
<.button type="submit" variant="primary">Save</.button>
|
||||||
|
<.inline_feedback status={@save_status} message={@save_error} />
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connection error handling
|
||||||
|
|
||||||
|
The `client-error` and `server-error` flashes (LiveView disconnect/reconnect) become banners too. Suppress them during intentional navigation to avoid a brief flash on refresh:
|
||||||
|
|
||||||
|
**JS** (`app.js`):
|
||||||
|
```js
|
||||||
|
window.addEventListener("beforeunload", () => {
|
||||||
|
document.body.classList.add("navigating-away")
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**CSS**:
|
||||||
|
```css
|
||||||
|
.navigating-away #flash-group { display: none; }
|
||||||
|
```
|
||||||
|
|
||||||
|
`beforeunload` fires on refresh/navigation but NOT on genuine connection drops, so the banner still shows when actually needed.
|
||||||
|
|
||||||
|
## Migration categories
|
||||||
|
|
||||||
### Category 1: Form saves → inline feedback
|
### Category 1: Form saves → inline feedback
|
||||||
|
|
||||||
These should become contextual inline confirmations near the action:
|
| Current flash | Location | Replacement |
|
||||||
|
|
||||||
| Current flash | Location | Inline replacement |
|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| "Theme saved successfully" | Theme editor | Green tick next to save button, brief "Saved" label |
|
| "Theme saved successfully" | Theme editor | Inline "Saved" tick next to save button |
|
||||||
| "Email settings saved" | Email settings | Green tick/label near save area |
|
| "Email settings saved" | Email settings | Inline "Saved" tick near save |
|
||||||
| "Settings saved" | Provider form | Green tick near save |
|
| "Settings saved" | Provider form | Inline "Saved" tick near save |
|
||||||
| "Navigation saved" | Navigation editor | Green tick near save |
|
| "Navigation saved" | Navigation editor | Inline "Saved" tick near save |
|
||||||
| "Page settings saved" | Page editor | Green tick near save |
|
| "Page settings saved" | Page editor | Inline "Saved" tick near save |
|
||||||
| "Metadata updated" | Media library | Green tick on the metadata form |
|
| "Metadata updated" | Media library | Inline "Saved" tick on metadata form |
|
||||||
| "Product updated" | Product show | Green tick near the field that changed |
|
| "Product updated" | Product show | Inline "Saved" tick near changed field |
|
||||||
|
|
||||||
### Category 2: Validation errors → inline field errors
|
### Category 2: Validation errors → inline field errors
|
||||||
|
|
||||||
Already partially in place via changesets, but some are flash-based:
|
These flash-based validation messages become proper inline field errors. Works with and without JS — controller re-renders form with changeset errors, LiveView validates on change.
|
||||||
|
|
||||||
| Current flash | Location | Inline replacement |
|
| Current flash | Location | Replacement |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| "Please enter your API token" | Setup wizard | Red border + error text on the API key field |
|
| "Please enter your API token" | Setup wizard | Red border + error on API key field |
|
||||||
| "Missing required fields: {labels}" | Email settings | Red border on each missing field |
|
| "Missing required fields: {labels}" | Email settings | Red border on each missing field |
|
||||||
| "Please enter your Stripe secret key" | Settings | Red border + error on the Stripe key field |
|
| "Please enter your Stripe secret key" | Settings | Red border + error on Stripe key field |
|
||||||
| "Please fill in all required fields" | Contact form | Red border on each empty required field |
|
| "Please fill in all required fields" | Contact form | Red border on each empty required field |
|
||||||
| "Please enter a valid email address" | Newsletter | Red border + error on email field |
|
| "Please enter a valid email address" | Newsletter | Red border + error on email field |
|
||||||
| "Please enter your email address" | Various | Red border + error on email field |
|
|
||||||
| "Password must be at least 12 characters" | Setup recover | Red border + error on password field |
|
| "Password must be at least 12 characters" | Setup recover | Red border + error on password field |
|
||||||
| "Please enter a shop name" / "email address" | Setup | Red border on the relevant field |
|
| "Please enter a shop name" / "email" | Setup | Red border on relevant field |
|
||||||
|
|
||||||
### Category 3: State changes → top banner
|
### Category 3: State changes → top banner
|
||||||
|
|
||||||
These are page-level outcomes, best as persistent top banners:
|
Page-level outcomes, kept as `put_flash` → render as banner instead of toast:
|
||||||
|
|
||||||
| Current flash | Location | Banner replacement |
|
| Current flash | Location |
|
||||||
|---|---|---|
|
|---|---|
|
||||||
| "Shop is now live" / "Shop taken offline" | Settings | Green/amber banner at top of settings |
|
| "Shop is now live" / "Shop taken offline" | Settings |
|
||||||
| "Connected to {provider}!" | Provider form | Green banner on the provider page |
|
| "Connected to {provider}!" | Provider form |
|
||||||
| "Email provider disconnected" | Email settings | Amber banner |
|
| "Email provider disconnected" | Email settings |
|
||||||
| "Stripe connected and webhook endpoint created" | Settings | Green banner |
|
| "Stripe connected and webhook endpoint created" | Settings |
|
||||||
| "Provider connection deleted" | Providers index | Green banner |
|
| "Provider connection deleted" | Providers index |
|
||||||
| "Page saved" | Page editor | Green banner |
|
| "Page deleted" / "Page created" | Pages index |
|
||||||
| "Page deleted" / "Page created" | Pages index | Green banner |
|
|
||||||
|
|
||||||
### Category 4: Operation outcomes → top banner
|
### Category 4: Operation outcomes → top banner
|
||||||
|
|
||||||
Async or significant operations:
|
| Current flash | Location |
|
||||||
|
|---|---|
|
||||||
|
| "Sync started for {name}" | Providers/settings |
|
||||||
|
| "Connected! Product sync started in the background." | Setup |
|
||||||
|
| "Submission retry enqueued" | Activity log |
|
||||||
|
| "Image uploaded" / "Image deleted" | Media library |
|
||||||
|
| "Campaign is being sent!" | Newsletter |
|
||||||
|
| "Test email sent to {email}" | Email settings |
|
||||||
|
| "Message sent! We'll get back to you soon." | Contact |
|
||||||
|
|
||||||
| Current flash | Location | Banner replacement |
|
### Category 5: Auth/system → top banner
|
||||||
|---|---|---|
|
|
||||||
| "Sync started for {name}" | Providers/settings | Green banner with progress note |
|
|
||||||
| "Connected! Product sync started in the background." | Setup | Green banner |
|
|
||||||
| "Submission retry enqueued" | Activity log | Green banner |
|
|
||||||
| "Image uploaded" / "Image deleted" | Media library | Green banner |
|
|
||||||
| "Campaign is being sent!" | Newsletter | Green banner |
|
|
||||||
| "Test email sent to {email}" | Email settings | Green banner |
|
|
||||||
| "Added to basket" | Shop cart | Inline: brief confirmation near the add button or cart icon update |
|
|
||||||
| "Removed from basket" | Shop cart | Inline: item visually removed, no separate message needed |
|
|
||||||
| "Message sent! We'll get back to you soon." | Contact | Green banner above the form (or replace form with success state) |
|
|
||||||
|
|
||||||
### Category 5: Auth/system messages → top banner (keep as-is pattern)
|
| Current flash | Location |
|
||||||
|
|---|---|
|
||||||
|
| "Welcome back!" | Dashboard |
|
||||||
|
| "Logged out successfully" | Login page |
|
||||||
|
| "Invalid email or password" | Login (could be inline under form) |
|
||||||
|
| "User confirmed successfully" | Email confirm |
|
||||||
|
|
||||||
These are inherently page-level and work fine as top banners:
|
### Category 6: Cart feedback → inline
|
||||||
|
|
||||||
| Current flash | Location | Notes |
|
|
||||||
|---|---|---|
|
|
||||||
| "Welcome back!" | Login redirect | Green banner on dashboard |
|
|
||||||
| "Logged out successfully" | Post-logout | Green banner on login page |
|
|
||||||
| "Invalid email or password" | Login | Could be inline under the form, or red banner |
|
|
||||||
| "User confirmed successfully" | Email confirm | Green banner |
|
|
||||||
| "Your basket is empty" | Checkout | Redirect + banner or inline empty state |
|
|
||||||
|
|
||||||
### Category 6: Error/failure messages → inline or banner
|
|
||||||
|
|
||||||
| Current flash | Replacement |
|
| Current flash | Replacement |
|
||||||
|---|---|
|
|---|---|
|
||||||
| "Could not connect — check your API key" | Inline error on the API key field + help link |
|
| "Added to basket" | Brief inline confirmation near add button / cart icon badge update |
|
||||||
| "Stripe connection failed: {message}" | Inline error near Stripe key field |
|
| "Removed from basket" | Item visually removed, no separate message |
|
||||||
| "Failed to send test email: {reason}" | Inline error near the test email button |
|
|
||||||
| "Upload failed" | Inline error near the upload area |
|
|
||||||
| "Cannot delete — image is still in use" | Red banner with explanation |
|
|
||||||
| "Something went wrong. Please try again." | Red banner |
|
|
||||||
|
|
||||||
## Implementation
|
## Implementation plan
|
||||||
|
|
||||||
### Phase 1: Build the notification components
|
### Phase 1: Build components (~2h)
|
||||||
|
|
||||||
1. **Inline feedback component** — reusable component that shows success/error state next to any action. Props: status (success/error/loading), message, auto-clear timing (optional, for success only after state persists).
|
Build both components. Convert flash rendering from toast to banner. No behaviour changes — all existing `put_flash` calls work, just render differently.
|
||||||
2. **Top banner component** — replaces the current flash component. Pushes content down, persistent until dismissed, coloured by type.
|
|
||||||
3. **Remove** the existing floating toast CSS/JS.
|
|
||||||
|
|
||||||
### Phase 2: Migrate admin forms (highest impact)
|
1. Restyle `<.flash>` from `.admin-toast` (fixed) to `.admin-banner` (document flow)
|
||||||
|
2. Move `<.flash_group>` in admin layout from after the div to inside content area
|
||||||
|
3. Same for shop layout — restyle `.shop-flash` to document flow
|
||||||
|
4. Build `<.inline_feedback>` component in `core_components.ex`
|
||||||
|
5. Add `beforeunload` suppression for connection error banners
|
||||||
|
6. Delete old `.admin-toast` and `.shop-flash-group` (fixed-position) CSS
|
||||||
|
|
||||||
Start with the most-used admin pages:
|
### Phase 2: Migrate admin forms (~3h)
|
||||||
|
|
||||||
|
Replace `put_flash(:info, "Saved")` with inline feedback on the highest-traffic pages:
|
||||||
- Theme editor
|
- Theme editor
|
||||||
- Page editor
|
- Page editor
|
||||||
- Settings
|
- Settings
|
||||||
- Email settings
|
- Email settings
|
||||||
- Provider forms
|
- Provider forms
|
||||||
|
|
||||||
### Phase 3: Migrate remaining admin pages
|
Each migration: add `:save_status` assign, swap `put_flash` for `assign(:save_status, :saved)`, add `<.inline_feedback>` to template, add `Process.send_after` auto-clear.
|
||||||
|
|
||||||
|
### Phase 3: Migrate remaining admin pages (~2h)
|
||||||
|
|
||||||
- Media library
|
- Media library
|
||||||
- Products
|
- Products
|
||||||
@ -146,27 +325,25 @@ Start with the most-used admin pages:
|
|||||||
- Redirects
|
- Redirects
|
||||||
- Navigation
|
- Navigation
|
||||||
|
|
||||||
### Phase 4: Migrate shop pages
|
### Phase 4: Migrate shop pages (~2h)
|
||||||
|
|
||||||
- Cart (add/remove feedback)
|
- Cart (add/remove → inline feedback)
|
||||||
- Contact form
|
- Contact form (success → replace form with success state)
|
||||||
- Checkout errors
|
- Checkout errors
|
||||||
- Auth flows (login, registration, confirmation)
|
- Auth flows (login, registration, confirmation)
|
||||||
|
|
||||||
### Phase 5: Migrate setup wizard
|
### Phase 5: Migrate setup wizard (~1h)
|
||||||
|
|
||||||
Update the setup flow (ties into the onboarding-ux v2 plan).
|
Update setup flow — ties into onboarding-ux v2 plan. If onboarding tasks A/B are done first, this phase applies inline feedback to the new guided flow.
|
||||||
|
|
||||||
## Task breakdown
|
## Task breakdown
|
||||||
|
|
||||||
| # | Task | Est | Status |
|
| # | Task | Est | Status |
|
||||||
|---|------|-----|--------|
|
|---|------|-----|--------|
|
||||||
| 1 | Build inline feedback component | 1.5h | planned |
|
| 1 | Build banner + inline feedback components, restyle flash rendering | 2h | planned |
|
||||||
| 2 | Build persistent top banner component (replaces flash) | 1.5h | planned |
|
| 2 | Migrate admin forms (theme, pages, settings, email, providers) | 3h | planned |
|
||||||
| 3 | Migrate admin forms to inline feedback (theme, pages, settings, email, providers) | 3h | planned |
|
| 3 | Migrate remaining admin pages (media, products, activity, newsletter, redirects, nav) | 2h | planned |
|
||||||
| 4 | Migrate remaining admin pages (media, products, activity, newsletter, redirects, nav) | 2h | planned |
|
| 4 | Migrate shop pages (cart, contact, checkout, auth) | 2h | planned |
|
||||||
| 5 | Migrate shop pages (cart, contact, checkout, auth) | 2h | planned |
|
| 5 | Migrate setup wizard notifications | 1h | planned |
|
||||||
| 6 | Migrate setup wizard notifications | 1h | planned |
|
|
||||||
| 7 | Remove old flash/toast CSS and JS | 30m | planned |
|
|
||||||
|
|
||||||
Total estimate: ~11.5h
|
Total estimate: ~10h
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user