From 74ab6411f75d3a9269e2bec387f27b07c345317b Mon Sep 17 00:00:00 2001 From: jamey Date: Sun, 8 Mar 2026 23:09:51 +0000 Subject: [PATCH] add unified on-site editing mode plan Co-Authored-By: Claude Opus 4.5 --- PROGRESS.md | 26 ++- docs/plans/unified-editing-mode.md | 270 +++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 14 deletions(-) create mode 100644 docs/plans/unified-editing-mode.md diff --git a/PROGRESS.md b/PROGRESS.md index 83aaa30..65925bc 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -81,23 +81,20 @@ Replaced floating toast/flash messages with inline feedback and persistent top b | 6 | Migrate setup wizard notifications | 1h | done | | 7 | Remove old flash/toast CSS and JS | 30m | done | -### Live site editor ([plan](docs/plans/live-site-editor.md)) +### Unified on-site editing ([plan](docs/plans/unified-editing-mode.md)) -On-site editing overlay for admins: browse the real shop with a sidebar for theme and page editing. Inline contenteditable for text, live CSS variable injection for theme changes. Responsive layout (split view on desktop, overlay on mobile). +Extend the existing page editor (PageEditorHook + editor_sheet) to include theme editing. Admin clicks "Theme" → taken to actual shop with a 3-tab panel (Page | Theme | Settings). See changes live on the real site instead of a fake preview. | Phase | Description | Est | Status | |---|---|---|---| -| 1 | Design: sketch approaches, pick one | 2h | planned | -| 2 | Extract shared components from theme editor and page editor | 4h | planned | -| 3 | Build editor wrapper LiveView with sidebar shell | 3h | planned | -| 4 | Theme editing in sidebar (re-use theme controls, live CSS vars) | 3h | planned | -| 5 | Block list and block settings in sidebar | 3h | planned | -| 6 | Block selection: click-to-select with highlight on page | 2h | planned | -| 7 | Inline text editing with contenteditable + phx-hook | 4h | planned | -| 8 | Responsive layout (split view / overlay) | 2h | planned | -| 9 | Save/discard/undo flow | 2h | planned | -| 10 | Edit mode toggle (floating button for admins on shop pages) | 1h | planned | -| 11 | Polish and testing | 4h | planned | +| 1 | Add theme editing state to PageEditorHook | 2h | planned | +| 2 | Add 3-tab UI to editor panel (Page/Theme/Settings) | 2h | planned | +| 3 | Extract theme editor into reusable component | 3h | planned | +| 3b | Create settings editor component | 2h | planned | +| 4 | Image upload handling in hook context | 2h | planned | +| 5 | URL-based mode activation (?edit=theme) | 1h | planned | +| 6 | Admin routing redirect | 30m | planned | +| 7 | Polish and testing | 2h | planned | ### Quick fixes (from usability testing) @@ -149,6 +146,7 @@ All plans in [docs/plans/](docs/plans/). Completed plans are kept as architectur | [url-redirects.md](docs/plans/url-redirects.md) | Complete | | [onboarding-ux.md](docs/plans/onboarding-ux.md) | Planned (v2) | | [notification-overhaul.md](docs/plans/notification-overhaul.md) | Planned | -| [live-site-editor.md](docs/plans/live-site-editor.md) | Design exploration | +| [live-site-editor.md](docs/plans/live-site-editor.md) | Superseded by unified-editing-mode | +| [unified-editing-mode.md](docs/plans/unified-editing-mode.md) | Planned | | [profit-aware-pricing.md](docs/plans/profit-aware-pricing.md) | Planned | | [security-hardening.md](docs/plans/security-hardening.md) | Planned | diff --git a/docs/plans/unified-editing-mode.md b/docs/plans/unified-editing-mode.md new file mode 100644 index 0000000..08fe112 --- /dev/null +++ b/docs/plans/unified-editing-mode.md @@ -0,0 +1,270 @@ +# Unified On-Site Editing Mode + +Status: Planned + +Replace the separate admin theme editor (`/admin/theme`) with an on-site editing experience. When the admin clicks "Theme" or "Edit page", they're taken to the actual shop where a sliding panel allows them to edit either page content or theme settings — seeing changes live on the real site. + +## Current Architecture + +The codebase already has a robust pattern for on-site editing via the **PageEditorHook**: + +- `PageEditorHook` attaches to all shop pages, initializing ~15 editor-related assigns +- `editor_sheet` component in `ShopComponents.Layout` renders a FAB + sliding panel +- `PageRenderer` conditionally renders editor UI when `@is_admin` is true +- Changes preview instantly; state persists across the session + +The theme editor currently lives at `/admin/theme` with its own LiveView and fake preview. + +## Approach + +**Extend the existing editor infrastructure** to support both page editing and theme editing: + +1. Add theme editing state to the existing hook system +2. Add a tab switcher to the editor panel (Page | Theme | Settings) +3. Extract theme editor UI into a reusable component +4. Route `/admin/theme` to shop homepage with `?edit=theme` param + +## User Flow + +1. Admin clicks "Theme" in admin sidebar → redirects to `/?edit=theme` +2. Shop homepage loads with theme editing panel open +3. Admin can switch between "Page", "Theme", and "Settings" tabs +4. Admin can navigate to other shop pages while keeping editor open +5. "Done" or "×" button returns to admin or closes panel + +## Files to Modify + +| File | Change | +|------|--------| +| `lib/berrypod_web/page_editor_hook.ex` | Add theme/settings editing assigns, tab state, event handlers | +| `lib/berrypod_web/page_renderer.ex` | Add tab UI to editor_sheet, dispatch to theme/page/settings content | +| `lib/berrypod_web/components/shop_components/layout.ex` | Update editor_sheet for 3-tab support, add new keys to layout_keys | +| `lib/berrypod_web/components/shop_components/theme_editor.ex` | **New** - Extracted theme editor panel component | +| `lib/berrypod_web/components/shop_components/settings_editor.ex` | **New** - Page/shop settings panel component | +| `lib/berrypod_web/router.ex` | Redirect /admin/theme to /?edit=theme | +| `assets/css/shop/editor.css` | **New** - Editor panel styling (extract from admin) | +| `assets/js/hooks/theme_editor.js` | **New** - ColorSync and other theme editor hooks | + +## Implementation + +### Phase 1: Theme Editor Hook Integration + +Add theme editing state to `PageEditorHook`: + +```elixir +# New assigns in on_mount +:theme_editing -> false +:theme_settings -> nil (loaded when theme_editing activates) +:theme_active_preset -> nil +:theme_logo_image -> nil +:theme_header_image -> nil +:theme_icon_image -> nil +:theme_contrast_warning -> :ok +:theme_customise_open -> false + +# New event handlers +"theme_*" events -> handled by attach_hook similar to editor_* events +``` + +### Phase 2: Editor Panel Tabs + +Add three tabs to the editor panel: + +| Tab | Content | When available | +|-----|---------|----------------| +| **Page** | Block editor for custom pages | Only on editable pages (home, about, custom CMS pages) | +| **Theme** | Global styles, mood, typography, branding | Always | +| **Settings** | Page-specific settings (SEO, slug) or global shop settings | Always (content varies by page) | + +Update `editor_sheet` component: + +```heex +
+ + + +
+ +<%= case @editor_active_tab do %> + <% :page -> %> + <.editor_sheet_content ... /> + <% :theme -> %> + <.theme_editor_content ... /> + <% :settings -> %> + <.settings_editor_content ... /> +<% end %> +``` + +**Settings tab content varies by context:** +- On custom CMS pages: Page title, slug, SEO (meta title, description) +- On product pages: Read-only product info, link to admin product editor +- On collection pages: Collection settings, link to admin +- Global fallback: Shop name, description, favicon settings + +### Phase 3: Extract Theme Editor Component + +Create `lib/berrypod_web/components/shop_components/theme_editor.ex`: + +- Extract the sidebar content from current `/admin/theme` template +- Reuse same event names (`update_setting`, `toggle_setting`, `apply_preset`, etc.) +- Support image uploads via `allow_upload` passed from hook + +Key sections to extract: +- Presets grid +- Mood/typography/shape/density selectors +- Logo upload + settings +- Header background upload + settings +- Accent color pickers +- Customise accordion (advanced settings) + +### Phase 3b: Create Settings Editor Component + +Create `lib/berrypod_web/components/shop_components/settings_editor.ex`: + +**Content varies by page type:** + +| Page type | Settings shown | +|-----------|---------------| +| Custom CMS page | Page title, slug, visibility, SEO meta | +| Home page | Shop name, description, SEO defaults | +| Product page | Read-only product name, link to admin product editor | +| Collection page | Read-only collection name, link to admin | +| Cart/checkout | Shop policies, checkout settings link | + +**Common sections:** +- Page SEO (meta title, description, social image) +- Favicon settings (short name, icon upload) +- Shop identity (name, description) + +### Phase 4: Image Upload Handling + +Image uploads need special handling since we're in a hook, not a LiveView: + +Option A: **Delegate to the parent LiveView** +- Pass `@uploads` from the LiveView through assigns +- Hook events trigger upload handling in the LiveView +- Cleanest approach, matches existing pattern + +Option B: **Use a LiveComponent for uploads** +- Wrap upload sections in a stateful LiveComponent +- Component handles its own uploads +- More isolated but adds complexity + +**Recommended: Option A** — follow the pattern the page editor already uses. + +### Phase 5: URL-Based Mode Activation + +Handle `?edit=theme` query param: + +```elixir +# In PageEditorHook handle_params hook +defp handle_params_hook(params, _uri, socket) do + socket = + case params["edit"] do + "theme" -> enter_theme_edit_mode(socket) + "page" -> enter_page_edit_mode(socket) + _ -> socket + end + {:cont, socket} +end +``` + +### Phase 6: Admin Routing + +Update router to redirect theme link: + +```elixir +# In admin scope, redirect /admin/theme to shop +get "/theme", Plug.Redirect, to: "/?edit=theme" +``` + +Or keep the admin theme page as a fallback/redirect: + +```elixir +live "/theme", Admin.Theme.Redirect # Simple LiveView that redirects +``` + +## State Management + +**Theme editing state persists across navigation** via hook attach: + +- `attach_hook(:theme_params, :handle_params, &handle_params_hook/3)` tracks URL +- Theme settings stored in socket assigns +- CSS regenerated and assigned to `@generated_css` on each change +- ThemeHook already loads CSS; we just update the assign + +**Dirty tracking:** +- Theme changes save immediately (current behavior) OR +- Add "unsaved" state like page editor (better UX but more work) + +**Recommendation:** Keep immediate save for now (it's the existing behavior and simpler). + +## CSS Considerations + +The editor panel uses admin CSS classes. Options: + +1. **Extract shared styles** into `shop/editor.css` loaded on all shop pages +2. **Namespace admin styles** so they work in shop context +3. **Use inline styles** (not recommended) + +**Recommended:** Create `assets/css/shop/editor.css` with editor panel styles, include it in shop layout when `@is_admin`. + +## What Happens to /admin/theme? + +Options: +1. **Remove it entirely** — redirects to `/?edit=theme` +2. **Keep as fallback** — simple page that redirects or links to on-site editor +3. **Keep for non-visual settings** — things like favicon short name, SEO defaults + +**Recommended:** Redirect to `/?edit=theme` for now. Can always add back a minimal settings page later if needed. + +## Verification + +1. Click "Theme" in admin → lands on shop homepage with theme panel open +2. Change mood → see colors update instantly on real site +3. Upload logo → appears in real header immediately +4. Navigate to product page → theme panel stays open +5. Switch to "Page" tab on homepage → shows page block editor +6. Switch to "Page" tab on product page → tab disabled (no editable blocks) +7. Click "Done" → returns to admin dashboard +8. Mobile: panel slides up from bottom, fully usable + +## Phased Rollout + +### MVP (Phases 1-3) +- Theme editing works on-site +- Basic tab UI (Page | Theme | Settings) +- All current theme settings functional +- No image uploads yet (use existing images) + +### Full Feature (Phases 4-6) +- Image uploads working +- URL-based mode activation +- Admin redirect in place +- Polish and edge cases + +## Future Enhancements (Not in Scope) + +- Undo/redo for theme changes +- "Preview without saving" mode +- Theme presets preview before applying +- Multi-page preview from single location