berrypod/docs/plans/editor-reorganisation.md
jamey 5a5103bc42
Some checks failed
deploy / deploy (push) Failing after 10m12s
update docs for completed social links editor
- Mark tasks 1-9 and 15-16 as done in editor-reorganisation plan
- Update plan status from Planned to In Progress
- Add implementation notes documenting social links architecture
- Update test count to 1800+ in PROGRESS.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-28 10:13:03 +00:00

14 KiB
Raw Blame History

Editor Panel Reorganisation

Status: In Progress

Problem

The current 3-tab editor panel (Page | Theme | Settings) has gaps and unintuitive organisation:

  1. Missing functionality — can't edit announcement bar text, social links, header/footer nav, footer about text
  2. Scattered concerns — shop name is in Theme (visual design) but it's business info; navigation settings are spread across multiple places
  3. Settings tab is underused — on system/product pages it's essentially read-only with links elsewhere

Vision

A user editing their shop should find everything in a logical place based on what they're trying to do:

  • "I want to change what's on this page" → Page tab
  • "I want to change how my site looks" → Theme tab
  • "I want to change site-wide content" → Site tab

Proposed Structure

Page tab (content on this specific page)

For all pages:

  • Block editor (add, reorder, duplicate, delete, edit)
  • Undo/redo

For custom CMS pages only (inline, not separate Settings tab):

  • Page title
  • URL slug
  • Meta description
  • Published toggle
  • Show in navigation toggle
  • Navigation label & position (if show_in_nav)

For system pages:

  • Block editor only (title/slug not editable)
  • "Reset to defaults" for resettable pages

For product/collection pages:

  • Read-only info with link to admin

Theme tab (visual design — how it looks)

Keep existing structure but remove shop name and logo (move to Site tab):

Quick settings:

  • Preset grid (8 themes)
  • Accent colour, hover colour, sale colour

Advanced (Customise accordion):

  • Typography: font style, size, heading weight
  • Colours: mood (warm, neutral, cool, dark)
  • Layout: grid columns, density, header layout, sticky header
  • Shape: corners, shadows, button style
  • Products: content width, image aspect, text alignment, hover image, show prices
  • Product page: trust badges, reviews, related products

Site tab (site-wide content — what appears everywhere)

New tab replacing "Settings". Contains everything that appears on every page:

Branding:

  • Shop name
  • Logo (upload, show/hide, size, recolour, colour)
  • Favicon (upload)
  • Header background image (upload, zoom, position)

Announcement bar:

  • Show announcement bar (toggle)
  • Announcement text (NEW — currently hardcoded)
  • Announcement link URL (optional)
  • Announcement style (info, sale, warning)

Header navigation:

  • Editable list of nav items
  • Each item: label, link (page picker or URL), position
  • "Add nav item" button

Footer:

  • About text (NEW — the footer blurb)
  • Copyright text (NEW — currently auto-generated)
  • Show newsletter signup (toggle)

Footer navigation:

  • Editable list of footer nav items ("Help" section)
  • Each item: label, link, position

Social links:

  • Editable list of social links (NEW)
  • Each link: platform (dropdown), URL
  • Reorder via drag or arrows

Data Model Changes

New fields in Settings

# Announcement bar
:announcement_text, :string, default: ""
:announcement_link, :string, default: ""
:announcement_style, :string, default: "info"  # info | sale | warning

# Footer content
:footer_about, :string, default: ""
:footer_copyright, :string, default: ""  # empty = auto-generate
:show_newsletter, :boolean, default: true
schema "social_links" do
  field :platform, :string  # instagram, bluesky, mastodon, twitter, youtube, tiktok, etc.
  field :url, :string
  field :position, :integer
  timestamps()
end

New schema: NavItem

schema "nav_items" do
  field :location, :string  # "header" | "footer"
  field :label, :string
  field :url, :string  # can be relative (/about) or absolute
  field :page_id, :binary_id  # optional, links to a Page
  field :position, :integer
  timestamps()
end

Migration Path

Phase 1: Data model + Site tab skeleton (3h)

  1. Add new Settings fields (announcement_text, footer_about, etc.)
  2. Create SocialLink schema and migration
  3. Create NavItem schema and migration
  4. Seed default nav items from current hardcoded values
  5. Seed default social links from current hardcoded values
  6. Create Site tab component (skeleton)

Phase 2: Announcement bar (1.5h)

  1. Add announcement text/link/style inputs to Site tab
  2. Update shop header to read from Settings instead of hardcoded
  3. Style variants for info/sale/warning
  1. Add social links editor to Site tab (list with add/remove/reorder)
  2. Platform dropdown with icons
  3. Update footer to read from SocialLink table
  4. Delete hardcoded social links

Phase 4: Navigation editors (3h)

  1. Add header nav editor to Site tab
  2. Add footer nav editor to Site tab
  3. Page picker component (dropdown of published pages)
  4. Update header/footer to read from NavItem table
  5. Delete hardcoded nav arrays
  1. Add footer about text input
  2. Add copyright text input (with placeholder showing auto-generated)
  3. Add newsletter toggle
  4. Update footer component to use these values

Phase 6: Move branding from Theme to Site (1.5h)

  1. Move shop name input to Site tab
  2. Move logo settings to Site tab
  3. Move favicon settings to Site tab
  4. Move header background settings to Site tab
  5. Update Theme tab to remove these sections
  6. Ensure Theme tab still feels complete (may need UI polish)

Phase 7: Merge Settings into Page (1h)

  1. For custom pages: move title/slug/meta/published/nav settings inline into Page tab
  2. Remove Settings tab entirely
  3. Update tab switching logic

Phase 8: Polish and testing (2h)

  1. Responsive design for Site tab
  2. Empty states
  3. Validation and error handling
  4. Test all combinations (custom page, system page, product page, collection)
  5. Update onboarding/help text if needed

Task Breakdown

# Task Depends Est Status
1 Data model: new Settings fields + migrations 1h done
2 Data model: SocialLink schema + seed defaults 1 45m done
3 Data model: NavItem schema + seed defaults 1 45m done
4 Site tab skeleton component 1 30m done
5 Announcement bar: editor UI 4 45m done
6 Announcement bar: read from Settings 5 30m done
7 Announcement bar: style variants 6 15m done
8 Social links: editor UI (list, add, remove, reorder) 4 1.5h done
9 Social links: read from database 8 30m done
10 Header nav: editor UI 4 1h planned
11 Header nav: page picker component 10 30m planned
12 Header nav: read from database 11 30m planned
13 Footer nav: editor UI 10 30m planned
14 Footer nav: read from database 13 30m planned
15 Footer content: about, copyright, newsletter toggle 4 45m done
16 Footer: read new fields 15 30m done
17 Move branding settings from Theme to Site 4 1h planned
18 Theme tab: remove branding, polish remaining 17 30m planned
19 Merge page settings into Page tab 45m planned
20 Remove Settings tab 19 15m planned
21 Polish: responsive, empty states, validation 1-20 1.5h planned
22 Testing: all page types, edge cases 21 30m planned

Total estimate: ~15h

Implementation Notes

The social links feature supports 40+ platforms grouped into 9 categories:

  • Social (Instagram, Threads, TikTok, Facebook, Twitter, Snapchat, LinkedIn)
  • Video & streaming (YouTube, Twitch, Vimeo, Kick, Rumble)
  • Music & podcasts (Spotify, SoundCloud, Bandcamp, Apple Podcasts)
  • Creative (Pinterest, Behance, Dribbble, Tumblr, Medium)
  • Support & sales (Patreon, Ko-fi, Etsy, Gumroad, Substack)
  • Federated (Mastodon, Pixelfed, Bluesky, PeerTube, Lemmy, Matrix)
  • Developer (GitHub, GitLab, Codeberg, SourceHut, Reddit)
  • Messaging (Discord, Telegram, Signal, WhatsApp)
  • Other (Linktree, RSS, Website, Custom)

URL handling:

  • normalize_url/1 trims whitespace and adds https:// to bare domains
  • Preserves existing protocols (http://, https://, app deep links like tg://, spotify:)
  • Preserves other URI schemes (mailto:, tel:, rss://)

Platform detection:

  • detect_platform/1 auto-detects platform from pasted URLs
  • Works with scheme-based detection (e.g., tg:// → telegram, spotify: → spotify)
  • Works with host-based detection (e.g., github.com → github, bsky.app → bluesky)
  • Handles subdomain patterns (e.g., artist.bandcamp.com → bandcamp)
  • Returns "custom" for unknown domains

Data flow:

  • Database → Site.list_social_links/0 → raw structs
  • Shop display → Site.social_links_for_shop/0 → filtered (no empty URLs), formatted maps
  • Editor preview → format_social_links_for_shop/1 in layout.ex → same filtering
  • Social links card block now uses database data via assigns[:social_links]

Files:

  • lib/berrypod/site.ex - Site context with social links CRUD
  • lib/berrypod/site/social_link.ex - Schema, URL normalization, platform detection
  • lib/berrypod_web/components/shop_components/site_editor.ex - Editor UI
  • lib/berrypod_web/page_editor_hook.ex - Event handlers
  • test/berrypod/site_test.exs - 35 tests covering all functionality

UI Wireframes

Site tab layout

┌─────────────────────────────────────┐
│ [Page] [Theme] [Site]               │  ← tabs
├─────────────────────────────────────┤
│                                     │
│ ▼ Branding                          │  ← collapsible section
│   Shop name: [____________]         │
│   Logo: [Upload] [Remove]           │
│   □ Show logo  □ Show shop name     │
│   Logo size: ●────────○ 48px        │
│   □ Recolour logo                   │
│   Favicon: [Upload]                 │
│                                     │
│ ▼ Announcement bar                  │
│   □ Show announcement bar           │
│   Text: [Free shipping over £50___] │
│   Link: [/delivery______________]   │
│   Style: ○ Info  ● Sale  ○ Warning  │
│                                     │
│ ▼ Header navigation                 │
│   ┌─────────────────────────────┐   │
│   │ Shop        /products    ↕ │   │
│   │ About       /about       ↕ │   │
│   │ Contact     /contact     ↕ │   │
│   └─────────────────────────────┘   │
│   [+ Add nav item]                  │
│                                     │
│ ▼ Footer                            │
│   About text:                       │
│   [Handmade with love in London___] │
│   [_______________________________] │
│   Copyright: [________________]     │
│   (Leave blank for "© 2026 Shop")   │
│   □ Show newsletter signup          │
│                                     │
│ ▼ Footer navigation                 │
│   ┌─────────────────────────────┐   │
│   │ Delivery    /delivery    ↕ │   │
│   │ Returns     /returns     ↕ │   │
│   │ Privacy     /privacy     ↕ │   │
│   └─────────────────────────────┘   │
│   [+ Add nav item]                  │
│                                     │
│ ▼ Social links                      │
│   ┌─────────────────────────────┐   │
│   │ 📷 Instagram  @myshop    ↕ │   │
│   │ 🦋 Bluesky    @my.bsky   ↕ │   │
│   │ ☕ Ko-fi      /myshop    ↕ │   │
│   └─────────────────────────────┘   │
│   [+ Add social link]               │
│                                     │
└─────────────────────────────────────┘

Page tab with inline settings (custom page)

┌─────────────────────────────────────┐
│ [Page] [Theme] [Site]               │
├─────────────────────────────────────┤
│                                     │
│ ▼ Page settings                     │  ← new section for custom pages
│   Title: [About Us_______________]  │
│   URL: berrypod.com/[about_______]  │
│   Meta description:                 │
│   [Learn about our story...______]  │
│   □ Published                       │
│   □ Show in navigation              │
│                                     │
│ ▼ Content blocks                    │
│   [Hero block]              [↑][↓][×]│
│   [Text block]              [↑][↓][×]│
│   [Image block]             [↑][↓][×]│
│   [+ Add block]                     │
│                                     │
│   [↩ Undo] [↪ Redo]                 │
│                                     │
└─────────────────────────────────────┘

Open Questions

  1. Should header/footer nav support nested items (dropdowns)? — Probably not for v1, keep it flat.

  2. Should social links include "custom" option? — Yes, allow custom label + URL for platforms we don't have icons for.

  3. What happens to existing hardcoded nav when we migrate? — Seed the database with current values, delete hardcoded arrays.

  4. Should announcement bar support scheduling? — Defer to profit-aware-pricing plan (task 71) which already includes this.

  5. Should we keep the Settings tab for "advanced" page settings? — No, inline is simpler. Power users can use admin pages panel.