add nav editors to Site tab with live preview
All checks were successful
deploy / deploy (push) Successful in 3m27s
All checks were successful
deploy / deploy (push) Successful in 3m27s
- Add header and footer nav editors to Site tab with drag-to-reorder, add/remove items, and destination picker (pages, collections, external) - Live preview updates as you edit nav items - Remove legacy /admin/navigation page and controller (was saving to Settings table, now uses nav_items table) - Update error_html.ex and pages/editor.ex to load nav from nav_items table - Update link_scanner to read from nav_items table, edit path now /?edit=site - Add Site.default_header_nav/0 and default_footer_nav/0 for previews/errors - Remove fallback logic from theme_hook.ex (database is now source of truth) - Seed default nav items and social links during setup Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -88,18 +88,23 @@ defmodule BerrypodWeb.ShopComponents.Layout do
|
||||
base = Map.take(assigns, @layout_keys)
|
||||
|
||||
# When site editor is active, use in-memory values for live preview
|
||||
# The site_* assigns are the editor's working copies, while announcement_*
|
||||
# and social_links are the database-loaded values from theme_hook
|
||||
# The site_state assigns is the editor's working copy, while announcement_*,
|
||||
# nav items, and social_links are the database-loaded values from theme_hook
|
||||
# Only override when site_editing is true (editor has loaded site state)
|
||||
if assigns[:site_editing] do
|
||||
# Convert raw SocialLink structs to shop format
|
||||
social_links = format_social_links_for_shop(assigns[:site_social_links] || [])
|
||||
if assigns[:site_editing] && assigns[:site_state] do
|
||||
state = assigns[:site_state]
|
||||
# Convert raw structs to shop format
|
||||
social_links = format_social_links_for_shop(state.social_links || [])
|
||||
header_nav = format_nav_items_for_shop(state.header_nav || [])
|
||||
footer_nav = format_nav_items_for_shop(state.footer_nav || [])
|
||||
|
||||
base
|
||||
|> Map.put(:announcement_text, assigns[:site_announcement_text])
|
||||
|> Map.put(:announcement_link, assigns[:site_announcement_link])
|
||||
|> Map.put(:announcement_style, assigns[:site_announcement_style])
|
||||
|> Map.put(:announcement_text, state.announcement_text)
|
||||
|> Map.put(:announcement_link, state.announcement_link)
|
||||
|> Map.put(:announcement_style, state.announcement_style)
|
||||
|> Map.put(:social_links, social_links)
|
||||
|> Map.put(:header_nav_items, header_nav)
|
||||
|> Map.put(:footer_nav_items, footer_nav)
|
||||
else
|
||||
base
|
||||
end
|
||||
@@ -122,6 +127,41 @@ defmodule BerrypodWeb.ShopComponents.Layout do
|
||||
end)
|
||||
end
|
||||
|
||||
# Convert raw NavItem structs to the format expected by shop components
|
||||
# Filters out items with empty labels (incomplete entries still being edited)
|
||||
defp format_nav_items_for_shop(items) do
|
||||
items
|
||||
|> Enum.reject(fn item -> is_nil(item.label) or item.label == "" end)
|
||||
|> Enum.map(fn item ->
|
||||
slug = extract_slug_from_url(item.url)
|
||||
|
||||
base = %{
|
||||
"label" => item.label,
|
||||
"href" => item.url,
|
||||
"slug" => slug
|
||||
}
|
||||
|
||||
# Add active_slugs for Shop nav item to highlight on collection and pdp pages
|
||||
if slug == "collection" do
|
||||
Map.put(base, "active_slugs", ["collection", "pdp"])
|
||||
else
|
||||
base
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
# Extract a slug from a URL for nav item matching
|
||||
defp extract_slug_from_url(url) when is_binary(url) do
|
||||
cond do
|
||||
url == "/" -> "home"
|
||||
String.starts_with?(url, "/collections") -> "collection"
|
||||
String.starts_with?(url, "/products") -> "pdp"
|
||||
true -> url |> String.trim_leading("/") |> String.split("/") |> List.first() || ""
|
||||
end
|
||||
end
|
||||
|
||||
defp extract_slug_from_url(_), do: ""
|
||||
|
||||
# Social
|
||||
defp platform_display_label("instagram"), do: "Instagram"
|
||||
defp platform_display_label("threads"), do: "Threads"
|
||||
|
||||
Reference in New Issue
Block a user