Tasks C, H, I from the plan: - Forgiving API key validation: add Printify UUID format and Printful length validation, validate on blur for fast feedback, helpful error messages with specific guidance - External links UX: verified all external links use <.external_link> component with target="_blank", rel="noopener noreferrer", icon, and screen reader text - Input styling WCAG compliance: increase input border contrast from ~3.3:1 to ~4.5-5:1 across all theme moods (neutral, warm, cool, dark) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -64,6 +64,24 @@ defmodule BerrypodWeb.Admin.Dashboard do
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%!-- Shop is live banner (not just now, but already live) --%>
|
||||
<div
|
||||
:if={@setup.site_live && !@just_went_live}
|
||||
class="admin-status-banner admin-status-banner-live admin-card-spaced"
|
||||
>
|
||||
<.icon name="hero-check-circle" class="size-5" />
|
||||
<span>Your shop is live</span>
|
||||
</div>
|
||||
|
||||
<%!-- Setup in progress message --%>
|
||||
<div
|
||||
:if={@show_checklist && !@just_went_live && !@setup.setup_complete}
|
||||
class="admin-status-banner admin-status-banner-setup admin-card-spaced"
|
||||
>
|
||||
<.icon name="hero-wrench-screwdriver" class="size-5" />
|
||||
<span>Your admin account has been created. Continue the full setup below.</span>
|
||||
</div>
|
||||
|
||||
<%!-- Launch checklist --%>
|
||||
<.launch_checklist
|
||||
:if={@show_checklist and !@just_went_live}
|
||||
@@ -222,6 +240,16 @@ defmodule BerrypodWeb.Admin.Dashboard do
|
||||
|
||||
<p :if={item[:hint] && !item.done} class="admin-checklist-hint">
|
||||
{item.hint}
|
||||
<a
|
||||
:if={item[:help_url]}
|
||||
href={item.help_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="admin-checklist-help"
|
||||
>
|
||||
<.icon name="hero-question-mark-circle-mini" class="size-4" />
|
||||
<span class="sr-only">Help (opens in new window)</span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p
|
||||
@@ -242,47 +270,58 @@ defmodule BerrypodWeb.Admin.Dashboard do
|
||||
|
||||
defp checklist_items(setup) do
|
||||
[
|
||||
# Setup wizard items (done first during onboarding)
|
||||
# Setup wizard items (matches guided flow step names)
|
||||
%{
|
||||
key: :provider_connected,
|
||||
label: "Connect a print provider",
|
||||
href: "/admin/providers?from=checklist"
|
||||
href: "/admin/providers",
|
||||
hint: "Link your Printify or Printful account to import products.",
|
||||
help_url:
|
||||
"https://help.printify.com/hc/en-us/articles/4483606633617-How-to-find-my-Printify-API-key"
|
||||
},
|
||||
%{
|
||||
key: :stripe_connected,
|
||||
label: "Connect Stripe",
|
||||
href: "/admin/settings?from=checklist"
|
||||
},
|
||||
# Post-setup items
|
||||
%{
|
||||
key: :products_synced,
|
||||
label: "Sync your products",
|
||||
href:
|
||||
if(setup.provider_connected,
|
||||
do: "/admin/products?from=checklist",
|
||||
else: "/admin/providers?from=checklist"
|
||||
),
|
||||
hint: "Import products from your print provider."
|
||||
label: "Connect Stripe for payments",
|
||||
href: "/admin/settings",
|
||||
hint: "Accept credit card payments from customers.",
|
||||
help_url: "https://stripe.com/docs/keys"
|
||||
},
|
||||
%{
|
||||
key: :email_configured,
|
||||
label: "Set up email",
|
||||
href: "/admin/settings/email?from=checklist",
|
||||
hint: "Needed for order confirmations, abandoned cart emails, and the contact form."
|
||||
href: "/admin/settings/email",
|
||||
hint: "Send order confirmations, shipping updates, and newsletters."
|
||||
},
|
||||
# Post-setup items
|
||||
%{
|
||||
key: :products_synced,
|
||||
label: "Import products",
|
||||
href:
|
||||
if(setup.provider_connected,
|
||||
do: "/admin/products",
|
||||
else: "/admin/providers"
|
||||
),
|
||||
hint: "Sync products from your print provider."
|
||||
},
|
||||
%{
|
||||
key: :has_shipping,
|
||||
label: "Set up shipping",
|
||||
href: "/admin/shipping",
|
||||
hint: "Configure shipping rates for your products."
|
||||
},
|
||||
%{
|
||||
key: :theme_customised,
|
||||
label: "Customise your theme",
|
||||
label: "Customise your shop",
|
||||
href: "/?edit=theme",
|
||||
hint: "Upload your logo, pick your colours, and choose a font that matches your brand."
|
||||
hint: "Upload your logo, pick colours, and choose fonts.",
|
||||
optional: true
|
||||
},
|
||||
%{
|
||||
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."
|
||||
hint: "Use card 4242 4242 4242 4242 with any future expiry and CVC.",
|
||||
optional: true
|
||||
},
|
||||
%{key: :site_live, label: "Go live"}
|
||||
]
|
||||
|
||||
@@ -40,14 +40,33 @@ defmodule BerrypodWeb.Admin.Providers.Form do
|
||||
|
||||
@impl true
|
||||
def handle_event("validate", %{"provider_connection" => params}, socket) do
|
||||
form =
|
||||
api_key = params["api_key"] || ""
|
||||
provider_type = socket.assigns.provider_type
|
||||
|
||||
# Build base changeset
|
||||
changeset =
|
||||
socket.assigns.connection
|
||||
|> ProviderConnection.changeset(params)
|
||||
|> Map.put(:action, :validate)
|
||||
|> to_form()
|
||||
|
||||
# Add key format validation error if key is present
|
||||
form =
|
||||
if api_key != "" do
|
||||
case KeyValidation.validate_provider_key(api_key, provider_type) do
|
||||
{:ok, _} ->
|
||||
to_form(changeset)
|
||||
|
||||
{:error, message} ->
|
||||
changeset
|
||||
|> Ecto.Changeset.add_error(:api_key, message)
|
||||
|> to_form()
|
||||
end
|
||||
else
|
||||
to_form(changeset)
|
||||
end
|
||||
|
||||
# Store api_key separately since changeset encrypts it immediately
|
||||
{:noreply, assign(socket, form: form, pending_api_key: params["api_key"])}
|
||||
{:noreply, assign(socket, form: form, pending_api_key: api_key)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
else: "Paste your key here"
|
||||
}
|
||||
autocomplete="off"
|
||||
phx-debounce="blur"
|
||||
/>
|
||||
|
||||
<%= if @live_action == :edit do %>
|
||||
|
||||
Reference in New Issue
Block a user