add setup onboarding page, dashboard launch checklist, provider registry

- new /setup page with three-section onboarding (account, provider, payments)
- dashboard launch checklist with progress bar, go-live, dismiss
- provider registry on Provider module (single source of truth for metadata)
- payments registry for Stripe
- setup context made provider-agnostic (provider_connected, theme_customised, etc.)
- admin provider pages now fully registry-driven (no hardcoded provider names)
- auth flow: fresh installs redirect to /setup, signed_in_path respects setup state
- removed old /admin/setup wizard
- 840 tests, 0 failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-20 00:34:06 +00:00
parent 989c5cd4df
commit c2caeed64d
33 changed files with 1927 additions and 1053 deletions

View File

@@ -1,75 +1,32 @@
<.header>
{if @live_action == :new,
do: "Connect to #{provider_label(@provider_type)}",
else: "#{provider_label(@provider_type)} settings"}
do: "Connect to #{@provider.name}",
else: "#{@provider.name} settings"}
</.header>
<div class="max-w-xl mt-6">
<%= if @live_action == :new do %>
<div class="prose prose-sm mb-6">
<p>
{provider_label(@provider_type)} is a print-on-demand service that prints and ships products for you.
{@provider.name} is a print-on-demand service that prints and ships products for you.
Connect your account to automatically import your products into your shop.
</p>
</div>
<%= if @provider_type == "printify" do %>
<div class="rounded-lg bg-base-200 p-4 mb-6 text-sm">
<p class="font-medium mb-2">Get your API key from Printify:</p>
<ol class="list-decimal list-inside space-y-1 text-base-content/80">
<li>
<a
href="https://printify.com/app/auth/login"
target="_blank"
rel="noopener"
class="admin-link"
>
Log in to Printify
</a>
(or <a
href="https://printify.com/app/auth/register"
target="_blank"
rel="noopener"
class="admin-link"
>create a free account</a>)
</li>
<li>Click <strong>Account</strong> (top right)</li>
<li>Select <strong>Connections</strong> from the dropdown</li>
<li>Find <strong>API tokens</strong> and click <strong>Generate</strong></li>
<li>
Enter a name (e.g. "My Shop"), keep <strong>all scopes</strong>
selected, and click <strong>Generate token</strong>
</li>
<li>Click <strong>Copy to clipboard</strong> and paste it below</li>
</ol>
</div>
<% else %>
<div class="rounded-lg bg-base-200 p-4 mb-6 text-sm">
<p class="font-medium mb-2">Get your API key from Printful:</p>
<ol class="list-decimal list-inside space-y-1 text-base-content/80">
<li>
<a
href="https://www.printful.com/auth/login"
target="_blank"
rel="noopener"
class="admin-link"
>
Log in to Printful
</a>
(or <a
href="https://www.printful.com/auth/signup"
target="_blank"
rel="noopener"
class="admin-link"
>create a free account</a>)
</li>
<li>Go to <strong>Settings</strong> &rarr; <strong>API access</strong></li>
<li>Click <strong>Create API key</strong></li>
<li>Give it a name and select <strong>all scopes</strong></li>
<li>Copy the token and paste it below</li>
</ol>
</div>
<% end %>
<div class="rounded-lg bg-base-200 p-4 mb-6 text-sm">
<p class="font-medium mb-2">Get your API key from {@provider.name}:</p>
<ol class="list-decimal list-inside space-y-1 text-base-content/80">
<li>
<a href={@provider.login_url} target="_blank" rel="noopener" class="admin-link">
Log in to {@provider.name}
</a>
(or <a href={@provider.signup_url} target="_blank" rel="noopener" class="admin-link">create a free account</a>)
</li>
<li :for={step <- @provider.setup_steps}>
{raw(step)}
</li>
</ol>
</div>
<% end %>
<.form for={@form} id="provider-form" phx-change="validate" phx-submit="save">
@@ -78,7 +35,7 @@
<.input
field={@form[:api_key]}
type="password"
label={"#{provider_label(@provider_type)} API key"}
label={"#{@provider.name} API key"}
placeholder={
if @live_action == :edit,
do: "Leave blank to keep current key",
@@ -106,7 +63,7 @@
<% {:ok, _info} -> %>
<span class="text-success flex items-center gap-1">
<.icon name="hero-check-circle" class="size-4" />
Connected to {connection_name(@test_result) || provider_label(@provider_type)}
Connected to {connection_name(@test_result) || @provider.name}
</span>
<% {:error, reason} -> %>
<span class="text-error flex items-center gap-1">
@@ -124,7 +81,7 @@
<div class="flex gap-2 mt-6">
<.button type="submit" disabled={@testing}>
{if @live_action == :new,
do: "Connect to #{provider_label(@provider_type)}",
do: "Connect to #{@provider.name}",
else: "Save changes"}
</.button>
<.link navigate={~p"/admin/providers"} class="admin-btn admin-btn-ghost">