add legal page editor integration and media library polish
Some checks failed
deploy / deploy (push) Has been cancelled
Some checks failed
deploy / deploy (push) Has been cancelled
Legal pages (privacy, delivery, terms) now auto-populate content from shop settings on mount, show auto-generated vs customised badges, and have a regenerate button. Theme editor gains alt text fields for logo, header, and icon images. Image picker in page builder now has an upload button and alt text warning badges. Clearing unused image references shows an orphan info flash. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -285,6 +285,36 @@ defmodule BerrypodWeb.Admin.Theme.Index do
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("update_image_alt", %{"image-id" => image_id, "alt" => alt}, socket) do
|
||||
case Media.get_image(image_id) do
|
||||
nil ->
|
||||
{:noreply, socket}
|
||||
|
||||
image ->
|
||||
{:ok, updated} = Media.update_image_metadata(image, %{alt: alt})
|
||||
|
||||
# Refresh the relevant assign so the template sees the new alt text
|
||||
socket =
|
||||
cond do
|
||||
socket.assigns.logo_image && socket.assigns.logo_image.id == image_id ->
|
||||
assign(socket, :logo_image, updated)
|
||||
|
||||
socket.assigns.header_image && socket.assigns.header_image.id == image_id ->
|
||||
assign(socket, :header_image, updated)
|
||||
|
||||
socket.assigns[:icon_image] && socket.assigns.icon_image &&
|
||||
socket.assigns.icon_image.id == image_id ->
|
||||
assign(socket, :icon_image, updated)
|
||||
|
||||
true ->
|
||||
socket
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("remove_logo", _params, socket) do
|
||||
if logo = socket.assigns.logo_image do
|
||||
|
||||
@@ -172,6 +172,29 @@
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<form
|
||||
phx-change="update_image_alt"
|
||||
phx-value-image-id={@logo_image.id}
|
||||
class="mt-2"
|
||||
>
|
||||
<label class="flex items-center gap-2">
|
||||
<span class="text-xs text-base-content/60 shrink-0">Alt text</span>
|
||||
<input
|
||||
type="text"
|
||||
name="alt"
|
||||
value={@logo_image.alt || ""}
|
||||
placeholder="Describe this image"
|
||||
class="admin-input admin-input-sm flex-1"
|
||||
phx-debounce="blur"
|
||||
/>
|
||||
</label>
|
||||
<p
|
||||
:if={!@logo_image.alt || @logo_image.alt == ""}
|
||||
class="text-xs text-warning mt-1"
|
||||
>
|
||||
Missing alt text — add a description for accessibility
|
||||
</p>
|
||||
</form>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -449,6 +472,29 @@
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<form
|
||||
phx-change="update_image_alt"
|
||||
phx-value-image-id={@header_image.id}
|
||||
class="mt-2"
|
||||
>
|
||||
<label class="flex items-center gap-2">
|
||||
<span class="text-xs text-base-content/60 shrink-0">Alt text</span>
|
||||
<input
|
||||
type="text"
|
||||
name="alt"
|
||||
value={@header_image.alt || ""}
|
||||
placeholder="Describe this image"
|
||||
class="admin-input admin-input-sm flex-1"
|
||||
phx-debounce="blur"
|
||||
/>
|
||||
</label>
|
||||
<p
|
||||
:if={!@header_image.alt || @header_image.alt == ""}
|
||||
class="text-xs text-warning mt-1"
|
||||
>
|
||||
Missing alt text — add a description for accessibility
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<!-- Header Image Controls -->
|
||||
<div class="mt-3 flex flex-col gap-3">
|
||||
|
||||
Reference in New Issue
Block a user