format refactored admin templates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey 2026-03-01 19:39:56 +00:00
parent 867a69109e
commit 22d3e36ed5
4 changed files with 160 additions and 54 deletions

View File

@ -205,7 +205,10 @@ defmodule BerrypodWeb.Admin.Newsletter do
</div> </div>
<button <button
phx-click="toggle_enabled" phx-click="toggle_enabled"
class={["admin-switch", if(@newsletter_enabled, do: "admin-switch-on", else: "admin-switch-off")]} class={[
"admin-switch",
if(@newsletter_enabled, do: "admin-switch-on", else: "admin-switch-off")
]}
role="switch" role="switch"
aria-checked={to_string(@newsletter_enabled)} aria-checked={to_string(@newsletter_enabled)}
aria-label="Toggle newsletter signups" aria-label="Toggle newsletter signups"
@ -231,10 +234,18 @@ defmodule BerrypodWeb.Admin.Newsletter do
</div> </div>
<div class="admin-row" style="--admin-row-gap: 0.75rem;"> <div class="admin-row" style="--admin-row-gap: 0.75rem;">
<.link navigate={~p"/admin/newsletter?tab=subscribers"} class="admin-link" style="font-weight: 500;"> <.link
navigate={~p"/admin/newsletter?tab=subscribers"}
class="admin-link"
style="font-weight: 500;"
>
View subscribers View subscribers
</.link> </.link>
<.link navigate={~p"/admin/newsletter?tab=campaigns"} class="admin-link" style="font-weight: 500;"> <.link
navigate={~p"/admin/newsletter?tab=campaigns"}
class="admin-link"
style="font-weight: 500;"
>
View campaigns View campaigns
</.link> </.link>
</div> </div>
@ -328,7 +339,9 @@ defmodule BerrypodWeb.Admin.Newsletter do
<div :if={@subscriber_count == 0} class="admin-empty-state"> <div :if={@subscriber_count == 0} class="admin-empty-state">
<.icon name="hero-envelope" class="admin-empty-state-icon" /> <.icon name="hero-envelope" class="admin-empty-state-icon" />
<p class="admin-empty-state-title">No subscribers yet</p> <p class="admin-empty-state-title">No subscribers yet</p>
<p class="admin-empty-state-text">Subscribers will appear here when people sign up via your shop.</p> <p class="admin-empty-state-text">
Subscribers will appear here when people sign up via your shop.
</p>
</div> </div>
</div> </div>
""" """

View File

@ -48,7 +48,10 @@ defmodule BerrypodWeb.Admin.OrderShow do
</div> </div>
</.header> </.header>
<div class="admin-grid" style="--admin-grid-min: 20rem; --admin-grid-gap: 1.5rem; margin-top: 1.5rem;"> <div
class="admin-grid"
style="--admin-grid-min: 20rem; --admin-grid-gap: 1.5rem; margin-top: 1.5rem;"
>
<%!-- order info --%> <%!-- order info --%>
<div class="admin-card"> <div class="admin-card">
<div class="admin-card-body"> <div class="admin-card-body">

View File

@ -593,7 +593,12 @@ defmodule BerrypodWeb.Admin.Settings do
<p class="admin-section-desc" style="margin-top: 0;"> <p class="admin-section-desc" style="margin-top: 0;">
To accept payments, connect your Stripe account by entering your secret key. To accept payments, connect your Stripe account by entering your secret key.
You can find it in your You can find it in your
<a href="https://dashboard.stripe.com/apikeys" target="_blank" rel="noopener" class="admin-link"> <a
href="https://dashboard.stripe.com/apikeys"
target="_blank"
rel="noopener"
class="admin-link"
>
Stripe dashboard Stripe dashboard
</a> </a>
under Developers &rarr; API keys. under Developers &rarr; API keys.
@ -631,7 +636,9 @@ defmodule BerrypodWeb.Admin.Settings do
</div> </div>
<div class="admin-dl-row"> <div class="admin-dl-row">
<dt class="admin-dl-term">Webhook URL</dt> <dt class="admin-dl-term">Webhook URL</dt>
<dd class="admin-dl-value"><code style="font-size: 0.75rem; word-break: break-all;">{@stripe_webhook_url}</code></dd> <dd class="admin-dl-value">
<code style="font-size: 0.75rem; word-break: break-all;">{@stripe_webhook_url}</code>
</dd>
</div> </div>
<div class="admin-dl-row"> <div class="admin-dl-row">
<dt class="admin-dl-term">Webhook secret</dt> <dt class="admin-dl-term">Webhook secret</dt>
@ -670,7 +677,11 @@ defmodule BerrypodWeb.Admin.Settings do
</.form> </.form>
<% else %> <% else %>
<div style="border-top: 1px solid var(--t-surface-sunken); padding-top: 0.75rem;"> <div style="border-top: 1px solid var(--t-surface-sunken); padding-top: 0.75rem;">
<button phx-click="toggle_stripe_advanced" class="admin-link-subtle admin-row" style="--admin-row-gap: 0.25rem;"> <button
phx-click="toggle_stripe_advanced"
class="admin-link-subtle admin-row"
style="--admin-row-gap: 0.25rem;"
>
<.icon <.icon
name={if @advanced_open, do: "hero-chevron-down-mini", else: "hero-chevron-right-mini"} name={if @advanced_open, do: "hero-chevron-down-mini", else: "hero-chevron-right-mini"}
class="size-4" class="size-4"

View File

@ -37,7 +37,7 @@
<.link href={~p"/admin"} class="theme-back-link"> <.link href={~p"/admin"} class="theme-back-link">
<.icon name="hero-arrow-left-mini" class="size-4" /> Admin <.icon name="hero-arrow-left-mini" class="size-4" /> Admin
</.link> </.link>
<!-- Header --> <!-- Header -->
<div class="theme-header"> <div class="theme-header">
<div style="flex: 1;"> <div style="flex: 1;">
@ -67,7 +67,7 @@
</svg> </svg>
</button> </button>
</div> </div>
<!-- Site Name --> <!-- Site Name -->
<div class="theme-field" style="margin-bottom: 1.5rem;"> <div class="theme-field" style="margin-bottom: 1.5rem;">
<label class="theme-section-label">Shop name</label> <label class="theme-section-label">Shop name</label>
@ -82,11 +82,11 @@
/> />
</form> </form>
</div> </div>
<!-- Branding Section --> <!-- Branding Section -->
<div class="theme-panel"> <div class="theme-panel">
<label class="theme-section-label" style="margin-bottom: 1rem;">Logo & header</label> <label class="theme-section-label" style="margin-bottom: 1rem;">Logo & header</label>
<!-- Logo Mode Radio Cards --> <!-- Logo Mode Radio Cards -->
<div class="admin-stack" style="--admin-stack-gap: 0.5rem; margin-bottom: 1rem;"> <div class="admin-stack" style="--admin-stack-gap: 0.5rem; margin-bottom: 1rem;">
<%= for {value, title, desc} <- [ <%= for {value, title, desc} <- [
@ -131,7 +131,7 @@
</label> </label>
<% end %> <% end %>
</div> </div>
<!-- Logo Upload (for logo-text and logo-only modes) --> <!-- Logo Upload (for logo-text and logo-only modes) -->
<%= if @theme_settings.logo_mode in ["logo-text", "logo-only"] do %> <%= if @theme_settings.logo_mode in ["logo-text", "logo-only"] do %>
<div class="theme-subsection"> <div class="theme-subsection">
@ -215,10 +215,14 @@
<%= for err <- upload_errors(@uploads.logo_upload) do %> <%= for err <- upload_errors(@uploads.logo_upload) do %>
<p class="theme-error-text">{error_to_string(err)}</p> <p class="theme-error-text">{error_to_string(err)}</p>
<% end %> <% end %>
<!-- Logo Size Slider --> <!-- Logo Size Slider -->
<%= if @logo_image do %> <%= if @logo_image do %>
<form phx-change="update_setting" phx-value-field="logo_size" style="margin-top: 0.75rem;"> <form
phx-change="update_setting"
phx-value-field="logo_size"
style="margin-top: 0.75rem;"
>
<div class="theme-slider-header"> <div class="theme-slider-header">
<span class="theme-slider-label">Logo size</span> <span class="theme-slider-label">Logo size</span>
<span class="theme-slider-value">{@theme_settings.logo_size}px</span> <span class="theme-slider-value">{@theme_settings.logo_size}px</span>
@ -233,7 +237,7 @@
style="width: 100%;" style="width: 100%;"
/> />
</form> </form>
<!-- SVG Recolor Toggle (only for SVG logos) --> <!-- SVG Recolor Toggle (only for SVG logos) -->
<%= if @logo_image.is_svg do %> <%= if @logo_image.is_svg do %>
<div style="margin-top: 0.75rem;"> <div style="margin-top: 0.75rem;">
@ -275,14 +279,14 @@
</div> </div>
<% end %> <% end %>
</div> </div>
<!-- Site Icon / Favicon --> <!-- Site Icon / Favicon -->
<div class="theme-panel"> <div class="theme-panel">
<label class="theme-section-label">Site icon</label> <label class="theme-section-label">Site icon</label>
<p class="admin-text-tertiary" style="margin-bottom: 1rem;"> <p class="admin-text-tertiary" style="margin-bottom: 1rem;">
Your icon appears in browser tabs and on home screens. Your icon appears in browser tabs and on home screens.
</p> </p>
<!-- Use logo as icon toggle --> <!-- Use logo as icon toggle -->
<label class="admin-toggle-label" style="margin-bottom: 1rem;"> <label class="admin-toggle-label" style="margin-bottom: 1rem;">
<input <input
@ -294,7 +298,7 @@
/> />
<span class="theme-slider-label">Use logo as favicon</span> <span class="theme-slider-label">Use logo as favicon</span>
</label> </label>
<!-- Icon upload (only when not using logo) --> <!-- Icon upload (only when not using logo) -->
<%= if !@theme_settings.use_logo_as_icon do %> <%= if !@theme_settings.use_logo_as_icon do %>
<div style="padding-top: 0.75rem; border-top: 1px solid var(--t-border-default);"> <div style="padding-top: 0.75rem; border-top: 1px solid var(--t-border-default);">
@ -363,7 +367,7 @@
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
<!-- Short name --> <!-- Short name -->
<div class="theme-subsection" style="padding-top: 0.75rem;"> <div class="theme-subsection" style="padding-top: 0.75rem;">
<form phx-change="update_setting" phx-value-field="favicon_short_name"> <form phx-change="update_setting" phx-value-field="favicon_short_name">
@ -381,7 +385,7 @@
/> />
</form> </form>
</div> </div>
<!-- Icon background colour --> <!-- Icon background colour -->
<div style="margin-top: 0.75rem;"> <div style="margin-top: 0.75rem;">
<form <form
@ -406,7 +410,7 @@
</form> </form>
</div> </div>
</div> </div>
<!-- Header Background Toggle --> <!-- Header Background Toggle -->
<div style="margin-bottom: 1.5rem;"> <div style="margin-bottom: 1.5rem;">
<label class="admin-toggle-label"> <label class="admin-toggle-label">
@ -425,7 +429,7 @@
</span> </span>
</label> </label>
</div> </div>
<!-- Header Image Upload (only when enabled) --> <!-- Header Image Upload (only when enabled) -->
<%= if @theme_settings.header_background_enabled do %> <%= if @theme_settings.header_background_enabled do %>
<div class="theme-panel"> <div class="theme-panel">
@ -478,7 +482,7 @@
Missing alt text — add a description for accessibility Missing alt text — add a description for accessibility
</p> </p>
</form> </form>
<!-- Header Image Controls --> <!-- Header Image Controls -->
<div class="admin-stack" style="--admin-stack-gap: 0.75rem; margin-top: 0.75rem;"> <div class="admin-stack" style="--admin-stack-gap: 0.75rem; margin-top: 0.75rem;">
<form phx-change="update_setting" phx-value-field="header_zoom"> <form phx-change="update_setting" phx-value-field="header_zoom">
@ -559,7 +563,7 @@
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
<!-- Presets Section --> <!-- Presets Section -->
<div style="margin-bottom: 1.5rem;"> <div style="margin-bottom: 1.5rem;">
<label class="theme-section-label">Start with a preset</label> <label class="theme-section-label">Start with a preset</label>
@ -580,7 +584,7 @@
<% end %> <% end %>
</div> </div>
</div> </div>
<!-- Accent Colors --> <!-- Accent Colors -->
<div style="margin-bottom: 1.5rem;"> <div style="margin-bottom: 1.5rem;">
<label class="theme-section-label">Accent colour</label> <label class="theme-section-label">Accent colour</label>
@ -644,7 +648,7 @@
</div> </div>
</form> </form>
</div> </div>
<!-- Customise Section --> <!-- Customise Section -->
<details <details
class="theme-customise" class="theme-customise"
@ -668,7 +672,13 @@
<!-- Typography Group --> <!-- Typography Group -->
<div class="theme-group"> <div class="theme-group">
<div class="theme-group-header"> <div class="theme-group-header">
<svg class="theme-group-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg
class="theme-group-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polyline points="4 7 4 4 20 4 20 7"></polyline> <polyline points="4 7 4 4 20 4 20 7"></polyline>
<line x1="9" y1="20" x2="15" y2="20"></line> <line x1="9" y1="20" x2="15" y2="20"></line>
<line x1="12" y1="4" x2="12" y2="20"></line> <line x1="12" y1="4" x2="12" y2="20"></line>
@ -685,7 +695,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="typography" phx-value-field="typography"
phx-value-setting_value={typo} phx-value-setting_value={typo}
class={["theme-chip", @theme_settings.typography == typo && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.typography == typo && "theme-chip-active"
]}
> >
{typo} {typo}
</button> </button>
@ -702,7 +715,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="font_size" phx-value-field="font_size"
phx-value-setting_value={value} phx-value-setting_value={value}
class={["theme-chip", @theme_settings.font_size == value && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.font_size == value && "theme-chip-active"
]}
> >
{label} {label}
</button> </button>
@ -719,7 +735,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="heading_weight" phx-value-field="heading_weight"
phx-value-setting_value={value} phx-value-setting_value={value}
class={["theme-chip", @theme_settings.heading_weight == value && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.heading_weight == value && "theme-chip-active"
]}
> >
{label} {label}
</button> </button>
@ -727,11 +746,17 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Colours Group --> <!-- Colours Group -->
<div class="theme-group"> <div class="theme-group">
<div class="theme-group-header"> <div class="theme-group-header">
<svg class="theme-group-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg
class="theme-group-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="12" cy="12" r="10"></circle> <circle cx="12" cy="12" r="10"></circle>
<circle cx="12" cy="12" r="3"></circle> <circle cx="12" cy="12" r="3"></circle>
</svg> </svg>
@ -755,11 +780,17 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Layout Group --> <!-- Layout Group -->
<div class="theme-group"> <div class="theme-group">
<div class="theme-group-header"> <div class="theme-group-header">
<svg class="theme-group-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg
class="theme-group-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
<line x1="3" y1="9" x2="21" y2="9"></line> <line x1="3" y1="9" x2="21" y2="9"></line>
<line x1="9" y1="21" x2="9" y2="9"></line> <line x1="9" y1="21" x2="9" y2="9"></line>
@ -776,7 +807,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="grid_columns" phx-value-field="grid_columns"
phx-value-setting_value={cols} phx-value-setting_value={cols}
class={["theme-chip", @theme_settings.grid_columns == cols && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.grid_columns == cols && "theme-chip-active"
]}
> >
{cols} columns {cols} columns
</button> </button>
@ -793,7 +827,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="density" phx-value-field="density"
phx-value-setting_value={density} phx-value-setting_value={density}
class={["theme-chip", @theme_settings.density == density && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.density == density && "theme-chip-active"
]}
> >
{density} {density}
</button> </button>
@ -810,7 +847,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="header_layout" phx-value-field="header_layout"
phx-value-setting_value={layout} phx-value-setting_value={layout}
class={["theme-chip", @theme_settings.header_layout == layout && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.header_layout == layout && "theme-chip-active"
]}
> >
{layout} {layout}
</button> </button>
@ -844,11 +884,17 @@
</label> </label>
</div> </div>
</div> </div>
<!-- Shape Group --> <!-- Shape Group -->
<div style="margin-bottom: 1rem;"> <div style="margin-bottom: 1rem;">
<div class="theme-group-header"> <div class="theme-group-header">
<svg class="theme-group-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg
class="theme-group-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
</svg> </svg>
<span class="theme-group-title">Shape</span> <span class="theme-group-title">Shape</span>
@ -880,7 +926,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="card_shadow" phx-value-field="card_shadow"
phx-value-setting_value={value} phx-value-setting_value={value}
class={["theme-chip", @theme_settings.card_shadow == value && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.card_shadow == value && "theme-chip-active"
]}
> >
{label} {label}
</button> </button>
@ -897,7 +946,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="button_style" phx-value-field="button_style"
phx-value-setting_value={value} phx-value-setting_value={value}
class={["theme-chip", @theme_settings.button_style == value && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.button_style == value && "theme-chip-active"
]}
> >
{label} {label}
</button> </button>
@ -905,11 +957,17 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Products Group --> <!-- Products Group -->
<div class="theme-group"> <div class="theme-group">
<div class="theme-group-header"> <div class="theme-group-header">
<svg class="theme-group-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg
class="theme-group-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="3" width="7" height="7"></rect> <rect x="3" y="3" width="7" height="7"></rect>
<rect x="14" y="3" width="7" height="7"></rect> <rect x="14" y="3" width="7" height="7"></rect>
<rect x="14" y="14" width="7" height="7"></rect> <rect x="14" y="14" width="7" height="7"></rect>
@ -927,7 +985,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="layout_width" phx-value-field="layout_width"
phx-value-setting_value={width} phx-value-setting_value={width}
class={["theme-chip", @theme_settings.layout_width == width && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.layout_width == width && "theme-chip-active"
]}
> >
{width} {width}
</button> </button>
@ -944,7 +1005,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="image_aspect_ratio" phx-value-field="image_aspect_ratio"
phx-value-setting_value={value} phx-value-setting_value={value}
class={["theme-chip", @theme_settings.image_aspect_ratio == value && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.image_aspect_ratio == value && "theme-chip-active"
]}
> >
{label} {label}
</button> </button>
@ -961,7 +1025,10 @@
phx-click="update_setting" phx-click="update_setting"
phx-value-field="product_text_align" phx-value-field="product_text_align"
phx-value-setting_value={value} phx-value-setting_value={value}
class={["theme-chip", @theme_settings.product_text_align == value && "theme-chip-active"]} class={[
"theme-chip",
@theme_settings.product_text_align == value && "theme-chip-active"
]}
> >
{label} {label}
</button> </button>
@ -995,11 +1062,17 @@
</label> </label>
</div> </div>
</div> </div>
<!-- Product Page Group --> <!-- Product Page Group -->
<div style="margin-bottom: 1rem;"> <div style="margin-bottom: 1rem;">
<div class="theme-group-header"> <div class="theme-group-header">
<svg class="theme-group-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg
class="theme-group-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
<line x1="3" y1="9" x2="21" y2="9"></line> <line x1="3" y1="9" x2="21" y2="9"></line>
</svg> </svg>
@ -1047,7 +1120,7 @@
</div> </div>
</div> </div>
</details> </details>
<!-- Current Combination Display --> <!-- Current Combination Display -->
<div class="theme-combination"> <div class="theme-combination">
<div class="theme-combination-label">Current combination</div> <div class="theme-combination-label">Current combination</div>
@ -1066,7 +1139,7 @@
</div> </div>
<% end %> <% end %>
</div> </div>
<!-- Preview Area --> <!-- Preview Area -->
<div class="theme-preview-area"> <div class="theme-preview-area">
<div class="theme-preview-container"> <div class="theme-preview-container">
@ -1097,7 +1170,7 @@
</button> </button>
<% end %> <% end %>
</div> </div>
<!-- Browser Chrome --> <!-- Browser Chrome -->
<div class="theme-browser-chrome"> <div class="theme-browser-chrome">
<div class="theme-browser-dots"> <div class="theme-browser-dots">
@ -1106,7 +1179,13 @@
<div class="theme-browser-dot theme-browser-dot-max"></div> <div class="theme-browser-dot theme-browser-dot-max"></div>
</div> </div>
<div class="theme-browser-url"> <div class="theme-browser-url">
<svg class="theme-browser-url-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg
class="theme-browser-url-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect> <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path> <path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg> </svg>
@ -1115,7 +1194,7 @@
</span> </span>
</div> </div>
</div> </div>
<!-- Preview Frame --> <!-- Preview Frame -->
<div <div
class="themed theme-preview-frame" class="themed theme-preview-frame"