diff --git a/assets/css/admin/components.css b/assets/css/admin/components.css
index f8af23a..8f8854f 100644
--- a/assets/css/admin/components.css
+++ b/assets/css/admin/components.css
@@ -1384,6 +1384,11 @@
gap: 0.25rem;
}
+.setup-test-help {
+ margin: 0.375rem 0 0;
+ font-size: 0.8125rem;
+}
+
/* Card radio group — selectable cards backed by radio inputs */
.card-radio-fieldset {
border: none;
@@ -1528,7 +1533,15 @@
display: flex;
align-items: center;
justify-content: space-between;
+ width: 100%;
margin-bottom: 1rem;
+ padding: 0;
+ border: none;
+ background: none;
+ cursor: pointer;
+ font: inherit;
+ color: inherit;
+ text-align: left;
}
.admin-checklist-title {
@@ -1570,17 +1583,48 @@
.admin-checklist-item {
display: flex;
- align-items: center;
+ align-items: flex-start;
gap: 0.75rem;
padding: 0.5rem 0;
}
+.admin-checklist-content {
+ flex: 1;
+ min-width: 0;
+}
+
+.admin-checklist-row {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+}
+
+.admin-checklist-hint {
+ margin: 0.25rem 0 0;
+ font-size: 0.75rem;
+ color: var(--admin-text-muted);
+ line-height: 1.4;
+}
+
+.admin-checklist-optional {
+ display: inline-block;
+ margin-left: 0.375rem;
+ padding: 0.0625rem 0.375rem;
+ font-size: 0.6875rem;
+ font-weight: 500;
+ border-radius: 9999px;
+ background: var(--t-surface-sunken, #e5e5e5);
+ color: var(--admin-text-muted);
+ vertical-align: middle;
+}
+
.admin-checklist-check {
display: flex;
align-items: center;
justify-content: center;
width: 1.25rem;
height: 1.25rem;
+ margin-top: 0.125rem;
border-radius: 50%;
flex-shrink: 0;
border: 1.5px solid var(--t-border-default, #d4d4d4);
@@ -1594,7 +1638,6 @@
}
.admin-checklist-label {
- flex: 1;
font-size: 0.875rem;
}
@@ -1606,13 +1649,9 @@
flex-shrink: 0;
}
-.admin-checklist-footer {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-top: 1rem;
- padding-top: 0.75rem;
- border-top: 1px solid var(--t-surface-sunken, #e5e5e5);
+/* When collapsed, the header has no bottom margin */
+.admin-checklist-header:only-child {
+ margin-bottom: 0;
}
/* ── Page editor ── */
diff --git a/lib/berrypod/release.ex b/lib/berrypod/release.ex
index 849b9f4..5cf8a21 100644
--- a/lib/berrypod/release.ex
+++ b/lib/berrypod/release.ex
@@ -27,7 +27,7 @@ defmodule Berrypod.Release do
case Settings.get_setting("theme_settings") do
nil ->
- {:ok, _} = Settings.apply_preset(:studio)
+ {:ok, _} = Settings.apply_preset(:studio, skip_customised_flag: true)
:ok
_exists ->
diff --git a/lib/berrypod/settings.ex b/lib/berrypod/settings.ex
index 7a3b151..ba3d3c0 100644
--- a/lib/berrypod/settings.ex
+++ b/lib/berrypod/settings.ex
@@ -74,7 +74,6 @@ defmodule Berrypod.Settings do
def get_theme_settings do
case get_setting("theme_settings") do
nil ->
- # Return defaults
%ThemeSettings{}
settings_map when is_map(settings_map) ->
@@ -84,6 +83,16 @@ defmodule Berrypod.Settings do
end
end
+ @doc "Returns the shop name from Settings, falling back to a default."
+ def site_name do
+ get_setting("site_name") || "Store Name"
+ end
+
+ @doc "Returns the shop description from Settings, falling back to a default."
+ def site_description do
+ get_setting("site_description") || "Discover unique products and original designs."
+ end
+
@doc """
Updates the theme settings.
@@ -93,7 +102,7 @@ defmodule Berrypod.Settings do
{:ok, %ThemeSettings{}}
"""
- def update_theme_settings(attrs) when is_map(attrs) do
+ def update_theme_settings(attrs, opts \\ []) when is_map(attrs) do
current = get_theme_settings()
changeset = ThemeSettings.changeset(current, attrs)
@@ -102,7 +111,10 @@ defmodule Berrypod.Settings do
settings = Ecto.Changeset.apply_changes(changeset)
json = Jason.encode!(settings)
put_setting("theme_settings", json, "json")
- put_setting("theme_customised", true, "boolean")
+
+ unless opts[:skip_customised_flag] do
+ put_setting("theme_customised", true, "boolean")
+ end
# Invalidate and rewarm CSS cache
alias Berrypod.Theme.{CSSCache, CSSGenerator}
@@ -125,11 +137,11 @@ defmodule Berrypod.Settings do
{:ok, %ThemeSettings{}}
"""
- def apply_preset(preset_name) when is_atom(preset_name) do
+ def apply_preset(preset_name, opts \\ []) when is_atom(preset_name) do
preset = Berrypod.Theme.Presets.get(preset_name)
if preset do
- update_theme_settings(preset)
+ update_theme_settings(preset, opts)
else
{:error, :preset_not_found}
end
diff --git a/lib/berrypod/settings/theme_settings.ex b/lib/berrypod/settings/theme_settings.ex
index 6689f05..22b12e7 100644
--- a/lib/berrypod/settings/theme_settings.ex
+++ b/lib/berrypod/settings/theme_settings.ex
@@ -15,8 +15,6 @@ defmodule Berrypod.Settings.ThemeSettings do
field :accent_color, :string, default: "#f97316"
# Branding
- field :site_name, :string, default: "Store Name"
- field :site_description, :string, default: "Discover unique products and original designs."
field :logo_mode, :string, default: "text-only"
field :logo_image_id, :binary_id
field :logo_size, :integer, default: 36
@@ -68,8 +66,6 @@ defmodule Berrypod.Settings.ThemeSettings do
:grid_columns,
:header_layout,
:accent_color,
- :site_name,
- :site_description,
:logo_mode,
:logo_image_id,
:logo_size,
diff --git a/lib/berrypod/setup.ex b/lib/berrypod/setup.ex
index 0fbc24c..6d9967c 100644
--- a/lib/berrypod/setup.ex
+++ b/lib/berrypod/setup.ex
@@ -3,7 +3,7 @@ defmodule Berrypod.Setup do
Aggregates setup status checks for the setup flow and launch checklist.
"""
- alias Berrypod.{Accounts, Orders, Products, Settings}
+ alias Berrypod.{Accounts, Mailer, Orders, Products, Settings, Shipping}
@setup_secret_key :berrypod_setup_secret
@@ -62,10 +62,12 @@ defmodule Berrypod.Setup do
## Launch checklist phase
* `products_synced` / `product_count` — products imported
+ * `has_shipping` — at least one shipping rate exists
* `theme_customised` — theme settings have been saved at least once
* `has_orders` — at least one paid order exists
+ * `email_configured` — email adapter configured and verified
* `site_live` — shop is open to the public
- * `can_go_live` — minimum requirements met to go live
+ * `can_go_live` — minimum requirements met to go live (includes shipping)
* `checklist_dismissed` — admin has dismissed the launch checklist
"""
def setup_status do
@@ -77,6 +79,7 @@ defmodule Berrypod.Setup do
stripe_connected = Settings.has_secret?("stripe_api_key")
admin_created = Accounts.has_admin?()
site_live = Settings.site_live?()
+ has_shipping = Shipping.has_shipping_rates?()
%{
# Setup phase
@@ -89,10 +92,12 @@ defmodule Berrypod.Setup do
# Launch checklist
products_synced: products_synced,
product_count: product_count,
+ has_shipping: has_shipping,
theme_customised: Settings.get_setting("theme_customised", false) == true,
has_orders: Orders.has_paid_orders?(),
+ email_configured: Mailer.email_configured?(),
site_live: site_live,
- can_go_live: provider_connected and products_synced and stripe_connected,
+ can_go_live: provider_connected and products_synced and stripe_connected and has_shipping,
checklist_dismissed: Settings.get_setting("checklist_dismissed", false) == true
}
end
diff --git a/lib/berrypod/shipping.ex b/lib/berrypod/shipping.ex
index b5de249..b2809f8 100644
--- a/lib/berrypod/shipping.ex
+++ b/lib/berrypod/shipping.ex
@@ -310,6 +310,15 @@ defmodule Berrypod.Shipping do
# Queries
# =============================================================================
+ @doc """
+ Returns true if at least one shipping rate exists.
+ """
+ def has_shipping_rates? do
+ ShippingRate
+ |> limit(1)
+ |> Repo.exists?()
+ end
+
@doc """
Returns a list of distinct country codes that have shipping rates.
diff --git a/lib/berrypod_web/admin_layout_hook.ex b/lib/berrypod_web/admin_layout_hook.ex
index 4bed023..ce1926f 100644
--- a/lib/berrypod_web/admin_layout_hook.ex
+++ b/lib/berrypod_web/admin_layout_hook.ex
@@ -30,6 +30,8 @@ defmodule BerrypodWeb.AdminLayoutHook do
|> assign(:site_live, Settings.site_live?())
|> assign(:email_configured, Berrypod.Mailer.email_configured?())
|> assign(:theme_settings, theme_settings)
+ |> assign(:site_name, Settings.site_name())
+ |> assign(:site_description, Settings.site_description())
|> assign(:generated_css, generated_css)
|> assign(:attention_count, ActivityLog.count_needing_attention())
|> Phoenix.LiveView.attach_hook(:set_current_path, :handle_params, fn _params,
diff --git a/lib/berrypod_web/components/layouts/shop_root.html.heex b/lib/berrypod_web/components/layouts/shop_root.html.heex
index 1ad4d3a..137eecb 100644
--- a/lib/berrypod_web/components/layouts/shop_root.html.heex
+++ b/lib/berrypod_web/components/layouts/shop_root.html.heex
@@ -7,8 +7,8 @@
@@ -17,19 +17,19 @@
- <.live_title suffix={" · #{@theme_settings.site_name}"}>
+ <.live_title suffix={" · #{@site_name}"}>
{assigns[:page_title]}
<% og_title =
if assigns[:page_title],
- do: "#{assigns[:page_title]} · #{@theme_settings.site_name}",
- else: @theme_settings.site_name
+ do: "#{assigns[:page_title]} · #{@site_name}",
+ else: @site_name
og_description =
assigns[:page_description] ||
- @theme_settings.site_description ||
- "Welcome to #{@theme_settings.site_name}" %>
-
+ @site_description ||
+ "Welcome to #{@site_name}" %>
+
diff --git a/lib/berrypod_web/components/shop_components/layout.ex b/lib/berrypod_web/components/shop_components/layout.ex
index c5d5375..23516c7 100644
--- a/lib/berrypod_web/components/shop_components/layout.ex
+++ b/lib/berrypod_web/components/shop_components/layout.ex
@@ -48,7 +48,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
# Keys accepted by shop_layout — used by layout_assigns/1 so page templates
# can spread assigns without listing each one explicitly.
- @layout_keys ~w(theme_settings logo_image header_image mode cart_items cart_count
+ @layout_keys ~w(theme_settings site_name logo_image header_image mode cart_items cart_count
cart_subtotal cart_total cart_drawer_open cart_status active_page error_page is_admin
search_query search_results search_open categories shipping_estimate
country_code available_countries editing editor_current_path editor_sidebar_open
@@ -75,6 +75,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
The `error_page` flag disables the CartPersist hook and mobile bottom nav.
"""
attr :theme_settings, :map, required: true
+ attr :site_name, :string, required: true
attr :logo_image, :any, required: true
attr :header_image, :any, required: true
attr :mode, :atom, required: true
@@ -119,6 +120,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
<.shop_header
theme_settings={@theme_settings}
+ site_name={@site_name}
logo_image={@logo_image}
header_image={@header_image}
active_page={@active_page}
@@ -135,6 +137,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
<.shop_footer
theme_settings={@theme_settings}
+ site_name={@site_name}
mode={@mode}
categories={assigns[:categories] || []}
footer_nav_items={@footer_nav_items}
@@ -513,7 +516,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
## Attributes
- * `theme_settings` - Required. The theme settings map containing site_name.
+ * `theme_settings` - Required. The theme settings map.
* `mode` - Optional. Either `:live` (default) for real navigation or
`:preview` for theme preview mode with phx-click handlers.
@@ -523,6 +526,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
<.shop_footer theme_settings={@theme_settings} mode={:preview} />
"""
attr :theme_settings, :map, required: true
+ attr :site_name, :string, required: true
attr :mode, :atom, default: :live
attr :categories, :list, default: []
attr :footer_nav_items, :list, default: []
@@ -622,7 +626,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
@@ -649,6 +653,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
<.shop_header theme_settings={@theme_settings} mode={:preview} cart_count={2} />
"""
attr :theme_settings, :map, required: true
+ attr :site_name, :string, required: true
attr :logo_image, :map, default: nil
attr :header_image, :map, default: nil
attr :active_page, :string, default: nil
@@ -670,6 +675,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
<.logo_content
theme_settings={@theme_settings}
+ site_name={@site_name}
logo_image={@logo_image}
active_page={@active_page}
mode={@mode}
@@ -790,6 +796,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
# Logo content that links to home, except when already on home page.
# This follows accessibility best practices - current page should not be a link.
attr :theme_settings, :map, required: true
+ attr :site_name, :string, required: true
attr :logo_image, :map, default: nil
attr :active_page, :string, default: nil
attr :mode, :atom, default: :live
@@ -800,7 +807,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
~H"""
<%= if @is_home do %>
- <.logo_inner theme_settings={@theme_settings} logo_image={@logo_image} />
+ <.logo_inner theme_settings={@theme_settings} site_name={@site_name} logo_image={@logo_image} />
<% else %>
<%= if @mode == :preview do %>
- <.logo_inner theme_settings={@theme_settings} logo_image={@logo_image} />
+ <.logo_inner
+ theme_settings={@theme_settings}
+ site_name={@site_name}
+ logo_image={@logo_image}
+ />
<% else %>
<.link navigate="/" class="shop-logo-link">
- <.logo_inner theme_settings={@theme_settings} logo_image={@logo_image} />
+ <.logo_inner
+ theme_settings={@theme_settings}
+ site_name={@site_name}
+ logo_image={@logo_image}
+ />
<% end %>
<% end %>
@@ -821,6 +836,7 @@ defmodule BerrypodWeb.ShopComponents.Layout do
end
attr :theme_settings, :map, required: true
+ attr :site_name, :string, required: true
attr :logo_image, :map, default: nil
defp logo_inner(assigns) do
@@ -828,36 +844,36 @@ defmodule BerrypodWeb.ShopComponents.Layout do
<%= case @theme_settings.logo_mode do %>
<% "text-only" -> %>
- {@theme_settings.site_name}
+ {@site_name}
<% "logo-text" -> %>
<%= if @logo_image do %>

<% end %>
- {@theme_settings.site_name}
+ {@site_name}
<% "logo-only" -> %>
<%= if @logo_image do %>

<% else %>
- {@theme_settings.site_name}
+ {@site_name}
<% end %>
<% _ -> %>
- {@theme_settings.site_name}
+ {@site_name}
<% end %>
"""
diff --git a/lib/berrypod_web/controllers/error_html.ex b/lib/berrypod_web/controllers/error_html.ex
index 25f8b5c..de27e92 100644
--- a/lib/berrypod_web/controllers/error_html.ex
+++ b/lib/berrypod_web/controllers/error_html.ex
@@ -85,6 +85,8 @@ defmodule BerrypodWeb.ErrorHTML do
assigns =
assigns
|> Map.put(:theme_settings, theme_settings)
+ |> Map.put(:site_name, safe_load(&Settings.site_name/0) || "Store Name")
+ |> Map.put(:site_description, safe_load(&Settings.site_description/0) || "")
|> Map.put(:generated_css, generated_css)
|> Map.put(:logo_image, logo_image)
|> Map.put(:header_image, header_image)
diff --git a/lib/berrypod_web/controllers/favicon_controller.ex b/lib/berrypod_web/controllers/favicon_controller.ex
index 79dae17..0539dfe 100644
--- a/lib/berrypod_web/controllers/favicon_controller.ex
+++ b/lib/berrypod_web/controllers/favicon_controller.ex
@@ -25,15 +25,16 @@ defmodule BerrypodWeb.FaviconController do
def webmanifest(conn, _params) do
settings = Settings.get_theme_settings()
+ site_name = Settings.site_name()
short_name =
case settings.favicon_short_name do
name when is_binary(name) and name != "" -> name
- _ -> String.slice(settings.site_name, 0, 12)
+ _ -> String.slice(site_name, 0, 12)
end
manifest = %{
- name: settings.site_name,
+ name: site_name,
short_name: short_name,
theme_color: settings.accent_color || "#000000",
background_color: settings.icon_background_color || "#ffffff",
diff --git a/lib/berrypod_web/live/admin/dashboard.ex b/lib/berrypod_web/live/admin/dashboard.ex
index 10f8f04..e880239 100644
--- a/lib/berrypod_web/live/admin/dashboard.ex
+++ b/lib/berrypod_web/live/admin/dashboard.ex
@@ -3,14 +3,6 @@ defmodule BerrypodWeb.Admin.Dashboard do
alias Berrypod.{Cart, Orders, Products, Settings}
- @checklist_items [
- %{key: :products_synced, label: "Sync your products", href: "/admin/providers"},
- %{key: :stripe_connected, label: "Connect Stripe", href: "/admin/settings"},
- %{key: :theme_customised, label: "Customise your theme", href: "/admin/theme"},
- %{key: :has_orders, label: "Place a test order", href: "/"},
- %{key: :site_live, label: "Go live", href: nil}
- ]
-
@impl true
def mount(_params, _session, socket) do
setup = Berrypod.Setup.setup_status()
@@ -23,6 +15,7 @@ defmodule BerrypodWeb.Admin.Dashboard do
|> assign(:page_title, "Dashboard")
|> assign(:setup, setup)
|> assign(:show_checklist, show_checklist?(setup))
+ |> assign(:checklist_collapsed, false)
|> assign(:just_went_live, false)
|> assign(:paid_count, paid_count)
|> assign(:revenue, Orders.total_revenue())
@@ -43,14 +36,8 @@ defmodule BerrypodWeb.Admin.Dashboard do
|> assign(:just_went_live, true)}
end
- def handle_event("dismiss_checklist", _params, socket) do
- {:ok, _} = Settings.put_setting("checklist_dismissed", true, "boolean")
- setup = %{socket.assigns.setup | checklist_dismissed: true}
-
- {:noreply,
- socket
- |> assign(:setup, setup)
- |> assign(:show_checklist, false)}
+ def handle_event("toggle_checklist", _params, socket) do
+ {:noreply, assign(socket, :checklist_collapsed, !socket.assigns.checklist_collapsed)}
end
# ── Render ──
@@ -78,7 +65,11 @@ defmodule BerrypodWeb.Admin.Dashboard do
<%!-- Launch checklist --%>
- <.launch_checklist :if={@show_checklist and !@just_went_live} setup={@setup} />
+ <.launch_checklist
+ :if={@show_checklist and !@just_went_live}
+ setup={@setup}
+ collapsed={@checklist_collapsed}
+ />
<%!-- Stats --%>
@@ -158,86 +149,147 @@ defmodule BerrypodWeb.Admin.Dashboard do
# ==========================================================================
attr :setup, :map, required: true
+ attr :collapsed, :boolean, required: true
defp launch_checklist(assigns) do
- items =
- Enum.map(@checklist_items, fn item ->
- Map.put(item, :done, Map.get(assigns.setup, item.key, false))
- end)
+ items = checklist_items(assigns.setup)
- done_count = Enum.count(items, & &1.done)
- total = length(items)
+ # Email is optional — exclude from progress count
+ required_items = Enum.reject(items, &(&1.key == :email_configured))
+ done_count = Enum.count(required_items, & &1.done)
+ total = length(required_items)
progress_pct = round(done_count / total * 100)
- can_go_live =
- assigns.setup.provider_connected and assigns.setup.products_synced and
- assigns.setup.stripe_connected
-
assigns =
assigns
|> assign(:items, items)
|> assign(:done_count, done_count)
|> assign(:total, total)
|> assign(:progress_pct, progress_pct)
- |> assign(:can_go_live, can_go_live)
+ |> assign(:can_go_live, assigns.setup.can_go_live)
+ |> assign(:has_shipping, assigns.setup.has_shipping)
~H"""
-
+
-
+
-
<.icon :if={item.done} name="hero-check-mini" class="size-3" />
-
- {item.label}
-
+
+
+
+ {item.label}
+ optional
+
-
- <%= if item.key == :site_live do %>
-
- <% else %>
- <.link
- :if={!item.done}
- navigate={item.href}
- class="admin-btn admin-btn-secondary admin-btn-sm"
- >
- {if item.done, do: "View", else: "Start"} →
-
- <% end %>
-
+
+ <%= if item.key == :site_live do %>
+
+ <% else %>
+ <.link
+ :if={!item.done}
+ navigate={item.href}
+ class="admin-btn admin-btn-secondary admin-btn-sm"
+ >
+ Start →
+
+ <% end %>
+
+
+
+
+ {item.hint}
+
+
+
+ Shipping rates haven't synced yet. Try re-syncing your products from the <.link
+ navigate="/admin/providers"
+ class="admin-link"
+ >providers page.
+
+
-
-
"""
end
+ defp checklist_items(setup) do
+ [
+ # Setup wizard items (done first during onboarding)
+ %{
+ key: :provider_connected,
+ label: "Connect a print provider",
+ href: "/admin/providers"
+ },
+ %{
+ key: :stripe_connected,
+ label: "Connect Stripe",
+ href: "/admin/settings"
+ },
+ # Post-setup items
+ %{
+ key: :products_synced,
+ label: "Sync your products",
+ href: if(setup.provider_connected, do: "/admin/products", else: "/admin/providers"),
+ hint: "Import products from your print provider."
+ },
+ %{
+ key: :theme_customised,
+ label: "Customise your theme",
+ href: "/admin/theme",
+ hint: "Upload your logo, pick your colours, and choose a font that matches your brand."
+ },
+ %{
+ key: :email_configured,
+ label: "Set up email",
+ href: "/admin/settings",
+ optional: true,
+ hint: "Needed for order confirmations, abandoned cart emails, and the contact form."
+ },
+ %{
+ key: :has_orders,
+ label: "Place a test order",
+ href: "/",
+ hint:
+ "Use card 4242 4242 4242 4242 with any future expiry and CVC. " <>
+ "You'll see the order in Orders when it works."
+ },
+ %{key: :site_live, label: "Go live"}
+ ]
+ |> Enum.map(fn item ->
+ Map.put(item, :done, Map.get(setup, item.key, false))
+ end)
+ end
+
# ==========================================================================
# Components
# ==========================================================================
@@ -287,7 +339,7 @@ defmodule BerrypodWeb.Admin.Dashboard do
# ==========================================================================
defp show_checklist?(setup) do
- not setup.site_live and not setup.checklist_dismissed
+ not setup.site_live
end
defp format_revenue(amount_pence) when is_integer(amount_pence) do
diff --git a/lib/berrypod_web/live/admin/pages/editor.ex b/lib/berrypod_web/live/admin/pages/editor.ex
index f4ba74f..f7e8f0b 100644
--- a/lib/berrypod_web/live/admin/pages/editor.ex
+++ b/lib/berrypod_web/live/admin/pages/editor.ex
@@ -688,6 +688,7 @@ defmodule BerrypodWeb.Admin.Pages.Editor do
page_data={@page_data}
preview_data={@preview_data}
theme_settings={@theme_settings}
+ site_name={@site_name}
generated_css={@generated_css}
logo_image={@logo_image}
header_image={@header_image}
diff --git a/lib/berrypod_web/live/admin/theme/index.ex b/lib/berrypod_web/live/admin/theme/index.ex
index fa0f119..6d6f366 100644
--- a/lib/berrypod_web/live/admin/theme/index.ex
+++ b/lib/berrypod_web/live/admin/theme/index.ex
@@ -26,6 +26,8 @@ defmodule BerrypodWeb.Admin.Theme.Index do
socket =
socket
|> assign(:theme_settings, theme_settings)
+ |> assign(:site_name, Settings.site_name())
+ |> assign(:site_description, Settings.site_description())
|> assign(:generated_css, generated_css)
|> assign(:preview_page, :home)
|> assign(:presets_with_descriptions, Presets.all_with_descriptions())
@@ -174,6 +176,16 @@ defmodule BerrypodWeb.Admin.Theme.Index do
{:noreply, socket}
end
+ # Settings stored outside the theme JSON
+ @standalone_settings ~w(site_name site_description)
+
+ @impl true
+ def handle_event("update_setting", %{"field" => field, "setting_value" => value}, socket)
+ when field in @standalone_settings do
+ Settings.put_setting(field, value, "string")
+ {:noreply, assign(socket, String.to_existing_atom(field), value)}
+ end
+
@impl true
def handle_event("update_setting", %{"field" => field, "setting_value" => value}, socket) do
field_atom = String.to_existing_atom(field)
@@ -197,6 +209,19 @@ defmodule BerrypodWeb.Admin.Theme.Index do
end
end
+ @impl true
+ def handle_event("update_setting", %{"field" => field} = params, socket)
+ when field in @standalone_settings do
+ value = params[field]
+
+ if value do
+ Settings.put_setting(field, value, "string")
+ {:noreply, assign(socket, String.to_existing_atom(field), value)}
+ else
+ {:noreply, socket}
+ end
+ end
+
@impl true
def handle_event("update_setting", %{"field" => field} = params, socket) do
# For phx-change events from select/input elements, the value comes from the name attribute
@@ -439,6 +464,7 @@ defmodule BerrypodWeb.Admin.Theme.Index do
attr :page, :atom, required: true
attr :preview_data, :map, required: true
attr :theme_settings, :map, required: true
+ attr :site_name, :string, required: true
attr :logo_image, :any, required: true
attr :header_image, :any, required: true
attr :cart_drawer_open, :boolean, default: false
diff --git a/lib/berrypod_web/live/admin/theme/index.html.heex b/lib/berrypod_web/live/admin/theme/index.html.heex
index 5841f5a..a173103 100644
--- a/lib/berrypod_web/live/admin/theme/index.html.heex
+++ b/lib/berrypod_web/live/admin/theme/index.html.heex
@@ -74,7 +74,7 @@
@@ -374,7 +374,7 @@
type="text"
name="favicon_short_name"
value={@theme_settings.favicon_short_name}
- placeholder={String.slice(@theme_settings.site_name, 0, 12)}
+ placeholder={String.slice(@site_name, 0, 12)}
maxlength="12"
class="admin-input admin-input-sm"
/>
@@ -1181,7 +1181,7 @@
- {@theme_settings.site_name |> String.downcase() |> String.replace(" ", "")}.myshopify.com
+ {@site_name |> String.downcase() |> String.replace(" ", "")}.myshopify.com
@@ -1213,6 +1213,7 @@
page={@preview_page}
preview_data={@preview_data}
theme_settings={@theme_settings}
+ site_name={@site_name}
logo_image={@logo_image}
header_image={@header_image}
cart_drawer_open={@cart_drawer_open}
diff --git a/lib/berrypod_web/live/setup/onboarding.ex b/lib/berrypod_web/live/setup/onboarding.ex
index 39ce190..08836c0 100644
--- a/lib/berrypod_web/live/setup/onboarding.ex
+++ b/lib/berrypod_web/live/setup/onboarding.ex
@@ -2,7 +2,6 @@ defmodule BerrypodWeb.Setup.Onboarding do
use BerrypodWeb, :live_view
alias Berrypod.{Accounts, Products, Settings, Setup}
- alias Berrypod.Products.ProviderConnection
alias Berrypod.Providers.Provider
alias Berrypod.Stripe.Setup, as: StripeSetup
@@ -38,25 +37,30 @@ defmodule BerrypodWeb.Setup.Onboarding do
logged_in? = get_user(socket) != nil
provider_conn = Products.get_first_provider_connection()
+ current_step =
+ cond do
+ not logged_in? -> 1
+ not setup.provider_connected -> 2
+ true -> 3
+ end
+
socket
|> assign(:page_title, "Set up your shop")
|> assign(:setup, setup)
|> assign(:logged_in?, logged_in?)
+ |> assign(:current_step, current_step)
# Secret gate
|> assign(:require_secret?, Setup.require_setup_secret?())
|> assign(:secret_verified, false)
|> assign(:secret_form, to_form(%{"secret" => ""}, as: :secret))
# Account (card 1)
- |> assign(:account_form, to_form(%{"email" => ""}, as: :account))
+ |> assign(:account_form, to_form(%{"email" => "", "shop_name" => ""}, as: :account))
# Provider (card 2)
|> assign(:providers, Provider.all())
|> assign(:selected_provider, nil)
|> assign(:provider_form, to_form(%{"api_key" => ""}, as: :provider))
- |> assign(:provider_testing, false)
- |> assign(:provider_test_result, nil)
|> assign(:provider_connecting, false)
|> assign(:provider_conn, provider_conn)
- |> assign(:pending_provider_key, nil)
# Stripe (card 3)
|> assign(:stripe_form, to_form(%{"api_key" => ""}, as: :stripe))
|> assign(:stripe_connecting, false)
@@ -75,10 +79,17 @@ defmodule BerrypodWeb.Setup.Onboarding do
# ── Events: Account ──
- def handle_event("create_account", %{"account" => %{"email" => email}}, socket) do
+ def handle_event("create_account", %{"account" => params}, socket) do
+ email = params["email"]
+ shop_name = String.trim(params["shop_name"] || "")
+
if email == "" do
{:noreply, put_flash(socket, :error, "Please enter your email address")}
else
+ if shop_name != "" do
+ Settings.put_setting("site_name", shop_name, "string")
+ end
+
case Accounts.register_and_confirm_admin(%{email: email}) do
{:ok, user} ->
token = Accounts.generate_login_token(user)
@@ -105,33 +116,7 @@ defmodule BerrypodWeb.Setup.Onboarding do
{:noreply,
socket
|> assign(:selected_provider, type)
- |> assign(:provider_form, to_form(%{"api_key" => ""}, as: :provider))
- |> assign(:provider_test_result, nil)
- |> assign(:pending_provider_key, nil)}
- end
-
- def handle_event("validate_provider", %{"provider" => params}, socket) do
- {:noreply, assign(socket, pending_provider_key: params["api_key"])}
- end
-
- def handle_event("test_provider", _params, socket) do
- type = socket.assigns.selected_provider
- api_key = socket.assigns.pending_provider_key
-
- if api_key in [nil, ""] do
- {:noreply, assign(socket, provider_test_result: {:error, :no_api_key})}
- else
- socket = assign(socket, provider_testing: true, provider_test_result: nil)
-
- temp_conn = %ProviderConnection{
- provider_type: type,
- api_key_encrypted: encrypt_api_key(api_key)
- }
-
- result = Berrypod.Providers.test_connection(temp_conn)
-
- {:noreply, assign(socket, provider_testing: false, provider_test_result: result)}
- end
+ |> assign(:provider_form, to_form(%{"api_key" => ""}, as: :provider))}
end
def handle_event("connect_provider", %{"provider" => %{"api_key" => api_key}}, socket) do
@@ -142,22 +127,32 @@ defmodule BerrypodWeb.Setup.Onboarding do
else
socket = assign(socket, provider_connecting: true)
- params =
- %{"api_key" => api_key, "provider_type" => type}
- |> maybe_add_shop_config(socket.assigns.provider_test_result)
- |> maybe_add_name(socket.assigns.provider_test_result, type)
+ name =
+ case Provider.get(type) do
+ nil -> type
+ info -> info.name
+ end
+
+ params = %{"api_key" => api_key, "provider_type" => type, "name" => name}
case Products.create_provider_connection(params) do
{:ok, connection} ->
Products.enqueue_sync(connection)
setup = Setup.setup_status()
- {:noreply,
- socket
- |> assign(:provider_connecting, false)
- |> assign(:provider_conn, connection)
- |> assign(:setup, setup)
- |> put_flash(:info, "Connected! Product sync started in the background.")}
+ if setup.setup_complete do
+ {:noreply,
+ socket
+ |> put_flash(:info, "You're in! Here's your launch checklist.")
+ |> push_navigate(to: ~p"/admin")}
+ else
+ {:noreply,
+ socket
+ |> assign(:provider_connecting, false)
+ |> assign(:provider_conn, connection)
+ |> assign(:setup, setup)
+ |> put_flash(:info, "Connected! Product sync started in the background.")}
+ end
{:error, _changeset} ->
{:noreply,
@@ -180,11 +175,18 @@ defmodule BerrypodWeb.Setup.Onboarding do
{:ok, _result} ->
setup = Setup.setup_status()
- {:noreply,
- socket
- |> assign(:stripe_connecting, false)
- |> assign(:setup, setup)
- |> put_flash(:info, "Stripe connected")}
+ if setup.setup_complete do
+ {:noreply,
+ socket
+ |> put_flash(:info, "You're in! Here's your launch checklist.")
+ |> push_navigate(to: ~p"/admin")}
+ else
+ {:noreply,
+ socket
+ |> assign(:stripe_connecting, false)
+ |> assign(:setup, setup)
+ |> put_flash(:info, "Stripe connected")}
+ end
{:error, message} ->
{:noreply,
@@ -243,20 +245,27 @@ defmodule BerrypodWeb.Setup.Onboarding do
<%!-- All three setup cards --%>
<.section_card
- title="Create admin account"
+ title="Set up your account"
number={1}
done={@logged_in?}
summary={account_summary(assigns)}
>
-
Enter your email to create the admin account.
+
Name your shop and create the admin account.
<.form for={@account_form} phx-submit="create_account">
+ <.input
+ field={@account_form[:shop_name]}
+ type="text"
+ label="Shop name"
+ placeholder="e.g. Acme Prints"
+ autocomplete="off"
+ phx-mounted={@current_step == 1 && JS.focus()}
+ />
<.input
field={@account_form[:email]}
type="email"
label="Email address"
autocomplete="email"
required
- phx-mounted={JS.focus()}
/>
<.button phx-disable-with="Creating account...">Create account
@@ -274,8 +283,6 @@ defmodule BerrypodWeb.Setup.Onboarding do
providers={@providers}
selected={@selected_provider}
form={@provider_form}
- testing={@provider_testing}
- test_result={@provider_test_result}
connecting={@provider_connecting}
/>
@@ -289,6 +296,7 @@ defmodule BerrypodWeb.Setup.Onboarding do
<.stripe_section
form={@stripe_form}
connecting={@stripe_connecting}
+ focus={@current_step == 3}
/>
@@ -346,8 +354,6 @@ defmodule BerrypodWeb.Setup.Onboarding do
attr :providers, :list, required: true
attr :selected, :string, default: nil
attr :form, :any, required: true
- attr :testing, :boolean, required: true
- attr :test_result, :any, default: nil
attr :connecting, :boolean, required: true
defp provider_section(assigns) do
@@ -376,7 +382,7 @@ defmodule BerrypodWeb.Setup.Onboarding do
- <.form for={@form} phx-change="validate_provider" phx-submit="connect_provider">
+ <.form for={@form} phx-submit="connect_provider">
<.input
field={@form[:api_key]}
type="password"
@@ -386,58 +392,21 @@ defmodule BerrypodWeb.Setup.Onboarding do
/>
-
- <.button type="submit" disabled={@connecting or @testing}>
+ <.button type="submit" disabled={@connecting}>
{if @connecting, do: "Connecting...", else: "Connect"}
-
- <.provider_test_feedback :if={@test_result} result={@test_result} />
"""
end
- attr :result, :any, required: true
-
- defp provider_test_feedback(assigns) do
- ~H"""
-
- <%= case @result do %>
- <% {:ok, info} -> %>
-
- <.icon name="hero-check-circle" class="size-4" />
- Connected{if info[:shop_name], do: " to #{info.shop_name}", else: ""}
-
- <% {:error, :no_api_key} -> %>
-
- <.icon name="hero-x-circle" class="size-4" /> Please enter your API token
-
- <% {:error, reason} -> %>
-
- <.icon name="hero-x-circle" class="size-4" /> {format_error(reason)}
-
- <% end %>
-
- """
- end
-
# ── Stripe section ──
attr :form, :any, required: true
attr :connecting, :boolean, required: true
+ attr :focus, :boolean, default: false
defp stripe_section(assigns) do
~H"""
@@ -461,13 +430,14 @@ defmodule BerrypodWeb.Setup.Onboarding do
label="Secret key"
autocomplete="off"
placeholder="sk_test_... or sk_live_..."
+ phx-mounted={@focus && JS.focus()}
/>
Starts with sk_test_ or sk_live_. Encrypted at rest.
<.button phx-disable-with="Connecting...">
- {if @connecting, do: "Connecting...", else: "Connect Stripe"}
+ {if @connecting, do: "Connecting...", else: "Connect"}
@@ -501,31 +471,6 @@ defmodule BerrypodWeb.Setup.Onboarding do
defp stripe_summary(_), do: nil
- defp encrypt_api_key(api_key) do
- case Berrypod.Vault.encrypt(api_key) do
- {:ok, encrypted} -> encrypted
- _ -> nil
- end
- end
-
- defp maybe_add_shop_config(params, {:ok, %{shop_id: shop_id}}) do
- config = Map.get(params, "config", %{}) |> Map.put("shop_id", to_string(shop_id))
- Map.put(params, "config", config)
- end
-
- defp maybe_add_shop_config(params, _), do: params
-
- defp maybe_add_name(params, {:ok, %{shop_name: name}}, _type) when is_binary(name) do
- Map.put_new(params, "name", name)
- end
-
- defp maybe_add_name(params, _, type) do
- case Provider.get(type) do
- nil -> Map.put_new(params, "name", type)
- info -> Map.put_new(params, "name", info.name)
- end
- end
-
defp provider_card_options(providers) do
Enum.map(providers, fn provider ->
option = %{
@@ -541,11 +486,4 @@ defmodule BerrypodWeb.Setup.Onboarding do
end
end)
end
-
- defp format_error(:unauthorized), do: "That token doesn't seem to be valid"
- defp format_error(:timeout), do: "Couldn't reach the provider — try again"
- defp format_error(:provider_not_implemented), do: "This provider isn't supported yet"
- defp format_error({:http_error, _code}), do: "Something went wrong — try again"
- defp format_error(error) when is_binary(error), do: error
- defp format_error(_), do: "Connection failed — check your token and try again"
end
diff --git a/lib/berrypod_web/live/shop/coming_soon.ex b/lib/berrypod_web/live/shop/coming_soon.ex
index 8520f03..82d827b 100644
--- a/lib/berrypod_web/live/shop/coming_soon.ex
+++ b/lib/berrypod_web/live/shop/coming_soon.ex
@@ -12,9 +12,9 @@ defmodule BerrypodWeb.Shop.ComingSoon do
-
})
+
-
{@theme_settings.site_name}
+
{@site_name}
We're getting things ready. Check back soon.
diff --git a/lib/berrypod_web/live/shop/home.ex b/lib/berrypod_web/live/shop/home.ex
index 461e104..067cf81 100644
--- a/lib/berrypod_web/live/shop/home.ex
+++ b/lib/berrypod_web/live/shop/home.ex
@@ -9,7 +9,7 @@ defmodule BerrypodWeb.Shop.Home do
extra = Pages.load_block_data(page.blocks, socket.assigns)
base = BerrypodWeb.Endpoint.url()
- site_name = socket.assigns.theme_settings.site_name
+ site_name = socket.assigns.site_name
org_ld =
Jason.encode!(
diff --git a/lib/berrypod_web/plugs/load_theme.ex b/lib/berrypod_web/plugs/load_theme.ex
index 81e816d..1e5de67 100644
--- a/lib/berrypod_web/plugs/load_theme.ex
+++ b/lib/berrypod_web/plugs/load_theme.ex
@@ -34,6 +34,8 @@ defmodule BerrypodWeb.Plugs.LoadTheme do
conn
|> assign(:theme_settings, theme_settings)
+ |> assign(:site_name, Settings.site_name())
+ |> assign(:site_description, Settings.site_description())
|> assign(:generated_css, generated_css)
end
end
diff --git a/lib/berrypod_web/theme_hook.ex b/lib/berrypod_web/theme_hook.ex
index f9f9da4..7002269 100644
--- a/lib/berrypod_web/theme_hook.ex
+++ b/lib/berrypod_web/theme_hook.ex
@@ -56,6 +56,8 @@ defmodule BerrypodWeb.ThemeHook do
socket =
socket
|> assign(:theme_settings, theme_settings)
+ |> assign(:site_name, Settings.site_name())
+ |> assign(:site_description, Settings.site_description())
|> assign(:generated_css, generated_css)
|> assign(:logo_image, Media.get_logo())
|> assign(:header_image, Media.get_header())
diff --git a/test/berrypod/setup_test.exs b/test/berrypod/setup_test.exs
index b93b270..e95fa87 100644
--- a/test/berrypod/setup_test.exs
+++ b/test/berrypod/setup_test.exs
@@ -20,6 +20,7 @@ defmodule Berrypod.SetupTest do
refute status.can_go_live
refute status.theme_customised
refute status.has_orders
+ refute status.has_shipping
refute status.checklist_dismissed
end
@@ -89,7 +90,7 @@ defmodule Berrypod.SetupTest do
assert Setup.setup_status().setup_complete
end
- test "can_go_live requires provider, products, and stripe" do
+ test "can_go_live requires provider, products, stripe, and shipping" do
{:ok, conn} =
Products.create_provider_connection(%{
name: "Test",
@@ -105,12 +106,25 @@ defmodule Berrypod.SetupTest do
status: "active"
})
- # Still missing stripe
+ # Still missing stripe and shipping
refute Setup.setup_status().can_go_live
- # Add stripe
{:ok, _} = Settings.put_secret("stripe_api_key", "sk_test_abc123")
+ # Still missing shipping
+ refute Setup.setup_status().can_go_live
+
+ Berrypod.Shipping.upsert_rates(conn.id, [
+ %{
+ blueprint_id: 1,
+ print_provider_id: 1,
+ country_code: "GB",
+ first_item_cost: 350,
+ additional_item_cost: 200,
+ currency: "GBP"
+ }
+ ])
+
assert Setup.setup_status().can_go_live
end
@@ -121,5 +135,64 @@ defmodule Berrypod.SetupTest do
assert Setup.setup_status().theme_customised
end
+
+ test "detects shipping rates" do
+ refute Setup.setup_status().has_shipping
+
+ {:ok, conn} =
+ Products.create_provider_connection(%{
+ name: "Test",
+ provider_type: "printify",
+ api_key: "test_api_key"
+ })
+
+ Berrypod.Shipping.upsert_rates(conn.id, [
+ %{
+ blueprint_id: 1,
+ print_provider_id: 1,
+ country_code: "GB",
+ first_item_cost: 350,
+ additional_item_cost: 200,
+ currency: "GBP"
+ }
+ ])
+
+ assert Setup.setup_status().has_shipping
+ end
+
+ test "can_go_live requires shipping rates" do
+ {:ok, conn} =
+ Products.create_provider_connection(%{
+ name: "Test",
+ provider_type: "printify",
+ api_key: "test_api_key"
+ })
+
+ {:ok, _product} =
+ Products.create_product(%{
+ title: "Test product",
+ provider_product_id: "ext-1",
+ provider_connection_id: conn.id,
+ status: "active"
+ })
+
+ {:ok, _} = Settings.put_secret("stripe_api_key", "sk_test_abc123")
+
+ # No shipping rates yet
+ refute Setup.setup_status().can_go_live
+
+ Berrypod.Shipping.upsert_rates(conn.id, [
+ %{
+ blueprint_id: 1,
+ print_provider_id: 1,
+ country_code: "GB",
+ first_item_cost: 350,
+ additional_item_cost: 200,
+ currency: "GBP"
+ }
+ ])
+
+ assert Setup.setup_status().can_go_live
+ end
end
end
diff --git a/test/berrypod_web/live/admin/dashboard_test.exs b/test/berrypod_web/live/admin/dashboard_test.exs
index 5874ece..51094cf 100644
--- a/test/berrypod_web/live/admin/dashboard_test.exs
+++ b/test/berrypod_web/live/admin/dashboard_test.exs
@@ -27,6 +27,8 @@ defmodule BerrypodWeb.Admin.DashboardTest do
{:ok, _view, html} = live(conn, ~p"/admin")
assert html =~ "Launch checklist"
+ assert html =~ "Connect a print provider"
+ assert html =~ "Connect Stripe"
assert html =~ "Sync your products"
assert html =~ "Customise your theme"
assert html =~ "Go live"
@@ -39,17 +41,22 @@ defmodule BerrypodWeb.Admin.DashboardTest do
refute html =~ "Launch checklist"
end
- test "dismiss checklist hides it", %{conn: conn} do
- {:ok, view, _html} = live(conn, ~p"/admin")
- assert has_element?(view, "button", "Dismiss")
+ test "collapse and expand checklist", %{conn: conn} do
+ {:ok, view, html} = live(conn, ~p"/admin")
+ assert html =~ "Sync your products"
- html = render_click(view, "dismiss_checklist")
+ # Collapse
+ html = render_click(view, "toggle_checklist")
+ refute html =~ "Sync your products"
+ assert html =~ "Launch checklist"
- refute html =~ "Launch checklist"
+ # Expand
+ html = render_click(view, "toggle_checklist")
+ assert html =~ "Sync your products"
end
test "go live button works", %{conn: conn} do
- # Need provider + products + stripe for go live to be enabled
+ # Need provider + products + stripe + shipping for go live
{:ok, conn_record} =
Berrypod.Products.create_provider_connection(%{
name: "Test",
@@ -67,6 +74,17 @@ defmodule BerrypodWeb.Admin.DashboardTest do
{:ok, _} = Berrypod.Settings.put_secret("stripe_api_key", "sk_test_123")
+ Berrypod.Shipping.upsert_rates(conn_record.id, [
+ %{
+ blueprint_id: 1,
+ print_provider_id: 1,
+ country_code: "GB",
+ first_item_cost: 350,
+ additional_item_cost: 200,
+ currency: "GBP"
+ }
+ ])
+
{:ok, view, _html} = live(conn, ~p"/admin")
html = render_click(view, "go_live")
@@ -74,6 +92,19 @@ defmodule BerrypodWeb.Admin.DashboardTest do
assert html =~ "Your shop is live"
assert Berrypod.Settings.site_live?()
end
+
+ test "shows test order guidance", %{conn: conn} do
+ {:ok, _view, html} = live(conn, ~p"/admin")
+
+ assert html =~ "4242 4242 4242 4242"
+ end
+
+ test "shows email setup as optional", %{conn: conn} do
+ {:ok, _view, html} = live(conn, ~p"/admin")
+
+ assert html =~ "Set up email"
+ assert html =~ "optional"
+ end
end
describe "stats" do
diff --git a/test/berrypod_web/live/setup/onboarding_test.exs b/test/berrypod_web/live/setup/onboarding_test.exs
index 3695eba..b2094ca 100644
--- a/test/berrypod_web/live/setup/onboarding_test.exs
+++ b/test/berrypod_web/live/setup/onboarding_test.exs
@@ -10,7 +10,7 @@ defmodule BerrypodWeb.Setup.OnboardingTest do
test "accessible on fresh install (no admin)", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/setup")
assert html =~ "Set up your shop"
- assert html =~ "Create admin account"
+ assert html =~ "Set up your account"
end
test "redirects to /admin when setup is complete", %{conn: conn} do
@@ -60,7 +60,7 @@ defmodule BerrypodWeb.Setup.OnboardingTest do
test "shows all three cards with email form active", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/setup")
- assert html =~ "Create admin account"
+ assert html =~ "Set up your account"
assert html =~ "Connect a print provider"
assert html =~ "Connect payments"
end
@@ -114,7 +114,7 @@ defmodule BerrypodWeb.Setup.OnboardingTest do
{:ok, _view, html} = live(conn, ~p"/setup")
assert html =~ "Secret key"
- assert html =~ "Connect Stripe"
+ assert html =~ "Connect payments"
end
end
diff --git a/test/berrypod_web/live/shop/coming_soon_test.exs b/test/berrypod_web/live/shop/coming_soon_test.exs
index 9e7a131..e013543 100644
--- a/test/berrypod_web/live/shop/coming_soon_test.exs
+++ b/test/berrypod_web/live/shop/coming_soon_test.exs
@@ -17,7 +17,7 @@ defmodule BerrypodWeb.Shop.ComingSoonTest do
end
test "displays the shop name", %{conn: conn} do
- {:ok, _} = Settings.update_theme_settings(%{site_name: "My Test Shop"})
+ Settings.put_setting("site_name", "My Test Shop", "string")
{:ok, _view, html} = live(conn, ~p"/coming-soon")
diff --git a/test/berrypod_web/page_renderer_test.exs b/test/berrypod_web/page_renderer_test.exs
index 3e0a9f4..9e84109 100644
--- a/test/berrypod_web/page_renderer_test.exs
+++ b/test/berrypod_web/page_renderer_test.exs
@@ -12,6 +12,7 @@ defmodule BerrypodWeb.PageRendererTest do
%{
__changed__: nil,
theme_settings: %ThemeSettings{},
+ site_name: "Test Store",
logo_image: nil,
header_image: nil,
mode: :shop,