# Notification system overhaul Status: Planned Replace floating toast/flash notifications with inline feedback and persistent top banners. Based on usability testing (March 2026) — flash messages overlay UI, auto-dismiss means users miss them, and the overall pattern feels messy. ## 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. ## New approach: two layers ### 1. Inline feedback (primary) Contextual to the field or action. Persistent until the state changes. - **Success:** green tick/label next to the saved field or action area. E.g. "Saved" next to a settings field after change. - **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. - **Loading/progress:** subtle indicator while an async action is in-flight (e.g. "Syncing..." next to sync button). Best for: form saves, field validation, toggle changes, individual actions. ### 2. Top banner (page-level confirmations) For actions that affect the whole page or aren't tied to a specific field. - Bold, clearly coloured background: green for success, red for errors, amber for warnings - Non-overlapping: pushes content down (not an overlay) - **Persistent until manually dismissed** (click to close) — no auto-dismiss, because users may be looking elsewhere - Clear close button (x icon) - 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. ### 3. No floating toasts Remove the floating toast pattern entirely. Between inline feedback and top banners, every use case is covered with better UX. ## Migration plan ### Category 1: Form saves → inline feedback These should become contextual inline confirmations near the action: | Current flash | Location | Inline replacement | |---|---|---| | "Theme saved successfully" | Theme editor | Green tick next to save button, brief "Saved" label | | "Email settings saved" | Email settings | Green tick/label near save area | | "Settings saved" | Provider form | Green tick near save | | "Navigation saved" | Navigation editor | Green tick near save | | "Page settings saved" | Page editor | Green tick near save | | "Metadata updated" | Media library | Green tick on the metadata form | | "Product updated" | Product show | Green tick near the field that changed | ### Category 2: Validation errors → inline field errors Already partially in place via changesets, but some are flash-based: | Current flash | Location | Inline replacement | |---|---|---| | "Please enter your API token" | Setup wizard | Red border + error text on the API key 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 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 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 | | "Please enter a shop name" / "email address" | Setup | Red border on the relevant field | ### Category 3: State changes → top banner These are page-level outcomes, best as persistent top banners: | Current flash | Location | Banner replacement | |---|---|---| | "Shop is now live" / "Shop taken offline" | Settings | Green/amber banner at top of settings | | "Connected to {provider}!" | Provider form | Green banner on the provider page | | "Email provider disconnected" | Email settings | Amber banner | | "Stripe connected and webhook endpoint created" | Settings | Green banner | | "Provider connection deleted" | Providers index | Green banner | | "Page saved" | Page editor | Green banner | | "Page deleted" / "Page created" | Pages index | Green banner | ### Category 4: Operation outcomes → top banner Async or significant operations: | Current flash | Location | Banner replacement | |---|---|---| | "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) These are inherently page-level and work fine as top banners: | 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 | |---|---| | "Could not connect — check your API key" | Inline error on the API key field + help link | | "Stripe connection failed: {message}" | Inline error near Stripe key field | | "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 ### Phase 1: Build the notification components 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). 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) Start with the most-used admin pages: - Theme editor - Page editor - Settings - Email settings - Provider forms ### Phase 3: Migrate remaining admin pages - Media library - Products - Activity log - Newsletter - Redirects - Navigation ### Phase 4: Migrate shop pages - Cart (add/remove feedback) - Contact form - Checkout errors - Auth flows (login, registration, confirmation) ### Phase 5: Migrate setup wizard Update the setup flow (ties into the onboarding-ux v2 plan). ## Task breakdown | # | Task | Est | Status | |---|------|-----|--------| | 1 | Build inline feedback component | 1.5h | planned | | 2 | Build persistent top banner component (replaces flash) | 1.5h | planned | | 3 | Migrate admin forms to inline feedback (theme, pages, settings, email, providers) | 3h | planned | | 4 | Migrate remaining admin pages (media, products, activity, newsletter, redirects, nav) | 2h | planned | | 5 | Migrate shop pages (cart, contact, checkout, auth) | 2h | planned | | 6 | Migrate setup wizard notifications | 1h | planned | | 7 | Remove old flash/toast CSS and JS | 30m | planned | Total estimate: ~11.5h