mirror of
https://github.com/plausible/analytics.git
synced 2024-11-22 18:52:38 +03:00
First pass: unify onboarding UI (#4445)
* First pass: unify onboarding UI * Dark mode fixes * Format * Update self-hosted index * Remove unnecessary child box in Enter Your 2FA screen * Fixup Enter Your 2FA screen
This commit is contained in:
parent
3b485afc91
commit
572f8abac5
@ -27,7 +27,7 @@ defmodule PlausibleWeb.Components.Generic do
|
||||
"border border-gray-300 dark:border-gray-500 text-red-700 bg-white dark:bg-gray-800 hover:text-red-500 dark:hover:text-red-400 focus:border-blue-300 active:text-red-800"
|
||||
}
|
||||
|
||||
@button_base_class "inline-flex items-center justify-center gap-x-2 rounded-md px-3.5 py-2.5 text-sm font-semibold shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700"
|
||||
@button_base_class "inline-flex items-center justify-center gap-x-2 rounded-md px-3.5 py-2.5 shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700"
|
||||
|
||||
attr(:type, :string, default: "button")
|
||||
attr(:theme, :string, default: "primary")
|
||||
@ -368,4 +368,46 @@ defmodule PlausibleWeb.Components.Generic do
|
||||
["w-4 h-4"]
|
||||
end
|
||||
end
|
||||
|
||||
slot :title
|
||||
slot :subtitle
|
||||
slot :inner_block, required: true
|
||||
slot :footer
|
||||
|
||||
attr :outer_markup, :boolean, default: true
|
||||
|
||||
def focus_box(assigns) do
|
||||
~H"""
|
||||
<div class={[
|
||||
"bg-white w-full max-w-lg mx-auto dark:bg-gray-800 text-black dark:text-gray-100",
|
||||
@outer_markup && "shadow-md rounded mb-4 mt-8"
|
||||
]}>
|
||||
<div class={[@outer_markup && "p-8"]}>
|
||||
<h2 :if={@title != []} class="text-xl font-black dark:text-gray-100">
|
||||
<%= render_slot(@title) %>
|
||||
</h2>
|
||||
|
||||
<div :if={@subtitle != []} class="mt-2 dark:text-gray-200">
|
||||
<%= render_slot(@subtitle) %>
|
||||
</div>
|
||||
|
||||
<div :if={@title != []} class="mt-8">
|
||||
<%= render_slot(@inner_block) %>
|
||||
</div>
|
||||
|
||||
<div :if={@title == []}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:if={@footer != []}
|
||||
class="flex flex-col dark:text-gray-200 border-t border-gray-300 dark:border-gray-700"
|
||||
>
|
||||
<div class={[@outer_markup && "p-8"]}>
|
||||
<%= render_slot(@footer) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
@ -21,104 +21,103 @@ defmodule PlausibleWeb.Live.Components.Verification do
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div
|
||||
class={[
|
||||
"dark:text-gray-100 text-center bg-white dark:bg-gray-800 flex flex-col",
|
||||
if(not @modal?, do: "shadow-md rounded px-8 pt-6 pb-4 mb-4 mt-4 h-96", else: "h-72")
|
||||
]}
|
||||
id="progress-indicator"
|
||||
>
|
||||
<div
|
||||
:if={not @finished? or (not @modal? and @success?)}
|
||||
class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-gray-700"
|
||||
>
|
||||
<div class="block pulsating-circle"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
:if={@finished? and @success? and @modal?}
|
||||
class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-green-500"
|
||||
id="check-circle"
|
||||
>
|
||||
<Heroicons.check_badge class="h-6 w-6 text-green-600 bg-green-100 dark:bg-green-500 dark:text-green-200" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
:if={@finished? and not @success?}
|
||||
class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-red-100 dark:bg-red-200"
|
||||
id="error-circle"
|
||||
>
|
||||
<Heroicons.exclamation_triangle class="h-6 w-6 text-red-600 bg-red-100 dark:bg-red-200 dark:text-red-800" />
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<h3 class="font-semibold leading-6 text-xl">
|
||||
<span :if={@finished? and @success?}>Success!</span>
|
||||
<span :if={not @finished?}>Verifying your integration</span>
|
||||
|
||||
<span :if={@finished? and not @success? and @interpretation}>
|
||||
<%= List.first(@interpretation.errors) %>
|
||||
</span>
|
||||
</h3>
|
||||
<p :if={@finished? and @success? and @modal?} id="progress" class="mt-2">
|
||||
Your integration is working and visitors are being counted accurately
|
||||
</p>
|
||||
<p :if={@finished? and @success? and not @modal?} id="progress" class="mt-2 animate-pulse">
|
||||
Your integration is working. Awaiting your first pageview.
|
||||
</p>
|
||||
<p :if={not @finished?} class="mt-2 animate-pulse" id="progress"><%= @message %></p>
|
||||
|
||||
<p
|
||||
:if={@finished? and not @success? and @interpretation}
|
||||
class="mt-2 text-ellipsis overflow-hidden"
|
||||
id="recommendation"
|
||||
<div id="progress-indicator">
|
||||
<PlausibleWeb.Components.Generic.focus_box outer_markup={not @modal?}>
|
||||
<div
|
||||
:if={not @finished? or (not @modal? and @success?)}
|
||||
class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-gray-700"
|
||||
>
|
||||
<span><%= List.first(@interpretation.recommendations).text %>. </span>
|
||||
<.styled_link href={List.first(@interpretation.recommendations).url} new_tab={true}>
|
||||
Learn more
|
||||
</.styled_link>
|
||||
</p>
|
||||
</div>
|
||||
<div class="block pulsating-circle"></div>
|
||||
</div>
|
||||
|
||||
<div :if={@finished?} class="mt-auto">
|
||||
<.button_link :if={not @success?} href="#" phx-click="retry" class="font-bold w-full">
|
||||
Verify integration again
|
||||
</.button_link>
|
||||
<.button_link
|
||||
:if={@success?}
|
||||
href={"/#{URI.encode_www_form(@domain)}?skip_to_dashboard=true"}
|
||||
class="w-full font-bold mb-4"
|
||||
<div
|
||||
:if={@finished? and @success? and @modal?}
|
||||
class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-green-500"
|
||||
id="check-circle"
|
||||
>
|
||||
Go to the dashboard
|
||||
</.button_link>
|
||||
</div>
|
||||
<Heroicons.check_badge class="h-6 w-6 text-green-600 bg-green-100 dark:bg-green-500 dark:text-green-200" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
:if={
|
||||
<div
|
||||
:if={@finished? and not @success?}
|
||||
class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-red-100 dark:bg-red-200"
|
||||
id="error-circle"
|
||||
>
|
||||
<Heroicons.exclamation_triangle class="h-6 w-6 text-red-600 bg-red-100 dark:bg-red-200 dark:text-red-800" />
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<h3 class="font-semibold leading-6 text-xl">
|
||||
<span :if={@finished? and @success?}>Success!</span>
|
||||
<span :if={not @finished?}>Verifying your integration</span>
|
||||
|
||||
<span :if={@finished? and not @success? and @interpretation}>
|
||||
<%= List.first(@interpretation.errors) %>
|
||||
</span>
|
||||
</h3>
|
||||
<p :if={@finished? and @success? and @modal?} id="progress" class="mt-2">
|
||||
Your integration is working and visitors are being counted accurately
|
||||
</p>
|
||||
<p :if={@finished? and @success? and not @modal?} id="progress" class="mt-2 animate-pulse">
|
||||
Your integration is working. Awaiting your first pageview.
|
||||
</p>
|
||||
<p :if={not @finished?} class="mt-2 animate-pulse" id="progress"><%= @message %></p>
|
||||
|
||||
<p
|
||||
:if={@finished? and not @success? and @interpretation}
|
||||
class="mt-2 text-ellipsis overflow-hidden"
|
||||
id="recommendation"
|
||||
>
|
||||
<span><%= List.first(@interpretation.recommendations).text %>. </span>
|
||||
<.styled_link href={List.first(@interpretation.recommendations).url} new_tab={true}>
|
||||
Learn more
|
||||
</.styled_link>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div :if={@finished?} class="mt-8">
|
||||
<.button_link :if={not @success?} href="#" phx-click="retry" class="w-full">
|
||||
Verify integration again
|
||||
</.button_link>
|
||||
<.button_link
|
||||
:if={@success?}
|
||||
href={"/#{URI.encode_www_form(@domain)}?skip_to_dashboard=true"}
|
||||
class="w-full font-bold mb-4"
|
||||
>
|
||||
Go to the dashboard
|
||||
</.button_link>
|
||||
</div>
|
||||
|
||||
<:footer :if={
|
||||
(not @modal? and not @success?) or
|
||||
(@finished? and not @success?)
|
||||
}
|
||||
class="mt-auto text-sm"
|
||||
>
|
||||
<%= if ee?() and @finished? and not @success? and @attempts >= 3 do %>
|
||||
Need further help with your integration? Do
|
||||
<.styled_link href="https://plausible.io/contact">
|
||||
contact us
|
||||
</.styled_link>
|
||||
<br />
|
||||
<% end %>
|
||||
<%= if not @success? and not @modal? do %>
|
||||
Need to see the snippet again?
|
||||
<.styled_link href={"/#{URI.encode_www_form(@domain)}/snippet?flow=#{@flow}"}>
|
||||
Click here
|
||||
</.styled_link>
|
||||
<br /> Run verification later and go to Site Settings?
|
||||
<.styled_link href={"/#{URI.encode_www_form(@domain)}/settings/general"}>
|
||||
Click here
|
||||
</.styled_link>
|
||||
<br />
|
||||
<% end %>
|
||||
</div>
|
||||
}>
|
||||
<ol class="list-disc space-y-1 ml-4 mt-1 mb-4">
|
||||
<%= if ee?() and @finished? and not @success? and @attempts >= 3 do %>
|
||||
<li>
|
||||
<b>Need further help with your integration?</b>
|
||||
<.styled_link href="https://plausible.io/contact">
|
||||
Contact us
|
||||
</.styled_link>
|
||||
</li>
|
||||
<% end %>
|
||||
<%= if not @success? and not @modal? do %>
|
||||
<li>
|
||||
Need to see the snippet again?
|
||||
<.styled_link href={"/#{URI.encode_www_form(@domain)}/snippet?flow=#{@flow}"}>
|
||||
Click here
|
||||
</.styled_link>
|
||||
</li>
|
||||
<li>
|
||||
Run verification later and go to Site Settings?
|
||||
<.styled_link href={"/#{URI.encode_www_form(@domain)}/settings/general"}>
|
||||
Click here
|
||||
</.styled_link>
|
||||
</li>
|
||||
<% end %>
|
||||
</ol>
|
||||
</:footer>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
@ -50,7 +50,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
<div class="w-full max-w-md mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8">
|
||||
<h2 class="text-xl font-black dark:text-gray-100">Invitation expired</h2>
|
||||
|
||||
<p class="mt-4 text-sm">
|
||||
<p class="mt-4">
|
||||
Your invitation has expired or been revoked. Please request fresh one or you can <%= link(
|
||||
"sign up",
|
||||
class: "text-indigo-600 hover:text-indigo-900",
|
||||
@ -87,7 +87,11 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
current_step="Register"
|
||||
/>
|
||||
|
||||
<div class="w-full max-w-3xl mx-auto flex flex-shrink-0">
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Enter your details
|
||||
</:title>
|
||||
|
||||
<.form
|
||||
:let={f}
|
||||
for={@form}
|
||||
@ -97,12 +101,9 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
phx-change="validate"
|
||||
phx-submit="register"
|
||||
phx-trigger-action={@trigger_submit}
|
||||
class="w-full max-w-md mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8"
|
||||
>
|
||||
<input name="user[register_action]" type="hidden" value={@live_action} />
|
||||
|
||||
<h2 class="text-xl font-black dark:text-gray-100">Enter your details</h2>
|
||||
|
||||
<%= if @invitation do %>
|
||||
<.email_input field={f[:email]} for_invitation={true} />
|
||||
<.name_input field={f[:name]} />
|
||||
@ -113,10 +114,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
|
||||
<div class="my-4">
|
||||
<div class="flex justify-between">
|
||||
<label
|
||||
for={f[:password].name}
|
||||
class="block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<label for={f[:password].name} class="block font-medium text-gray-700 dark:text-gray-300">
|
||||
Password
|
||||
</label>
|
||||
<.password_length_hint minimum={12} field={f[:password]} />
|
||||
@ -126,7 +124,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
field={f[:password]}
|
||||
strength={@password_strength}
|
||||
phx-debounce={200}
|
||||
class="dark:bg-gray-900 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-500 rounded-md dark:text-gray-300"
|
||||
class="dark:bg-gray-900 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full border-gray-300 dark:border-gray-500 rounded-md dark:text-gray-300"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -134,9 +132,9 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
<div class="my-4">
|
||||
<label
|
||||
for={f[:password_confirmation].name}
|
||||
class="block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
class="block font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
Password confirmation
|
||||
Confirm password
|
||||
</label>
|
||||
<div class="mt-1">
|
||||
<.input
|
||||
@ -144,7 +142,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
autocomplete="new-password"
|
||||
field={f[:password_confirmation]}
|
||||
phx-debounce={200}
|
||||
class="dark:bg-gray-900 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-500 rounded-md dark:text-gray-300"
|
||||
class="dark:bg-gray-900 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full border-gray-300 dark:border-gray-500 rounded-md dark:text-gray-300"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -176,9 +174,9 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
|
||||
<% submit_text =
|
||||
if ce?() or @invitation do
|
||||
"Create my account →"
|
||||
"Create my account"
|
||||
else
|
||||
"Start my free trial →"
|
||||
"Start my free trial"
|
||||
end %>
|
||||
<PlausibleWeb.Components.Generic.button
|
||||
id="register"
|
||||
@ -189,21 +187,21 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
<%= submit_text %>
|
||||
</PlausibleWeb.Components.Generic.button>
|
||||
|
||||
<p class="text-center text-gray-600 dark:text-gray-500 text-xs mt-4">
|
||||
<p class="text-center text-gray-600 dark:text-gray-500 mt-4">
|
||||
Already have an account? <%= link("Log in",
|
||||
to: "/login",
|
||||
class: "underline text-gray-800 dark:text-gray-50"
|
||||
) %> instead.
|
||||
) %>
|
||||
</p>
|
||||
</.form>
|
||||
</div>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
"""
|
||||
end
|
||||
|
||||
defp name_input(assigns) do
|
||||
~H"""
|
||||
<div class="my-4">
|
||||
<label for={@field.name} class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
<label for={@field.name} class="block font-medium text-gray-700 dark:text-gray-300">
|
||||
Full name
|
||||
</label>
|
||||
<div class="mt-1">
|
||||
@ -211,7 +209,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
field={@field}
|
||||
placeholder="Jane Doe"
|
||||
phx-debounce={200}
|
||||
class="dark:bg-gray-900 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-500 rounded-md dark:text-gray-300"
|
||||
class="dark:bg-gray-900 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full border-gray-300 dark:border-gray-500 rounded-md dark:text-gray-300"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -226,7 +224,6 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
focus:border-indigo-500
|
||||
block
|
||||
w-full
|
||||
sm:text-sm
|
||||
border-gray-300
|
||||
dark:border-gray-500
|
||||
rounded-md
|
||||
@ -248,7 +245,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
||||
~H"""
|
||||
<div class="my-4">
|
||||
<div class="flex justify-between">
|
||||
<label for={@field.name} class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
<label for={@field.name} class="block font-medium text-gray-700 dark:text-gray-300">
|
||||
Email
|
||||
</label>
|
||||
<p class="text-xs text-gray-500 mt-1">No spam, guaranteed.</p>
|
||||
|
@ -3,108 +3,111 @@
|
||||
current_step="Activate account"
|
||||
/>
|
||||
|
||||
<div class="w-full max-w-3xl mt-4 mx-auto flex">
|
||||
<%= if @has_email_code? do %>
|
||||
<%= form_for @conn, @form_submit_url, [class: "w-full max-w-lg mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8"], fn f -> %>
|
||||
<h2 class="text-xl font-black dark:text-gray-100">
|
||||
<%= if @has_any_memberships? do %>
|
||||
Verify your email address
|
||||
<% else %>
|
||||
Activate your account
|
||||
<% end %>
|
||||
</h2>
|
||||
|
||||
<div class="mt-2 text-sm text-gray-500 dark:text-gray-200 leading-tight">
|
||||
Please enter the 4-digit code we sent to <b><%= @conn.assigns[:current_user].email %></b>
|
||||
</div>
|
||||
|
||||
<div class="mt-12 flex items-stretch flex-grow">
|
||||
<div>
|
||||
<%= text_input(f, :code,
|
||||
class:
|
||||
"tracking-widest font-medium shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-36 px-8 border-gray-300 dark:border-gray-500 rounded-l-md dark:text-gray-200 dark:bg-gray-900",
|
||||
oninput:
|
||||
"this.value=this.value.replace(/[^0-9]/g, ''); if (this.value.length >= 4) document.getElementById('submit').focus()",
|
||||
onclick: "this.select();",
|
||||
maxlength: "4",
|
||||
placeholder: "••••",
|
||||
style: "letter-spacing: 10px;",
|
||||
required: "required"
|
||||
) %>
|
||||
</div>
|
||||
<PlausibleWeb.Components.Generic.button id="submit" type="submit" class="rounded-l-none">
|
||||
Activate →
|
||||
</PlausibleWeb.Components.Generic.button>
|
||||
</div>
|
||||
<%= error_tag(assigns, :error) %>
|
||||
|
||||
<div class="mt-16 text-sm dark:text-gray-100">
|
||||
Didn't receive an email?
|
||||
</div>
|
||||
<ol class="list-disc text-xs text-gray-500 leading-tight space-y-1 mt-1">
|
||||
<li>Check your spam folder</li>
|
||||
<li>
|
||||
<%= link("Send a new code",
|
||||
class: "underline text-indigo-600",
|
||||
to: "/activate/request-code",
|
||||
method: :post
|
||||
) %> to <%= @conn.assigns[:current_user].email %>
|
||||
</li>
|
||||
<%= if ee?() do %>
|
||||
<li>
|
||||
<a class="underline text-indigo-600" href="https://plausible.io/contact">
|
||||
Contact us
|
||||
</a>
|
||||
if the problem persists
|
||||
</li>
|
||||
<% else %>
|
||||
<li>
|
||||
Ask on our <%= link("community-supported forum",
|
||||
to: "https://github.com/plausible/analytics/discussions",
|
||||
class: "text-indigo-600 underline"
|
||||
) %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ol>
|
||||
<div class="mt-4 text-sm dark:text-gray-100">
|
||||
Entered the wrong email address?
|
||||
</div>
|
||||
<ul class="list-disc text-xs text-gray-500 leading-tight mt-1">
|
||||
<%= if @has_any_memberships? do %>
|
||||
<li>
|
||||
<%= link("Change email back to",
|
||||
class: "underline text-indigo-600",
|
||||
to: "/settings/email/cancel",
|
||||
method: "post"
|
||||
) %> to <%= @conn.assigns[:current_user].previous_email %>
|
||||
</li>
|
||||
<% else %>
|
||||
<li>
|
||||
<%= link("Delete this account",
|
||||
class: "underline text-indigo-600",
|
||||
to: "/me?redirect=/register",
|
||||
method: "delete",
|
||||
data: [confirm: "Deleting your account cannot be reversed. Are you sure?"]
|
||||
) %> and start over
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
<%= if @has_email_code? do %>
|
||||
<%= if @has_any_memberships? do %>
|
||||
Verify your email address
|
||||
<% else %>
|
||||
Activate your account
|
||||
<% end %>
|
||||
<% else %>
|
||||
Activate your account
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="w-full max-w-lg mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8">
|
||||
<h2 class="text-xl font-black dark:text-gray-100">Activate your account</h2>
|
||||
</:title>
|
||||
|
||||
<div class="mt-2 text-sm text-gray-500 dark:text-gray-200 leading-tight">
|
||||
A 4-digit activation code will be sent to <b><%= @conn.assigns[:current_user].email %></b>
|
||||
</div>
|
||||
<:subtitle :if={@has_email_code?}>
|
||||
<p class="truncate">
|
||||
Please enter the 4-digit code we sent to <b><%= @conn.assigns[:current_user].email %></b>
|
||||
</p>
|
||||
</:subtitle>
|
||||
|
||||
<%= error_tag(assigns, :error) %>
|
||||
<:subtitle :if={!@has_email_code?}>
|
||||
<p class="truncate">
|
||||
A 4-digit activation code will be sent to <b><%= @conn.assigns[:current_user].email %></b>
|
||||
</p>
|
||||
</:subtitle>
|
||||
|
||||
<%= button("Request activation code",
|
||||
to: "/activate/request-code",
|
||||
method: :post,
|
||||
class: "button mt-12"
|
||||
<div :if={@has_email_code?}>
|
||||
<%= form_for @conn, @form_submit_url, [], fn f -> %>
|
||||
<%= text_input(f, :code,
|
||||
class:
|
||||
"tracking-widest font-medium shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-36 px-8 border-gray-300 dark:border-gray-500 rounded-md dark:text-gray-200 dark:bg-gray-900 text-center",
|
||||
oninput:
|
||||
"this.value=this.value.replace(/[^0-9]/g, ''); if (this.value.length >= 4) document.getElementById('submit').focus()",
|
||||
onclick: "this.select();",
|
||||
maxlength: "4",
|
||||
placeholder: "••••",
|
||||
style: "letter-spacing: 10px;",
|
||||
required: "required"
|
||||
) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<PlausibleWeb.Components.Generic.button id="submit" type="submit" class="w-full mt-8">
|
||||
Activate
|
||||
</PlausibleWeb.Components.Generic.button>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= error_tag(assigns, :error) %>
|
||||
|
||||
<div :if={!@has_email_code?}>
|
||||
<%= button("Request activation code",
|
||||
to: "/activate/request-code",
|
||||
method: :post,
|
||||
class: "w-full button"
|
||||
) %>
|
||||
</div>
|
||||
|
||||
<:footer :if={@has_email_code?}>
|
||||
<b>Didn't receive an email?</b>
|
||||
|
||||
<ol class="list-disc space-y-1 ml-4 mt-1 mb-4">
|
||||
<li>Check your spam folder</li>
|
||||
<li>
|
||||
<%= link("Send a new code",
|
||||
class: "underline text-indigo-600",
|
||||
to: "/activate/request-code",
|
||||
method: :post
|
||||
) %> to <%= @conn.assigns[:current_user].email %>
|
||||
</li>
|
||||
|
||||
<%= if ee?() do %>
|
||||
<li>
|
||||
<a class="underline text-indigo-600" href="https://plausible.io/contact">
|
||||
Contact us
|
||||
</a>
|
||||
if the problem persists
|
||||
</li>
|
||||
<% else %>
|
||||
<li>
|
||||
Ask on our <%= link("community-supported forum",
|
||||
to: "https://github.com/plausible/analytics/discussions",
|
||||
class: "text-indigo-600 underline"
|
||||
) %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ol>
|
||||
|
||||
<b>Entered the wrong email address?</b>
|
||||
|
||||
<ol class="list-disc space-y-1 ml-4 mt-1">
|
||||
<%= if @has_any_memberships? do %>
|
||||
<li>
|
||||
<%= link("Change email back to",
|
||||
class: "underline text-indigo-600",
|
||||
to: "/settings/email/cancel",
|
||||
method: "post"
|
||||
) %> to <%= @conn.assigns[:current_user].previous_email %>
|
||||
</li>
|
||||
<% else %>
|
||||
<li>
|
||||
<%= link("Delete this account",
|
||||
class: "underline text-indigo-600",
|
||||
to: "/me?redirect=/register",
|
||||
method: "delete",
|
||||
data: [confirm: "Deleting your account cannot be reversed. Are you sure?"]
|
||||
) %> and start over
|
||||
</li>
|
||||
<% end %>
|
||||
</ol>
|
||||
</:footer>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
|
@ -1,49 +1,48 @@
|
||||
<div class="w-full max-w-3xl mt-4 mx-auto flex">
|
||||
<div class="w-full max-w-lg mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8">
|
||||
<h2 class="text-xl font-black dark:text-gray-100">
|
||||
<%= if @from_setup do %>
|
||||
Setup Two-Factor Authentication
|
||||
<% else %>
|
||||
Your New Recovery Codes
|
||||
<% end %>
|
||||
</h2>
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
<%= if @from_setup do %>
|
||||
Setup Two-Factor Authentication
|
||||
<% else %>
|
||||
Your New Recovery Codes
|
||||
<% end %>
|
||||
</:title>
|
||||
|
||||
<div class="text-sm mt-2 text-gray-500 dark:text-gray-200 leading-tight">
|
||||
Use these recovery codes to log in if you lose access to the authenticator application. Store them somewhere safe!
|
||||
<div
|
||||
id="recovery-codes-list"
|
||||
class="font-mono border-2 border-dotted border-gray-200 dark:border-gray-700 rounded-md text-gray-600 dark:text-gray-200 text-lg bg-gray-100 dark:bg-gray-900 p-2 mt-6 flex flex-wrap"
|
||||
>
|
||||
<%= for code <- @recovery_codes do %>
|
||||
<div class="basis-1/2 text-center"><%= code %></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<:subtitle>
|
||||
Use these recovery codes to log in if you lose access to the authenticator application. Store them somewhere safe!
|
||||
</:subtitle>
|
||||
|
||||
<div class="mt-6 flex sm:flex-row flex-col justify-between">
|
||||
<button onclick="print(); event.stopPropagation();" id="print" class="button">
|
||||
Print Codes <Heroicons.printer class="h-4 w-4 ml-2 mt-1" />
|
||||
</button>
|
||||
<button
|
||||
onclick="var list = document.getElementById('recovery-codes-list'); var selection = getSelection(); selection.removeAllRanges(); var range = createRange(); range.selectNodeContents(list); selection.addRange(range); document.execCommand('copy'); selection.removeAllRanges(); event.stopPropagation(); document.getElementById('copy-base-icon').classList.add('hidden'); document.getElementById('copy-done-icon').classList.remove('hidden'); setTimeout(function() { document.getElementById('copy-done-icon').classList.add('hidden'); document.getElementById('copy-base-icon').classList.remove('hidden'); }, 2000)"
|
||||
id="copy"
|
||||
class="button sm:mt-0 mt-3"
|
||||
>
|
||||
Copy to Clipboard
|
||||
<span id="copy-base-icon">
|
||||
<Heroicons.document_duplicate class="h-4 w-4 ml-2 mt-1" />
|
||||
</span>
|
||||
<span id="copy-done-icon" class="hidden">
|
||||
<Heroicons.check class="h-4 w-4 ml-2 mt-1" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
id="finish"
|
||||
class="button sm:mt-0 mt-3"
|
||||
onclick={"location.replace('#{Routes.auth_path(@conn, :user_settings) <> "#setup-2fa"}')"}
|
||||
>
|
||||
Finish
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
id="recovery-codes-list"
|
||||
class="font-mono border-2 border-dotted border-gray-200 dark:border-gray-700 rounded-md text-gray-600 dark:text-gray-200 text-lg bg-gray-100 dark:bg-gray-900 p-2 mt-6 flex flex-wrap"
|
||||
>
|
||||
<%= for code <- @recovery_codes do %>
|
||||
<div class="basis-1/2 text-center"><%= code %></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<button onclick="print(); event.stopPropagation();" id="print" class="button w-full">
|
||||
Print Codes <Heroicons.printer class="h-4 w-4 ml-2 mt-1" />
|
||||
</button>
|
||||
<button
|
||||
onclick="var list = document.getElementById('recovery-codes-list'); var selection = getSelection(); selection.removeAllRanges(); var range = createRange(); range.selectNodeContents(list); selection.addRange(range); document.execCommand('copy'); selection.removeAllRanges(); event.stopPropagation(); document.getElementById('copy-base-icon').classList.add('hidden'); document.getElementById('copy-done-icon').classList.remove('hidden'); setTimeout(function() { document.getElementById('copy-done-icon').classList.add('hidden'); document.getElementById('copy-base-icon').classList.remove('hidden'); }, 2000)"
|
||||
id="copy"
|
||||
class="button w-full mt-4"
|
||||
>
|
||||
Copy to Clipboard
|
||||
<span id="copy-base-icon">
|
||||
<Heroicons.document_duplicate class="h-4 w-4 ml-2 mt-1" />
|
||||
</span>
|
||||
<span id="copy-done-icon" class="hidden">
|
||||
<Heroicons.check class="h-4 w-4 ml-2 mt-1" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
id="finish"
|
||||
class="button w-full mt-4"
|
||||
onclick={"location.replace('#{Routes.auth_path(@conn, :user_settings) <> "#setup-2fa"}')"}
|
||||
>
|
||||
Finish
|
||||
</button>
|
||||
</div>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
|
@ -1,71 +1,73 @@
|
||||
<div class="w-full max-w-2xl mt-4 mx-auto flex">
|
||||
<div class="w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8">
|
||||
<h2 class="text-xl font-black dark:text-gray-100">
|
||||
Setup Two-Factor Authentication
|
||||
</h2>
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Setup Two-Factor Authentication
|
||||
</:title>
|
||||
|
||||
<div class="text-sm mt-2 text-gray-500 dark:text-gray-200">
|
||||
Link your Plausible account to the authenticator app you have installed either on your phone or computer.
|
||||
<div class="flex flex-col sm:flex-row items-center sm:items-start">
|
||||
<div class="mt-8">
|
||||
<div class="border-2 border-gray-300 inline-block p-2 dark:bg-white">
|
||||
<PlausibleWeb.Components.TwoFactor.qr_code text={@totp_uri} />
|
||||
</div>
|
||||
</div>
|
||||
<:subtitle>
|
||||
Link your Plausible account to the authenticator app you have installed either on your phone or computer.
|
||||
</:subtitle>
|
||||
|
||||
<div class="mt-8 sm:ml-4">
|
||||
<ol>
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 h-5 w-5 relative flex items-center justify-center">
|
||||
<div class="h-2 w-2 bg-gray-300 dark:bg-gray-700 rounded-full"></div>
|
||||
</div>
|
||||
Open the authenticator application
|
||||
</li>
|
||||
<li class="mt-1 flex items-start">
|
||||
<div class="flex-shrink-0 h-5 w-5 relative flex items-center justify-center">
|
||||
<div class="h-2 w-2 bg-gray-300 dark:bg-gray-700 rounded-full"></div>
|
||||
</div>
|
||||
Tap Scan a QR Code
|
||||
</li>
|
||||
<li class="mt-1 flex items-start">
|
||||
<div class="flex-shrink-0 h-5 w-5 relative flex items-center justify-center">
|
||||
<div class="h-2 w-2 bg-gray-300 dark:bg-gray-700 rounded-full"></div>
|
||||
</div>
|
||||
Scan this code with your phone camera or paste the code manually
|
||||
</li>
|
||||
</ol>
|
||||
<:footer>
|
||||
<p>
|
||||
Changed your mind?
|
||||
<a
|
||||
href={Routes.auth_path(@conn, :user_settings) <> "#setup-2fa"}
|
||||
class="underline text-indigo-600"
|
||||
>
|
||||
Go back to Settings
|
||||
</a>
|
||||
</p>
|
||||
</:footer>
|
||||
|
||||
<div class="sm:ml-2">
|
||||
<PlausibleWeb.Live.Components.Form.input_with_clipboard
|
||||
id="secret"
|
||||
name="secret_clipboard"
|
||||
label="Code"
|
||||
value={@secret}
|
||||
onfocus="this.value = this.value;"
|
||||
class="focus:ring-indigo-500 focus:border-indigo-500 bg-gray-50 dark:bg-gray-850 dark:text-gray-300 block w-7/12 rounded-md sm:text-sm border-gray-300 dark:border-gray-500 w-full p-2 mt-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center sm:items-start">
|
||||
<div class="mt-8">
|
||||
<div class="border-2 border-gray-300 inline-block p-2 dark:bg-white">
|
||||
<PlausibleWeb.Components.TwoFactor.qr_code text={@totp_uri} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-col-reverse sm:flex-row justify-between items-center">
|
||||
<p class="text-sm mt-4 sm:mt-0">
|
||||
Changed your mind?
|
||||
<a
|
||||
href={Routes.auth_path(@conn, :user_settings) <> "#setup-2fa"}
|
||||
class="underline text-indigo-600"
|
||||
>
|
||||
Go back to Settings
|
||||
</a>
|
||||
</p>
|
||||
<.unstyled_link
|
||||
id="proceed"
|
||||
class="button sm:w-auto w-full"
|
||||
href={Routes.auth_path(@conn, :verify_2fa_setup_form)}
|
||||
>
|
||||
Proceed →
|
||||
</.unstyled_link>
|
||||
<div class="mt-8 sm:ml-4">
|
||||
<ol>
|
||||
<li class="flex items-start">
|
||||
<div class="flex-shrink-0 h-5 w-5 relative flex items-center justify-center">
|
||||
<div class="h-2 w-2 bg-gray-300 dark:bg-gray-700 rounded-full"></div>
|
||||
</div>
|
||||
Open the authenticator application
|
||||
</li>
|
||||
<li class="mt-1 flex items-start">
|
||||
<div class="flex-shrink-0 h-5 w-5 relative flex items-center justify-center">
|
||||
<div class="h-2 w-2 bg-gray-300 dark:bg-gray-700 rounded-full"></div>
|
||||
</div>
|
||||
Tap Scan a QR Code
|
||||
</li>
|
||||
<li class="mt-1 flex items-start">
|
||||
<div class="flex-shrink-0 h-5 w-5 relative flex items-center justify-center">
|
||||
<div class="h-2 w-2 bg-gray-300 dark:bg-gray-700 rounded-full"></div>
|
||||
</div>
|
||||
Scan this code with your phone camera or paste the code manually
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<div class="sm:ml-2">
|
||||
<PlausibleWeb.Live.Components.Form.input_with_clipboard
|
||||
id="secret"
|
||||
name="secret_clipboard"
|
||||
label="Code"
|
||||
value={@secret}
|
||||
onfocus="this.value = this.value;"
|
||||
class="focus:ring-indigo-500 focus:border-indigo-500 bg-gray-50 dark:bg-gray-850 dark:text-gray-300 block w-7/12 rounded-md sm:text-sm border-gray-300 dark:border-gray-500 w-full p-2 mt-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-col-reverse sm:flex-row justify-between items-center">
|
||||
<.unstyled_link
|
||||
id="proceed"
|
||||
class="button w-full"
|
||||
href={Routes.auth_path(@conn, :verify_2fa_setup_form)}
|
||||
>
|
||||
Proceed
|
||||
</.unstyled_link>
|
||||
</div>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
|
@ -1,24 +0,0 @@
|
||||
<%= form_for @conn, "/login", [class: "w-full max-w-md mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mt-8"], fn f -> %>
|
||||
<h1 class="text-xl font-black dark:text-gray-100"><%= Phoenix.Flash.get(@flash, :login_title) || "Enter your email and password" %></h1>
|
||||
<%= if Phoenix.Flash.get(@flash, :login_instructions) do %>
|
||||
<p class="text-gray-500 text-sm mt-1 mb-2"><%= Phoenix.Flash.get(@flash, :login_instructions) %></p>
|
||||
<% end %>
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<div class="text-red-500 text-xs italic mt-4"><%= @conn.assigns[:error] %></div>
|
||||
<% end %>
|
||||
<div class="my-4 mt-8">
|
||||
<%= label f, :email, class: "block text-gray-700 dark:text-gray-300 text-sm font-bold mb-2" %>
|
||||
<%= email_input f, :email, autocomplete: "username", class: "bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500", placeholder: "user@example.com" %>
|
||||
</div>
|
||||
<div class="my-4">
|
||||
<%= label f, :password, class: "block text-gray-700 dark:text-gray-300 text-sm font-bold mb-2" %>
|
||||
<%= password_input f, :password, id: "current-password", autocomplete: "current-password", class: "transition bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500" %>
|
||||
<p class="text-gray-500 text-xs my-2">Forgot password? <a href="/password/request-reset" class="underline text-gray-800 dark:text-gray-50">Click here</a> to reset it.</p>
|
||||
</div>
|
||||
<%= submit "Login →", class: "button mt-4 w-full" %>
|
||||
<%= if Keyword.fetch!(Application.get_env(:plausible, :selfhost),:disable_registration) == false do %>
|
||||
<p class="text-center text-gray-500 text-xs mt-4">
|
||||
Don't have an account? <%= link("Register", to: "/register", class: "text-gray-800 dark:text-gray-50 underline") %> instead.
|
||||
</p>
|
||||
<% end %>
|
||||
<% end %>
|
58
lib/plausible_web/templates/auth/login_form.html.heex
Normal file
58
lib/plausible_web/templates/auth/login_form.html.heex
Normal file
@ -0,0 +1,58 @@
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
<%= Phoenix.Flash.get(@flash, :login_title) || "Enter your account credentials" %>
|
||||
</:title>
|
||||
<:subtitle>
|
||||
<%= if Phoenix.Flash.get(@flash, :login_instructions) do %>
|
||||
<p class="text-gray-500 mt-1 mb-2">
|
||||
<%= Phoenix.Flash.get(@flash, :login_instructions) %>
|
||||
</p>
|
||||
<% end %>
|
||||
</:subtitle>
|
||||
<%= form_for @conn, "/login", [], fn f -> %>
|
||||
<div class="my-4 mt-8">
|
||||
<%= label(f, :email, class: "block text-gray-700 dark:text-gray-300 mb-2") %>
|
||||
<%= email_input(f, :email,
|
||||
autocomplete: "username",
|
||||
class:
|
||||
"bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500",
|
||||
placeholder: "user@example.com"
|
||||
) %>
|
||||
</div>
|
||||
<div class="my-4">
|
||||
<%= label(f, :password, class: "block text-gray-700 dark:text-gray-300 mb-2") %>
|
||||
<%= password_input(f, :password,
|
||||
id: "current-password",
|
||||
autocomplete: "current-password",
|
||||
class:
|
||||
"transition bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500"
|
||||
) %>
|
||||
</div>
|
||||
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<div class="text-red-500 mt-4"><%= @conn.assigns[:error] %></div>
|
||||
<% end %>
|
||||
|
||||
<%= submit("Log in", class: "button mt-4 w-full") %>
|
||||
<% end %>
|
||||
|
||||
<:footer>
|
||||
<ol class="list-disc space-y-1 ml-4 mt-1 mb-4">
|
||||
<%= if Keyword.fetch!(Application.get_env(:plausible, :selfhost),:disable_registration) == false do %>
|
||||
<li>
|
||||
Don't have an account? <%= link("Register",
|
||||
to: "/register",
|
||||
class: "text-gray-800 dark:text-gray-50 underline"
|
||||
) %> instead.
|
||||
</li>
|
||||
<% end %>
|
||||
<li>
|
||||
Forgot password?
|
||||
<a href="/password/request-reset" class="underline text-gray-800 dark:text-gray-50">
|
||||
Click here
|
||||
</a>
|
||||
to reset it.
|
||||
</li>
|
||||
</ol>
|
||||
</:footer>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
@ -1,22 +0,0 @@
|
||||
<%= form_for @conn, "/password/request-reset", [class: "max-w-md w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mt-8"], fn f -> %>
|
||||
<h1 class="text-xl font-black dark:text-gray-100">Reset your password</h1>
|
||||
<div class="mt-4 dark:text-gray-100">Enter your email so we can send a password reset link</div>
|
||||
<div class="my-4 mt-8">
|
||||
<%= email_input f, :email, class: "transition bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500", placeholder: "user@example.com" %>
|
||||
</div>
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<div class="text-red-500 text-xs italic my-2"><%= @conn.assigns[:error] %></div>
|
||||
<% end %>
|
||||
|
||||
<%= if PlausibleWeb.Captcha.enabled?() do %>
|
||||
<div class="mt-4">
|
||||
<div class="h-captcha" data-sitekey="<%= PlausibleWeb.Captcha.sitekey() %>"></div>
|
||||
<%= if assigns[:captcha_error] do %>
|
||||
<div class="text-red-500 text-xs italic mt-3"><%= @captcha_error %></div>
|
||||
<% end %>
|
||||
<script src="https://hcaptcha.com/1/api.js" async defer></script>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= submit "Send reset link →", class: "button mt-4 w-full" %>
|
||||
<% end %>
|
@ -0,0 +1,35 @@
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Reset your password
|
||||
</:title>
|
||||
|
||||
<:subtitle>
|
||||
Enter your email so we can send a password reset link
|
||||
</:subtitle>
|
||||
|
||||
<%= form_for @conn, "/password/request-reset", [], fn f -> %>
|
||||
<div class="my-4 mt-8">
|
||||
<%= email_input(f, :email,
|
||||
class:
|
||||
"transition bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500",
|
||||
placeholder: "user@example.com"
|
||||
) %>
|
||||
</div>
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<div class="text-red-500 my-2"><%= @conn.assigns[:error] %></div>
|
||||
<% end %>
|
||||
|
||||
<%= if PlausibleWeb.Captcha.enabled?() do %>
|
||||
<div class="mt-4">
|
||||
<div class="h-captcha" data-sitekey={PlausibleWeb.Captcha.sitekey()}></div>
|
||||
<%= if assigns[:captcha_error] do %>
|
||||
<div class="text-red-500 text-xs mt-3"><%= @captcha_error %></div>
|
||||
<% end %>
|
||||
<script src="https://hcaptcha.com/1/api.js" async defer>
|
||||
</script>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= submit("Send reset link", class: "button mt-4 w-full") %>
|
||||
<% end %>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
@ -1,14 +1,33 @@
|
||||
<div class="w-full max-w-3xl mt-4 mx-auto flex">
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Enter Your 2FA Code
|
||||
</:title>
|
||||
|
||||
<:subtitle>
|
||||
Enter the code from your authenticator application before it expires or wait for a new one.
|
||||
</:subtitle>
|
||||
|
||||
<:footer>
|
||||
<ol class="list-disc space-y-1 ml-4 mt-1 mb-4">
|
||||
<li>
|
||||
Can't access your authenticator application?
|
||||
<.styled_link href={Routes.auth_path(@conn, :verify_2fa_recovery_code_form)}>
|
||||
Use recovery code
|
||||
</.styled_link>
|
||||
</li>
|
||||
<li :if={ee?()}>
|
||||
Lost your recovery codes?
|
||||
<.styled_link href="https://plausible.io/contact">
|
||||
Contact us
|
||||
</.styled_link>
|
||||
</li>
|
||||
</ol>
|
||||
</:footer>
|
||||
|
||||
<%= form_for @conn.params, Routes.auth_path(@conn, :verify_2fa), [
|
||||
class: "w-full max-w-lg mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8",
|
||||
onsubmit: "document.getElementById('verify-button').disabled = true"
|
||||
], fn f -> %>
|
||||
<h2 class="text-xl font-black dark:text-gray-100">
|
||||
Enter Your 2FA Code
|
||||
</h2>
|
||||
|
||||
<div class="text-sm mt-2 text-gray-500 dark:text-gray-200 leading-tight">
|
||||
Enter the code from your authenticator application before it expires or wait for a new one.
|
||||
<div class="mt-2 text-gray-500 dark:text-gray-200 leading-tight">
|
||||
<PlausibleWeb.Components.TwoFactor.verify_2fa_input form={f} field={:code} class="mt-6" />
|
||||
|
||||
<div class="mt-4 flex flex-inline items-center sm:justify-start justify-center">
|
||||
@ -20,24 +39,6 @@
|
||||
Trust this device for <%= @remember_2fa_days %> days
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-row justify-between items-center">
|
||||
<p class="text-sm">
|
||||
Can't access your authenticator application?
|
||||
<a
|
||||
href={Routes.auth_path(@conn, :verify_2fa_recovery_code_form)}
|
||||
class="underline text-indigo-600"
|
||||
>
|
||||
Use recovery code
|
||||
</a>
|
||||
<%= if ee?() do %>
|
||||
<br /> Lost your recovery codes?
|
||||
<a href="https://plausible.io/contact" class="underline text-indigo-600">
|
||||
Contact us
|
||||
</a>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
|
@ -1,38 +1,37 @@
|
||||
<div class="w-full max-w-3xl mt-4 mx-auto flex">
|
||||
<div class="w-full max-w-lg mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 py-6 mb-4 mt-8">
|
||||
<h2 class="text-xl font-black dark:text-gray-100">
|
||||
Setup Two-Factor Authentication
|
||||
</h2>
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Setup Two-Factor Authentication
|
||||
</:title>
|
||||
|
||||
<div class="text-sm mt-2 text-gray-500 dark:text-gray-200 leading-tight">
|
||||
<%= form_for @conn.params, Routes.auth_path(@conn, :verify_2fa_setup), [
|
||||
id: "verify-2fa-form",
|
||||
onsubmit: "document.getElementById('verify-button').disabled = true"
|
||||
], fn f -> %>
|
||||
Enter the code from your authenticator application before it expires or wait for a new one.
|
||||
<PlausibleWeb.Components.TwoFactor.verify_2fa_input form={f} field={:code} class="mt-6" />
|
||||
<:subtitle>
|
||||
Enter the code from your authenticator application before it expires or wait for a new one.
|
||||
</:subtitle>
|
||||
|
||||
<:footer>
|
||||
<p>
|
||||
Changed your mind?
|
||||
<a
|
||||
href={Routes.auth_path(@conn, :user_settings) <> "#setup-2fa"}
|
||||
class="underline text-indigo-600"
|
||||
>
|
||||
Go back to Settings
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= form_for @conn.params, Routes.auth_path(@conn, :initiate_2fa_setup), [id: "start-over-form"], fn _f -> %>
|
||||
Having trouble?
|
||||
<button class="underline text-indigo-600">
|
||||
Start over
|
||||
</button>
|
||||
<% end %>
|
||||
</p>
|
||||
</:footer>
|
||||
|
||||
<div class="mt-6 flex flex-col">
|
||||
<p class="text-sm">
|
||||
Changed your mind?
|
||||
<a
|
||||
href={Routes.auth_path(@conn, :user_settings) <> "#setup-2fa"}
|
||||
class="underline text-indigo-600"
|
||||
>
|
||||
Go back to Settings
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p class="text-sm">
|
||||
<%= form_for @conn.params, Routes.auth_path(@conn, :initiate_2fa_setup), [id: "start-over-form"], fn _f -> %>
|
||||
Having trouble?
|
||||
<button class="underline text-indigo-600">
|
||||
Start over
|
||||
</button>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%= form_for @conn.params, Routes.auth_path(@conn, :verify_2fa_setup), [
|
||||
id: "verify-2fa-form",
|
||||
onsubmit: "document.getElementById('verify-button').disabled = true"
|
||||
], fn f -> %>
|
||||
<PlausibleWeb.Components.TwoFactor.verify_2fa_input form={f} field={:code} class="mt-6" />
|
||||
<% end %>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
|
@ -1,34 +0,0 @@
|
||||
<div class="mt-12 w-full md:max-w-xl md:mx-auto bg-white dark:bg-gray-800 md:shadow-md md:rounded px-8 py-6">
|
||||
<p class="text-gray-900 text-xl font-black dark:text-gray-100">
|
||||
Welcome to Plausible!
|
||||
</p>
|
||||
<p class="mt-4 text-gray-600 dark:text-gray-200">
|
||||
<a href="https://plausible.io/" class="border-b text-indigo-700 font-semibold dark:text-indigo-400 border-indigo-700 dark:border-indigo-500">Plausible Analytics</a> is a simple, open source, lightweight (< 1 KB) and privacy-friendly alternative to Google Analytics. We're completely independent and solely funded by our 10,000+ paying subscribers. Read more <a href="https://plausible.io/about" class="border-b font-semibold text-indigo-700 dark:text-indigo-400 border-indigo-700 dark:border-indigo-500">about us.</a>
|
||||
</p>
|
||||
<ul class="mt-6 flex flex-wrap text-gray-700 dark:text-gray-300 space-y-1 md:space-y-0">
|
||||
<li class="w-full md:w-1/2 md:order-1">
|
||||
<%= link to: Routes.auth_path(@conn, :login), class: "flex items-center" do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-log-in h-4 w-4"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path><polyline points="10 17 15 12 10 7"></polyline><line x1="15" y1="12" x2="3" y2="12"></line></svg>
|
||||
<span class="ml-2 font-semibold underline text-indigo-700 dark:text-indigo-400">Login</span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class="w-full md:mt-1 md:w-1/2 md:order-3">
|
||||
<%= link to: Routes.auth_path(@conn, :register_form), class: "flex items-center" do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user-plus h-4 w-4"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><line x1="20" y1="8" x2="20" y2="14"></line><line x1="23" y1="11" x2="17" y2="11"></line></svg>
|
||||
<span class="ml-2 font-semibold underline text-indigo-700 dark:text-indigo-400">Register</span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class="w-full md:w-1/2 md:order-2">
|
||||
<a href="https://plausible.io/docs" class="flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book-open h-4 w-4"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path></svg>
|
||||
<span class="ml-2 font-semibold underline text-indigo-700 dark:text-indigo-400">Guides & Docs</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full md:mt-1 md:w-1/2 md:order-4">
|
||||
<a href="https://twitter.com/plausiblehq" class="flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-twitter h-4 w-4"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path></svg>
|
||||
<span class="ml-2 font-semibold underline text-indigo-700 dark:text-indigo-400">Follow on Twitter</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
40
lib/plausible_web/templates/page/index.html.heex
Normal file
40
lib/plausible_web/templates/page/index.html.heex
Normal file
@ -0,0 +1,40 @@
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Welcome to Plausible!
|
||||
</:title>
|
||||
|
||||
<p>
|
||||
<.styled_link href="https://plausible.io/">
|
||||
Plausible Analytics
|
||||
</.styled_link>
|
||||
is a simple, open source, lightweight (< 1 KB) and privacy-friendly alternative to Google Analytics. We're completely independent and solely funded by our 10,000+ paying subscribers. Read more
|
||||
<.styled_link href="https://plausible.io/about">
|
||||
about us.
|
||||
</.styled_link>
|
||||
</p>
|
||||
|
||||
<:footer>
|
||||
<ol class="list-disc space-y-1 ml-4 mt-1 mb-4">
|
||||
<li>
|
||||
<.styled_link href={Routes.auth_path(@conn, :login)}>
|
||||
Login
|
||||
</.styled_link>
|
||||
</li>
|
||||
<li>
|
||||
<.styled_link href={Routes.auth_path(@conn, :register_form)}>
|
||||
Register
|
||||
</.styled_link>
|
||||
</li>
|
||||
<li>
|
||||
<.styled_link href="https://plausible.io/docs">
|
||||
Guides & Docs
|
||||
</.styled_link>
|
||||
</li>
|
||||
<li>
|
||||
<.styled_link href="https://twitter.com/plausiblehq">
|
||||
Follow on Twitter
|
||||
</.styled_link>
|
||||
</li>
|
||||
</ol>
|
||||
</:footer>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
@ -1,9 +1,11 @@
|
||||
<PlausibleWeb.Components.FlowProgress.render flow={@flow} current_step="Add site info" />
|
||||
|
||||
<div class="w-full max-w-3xl mt-4 mx-auto flex">
|
||||
<%= form_for @changeset, @form_submit_url, [class: "max-w-lg w-full mx-auto bg-white dark:bg-gray-800 shadow-lg rounded px-8 pt-6 pb-8 mb-4 mt-8"], fn f -> %>
|
||||
<h2 class="text-xl font-black dark:text-gray-100 mb-4">Your website details</h2>
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Add website info
|
||||
</:title>
|
||||
|
||||
<%= form_for @changeset, @form_submit_url, [class: ""], fn f -> %>
|
||||
<PlausibleWeb.Components.Billing.Notice.limit_exceeded
|
||||
:if={@site_limit_exceeded?}
|
||||
current_user={@current_user}
|
||||
@ -42,17 +44,17 @@
|
||||
<% end %>
|
||||
|
||||
<div class="my-6">
|
||||
<%= label(f, :domain, class: "block text-sm font-medium text-gray-700 dark:text-gray-300") %>
|
||||
<p class="text-gray-500 dark:text-gray-400 text-xs mt-1">
|
||||
<%= label(f, :domain, class: "block font-medium dark:text-gray-300") %>
|
||||
<p class="text-gray-500 dark:text-gray-400 mt-1 text-sm">
|
||||
Just the naked domain or subdomain without 'www'
|
||||
</p>
|
||||
<div class="mt-2 flex rounded-md shadow-sm">
|
||||
<span class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 dark:border-gray-500 bg-gray-50 dark:bg-gray-850 text-gray-500 dark:text-gray-400 sm:text-sm">
|
||||
<span class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 dark:border-gray-500 bg-gray-50 dark:bg-gray-850 dark:text-gray-400">
|
||||
https://
|
||||
</span>
|
||||
<%= text_input(f, :domain,
|
||||
class:
|
||||
"focus:ring-indigo-500 focus:border-indigo-500 dark:bg-gray-800 flex-1 block w-full px-3 py-2 rounded-none rounded-r-md sm:text-sm border-gray-300 dark:border-gray-500 dark:bg-gray-900 dark:text-gray-300",
|
||||
"focus:ring-indigo-500 focus:border-indigo-500 dark:bg-gray-800 flex-1 block w-full px-3 py-2 rounded-none rounded-r-md border-gray-300 dark:border-gray-500 dark:bg-gray-900 dark:text-gray-300",
|
||||
placeholder: "example.com",
|
||||
disabled: @site_limit_exceeded?
|
||||
) %>
|
||||
@ -61,9 +63,9 @@
|
||||
</div>
|
||||
<div class="my-6">
|
||||
<%= label(f, :timezone, "Reporting Timezone",
|
||||
class: "block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
class: "block font-medium text-gray-700 dark:text-gray-300"
|
||||
) %>
|
||||
<p class="text-gray-500 dark:text-gray-400 text-xs mt-1">
|
||||
<p class="text-gray-500 dark:text-gray-400 text-sm mt-1">
|
||||
To make sure we agree on what 'today' means
|
||||
</p>
|
||||
|
||||
@ -78,24 +80,24 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var option;
|
||||
var option;
|
||||
|
||||
if (typeof Intl !== "undefined") {
|
||||
var timezoneName = Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||
option = document.querySelector('#tz-select option[value="' + timezoneName + '"]')
|
||||
}
|
||||
if (typeof Intl !== "undefined") {
|
||||
var timezoneName = Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||
option = document.querySelector('#tz-select option[value="' + timezoneName + '"]')
|
||||
}
|
||||
|
||||
if (!option) {
|
||||
var offset = (new Date()).getTimezoneOffset()
|
||||
option = document.querySelector('#tz-select option[offset="' + offset + '"]')
|
||||
option = document.querySelector('#tz-select option[offset="' + offset + '"]')
|
||||
}
|
||||
|
||||
if (option) { option.selected = "selected"}
|
||||
</script>
|
||||
|
||||
<%= submit("Add snippet →",
|
||||
<%= submit("Add snippet",
|
||||
class: "button mt-4 w-full disabled:cursor-not-allowed",
|
||||
disabled: @site_limit_exceeded?
|
||||
) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
|
@ -8,23 +8,44 @@
|
||||
current_step="Install snippet"
|
||||
/>
|
||||
|
||||
<div class="w-full max-w-3xl mt-4 mx-auto flex">
|
||||
<%= form_for @conn, @form_submit_url, [class: "max-w-lg w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8"], fn f -> %>
|
||||
<h2 class="text-xl font-bold dark:text-gray-100">Add JavaScript snippet</h2>
|
||||
<div class="mt-4">
|
||||
<p :if={Plausible.Verification.enabled?()} class="dark:text-gray-100">
|
||||
Include this snippet in the <code><head></code>
|
||||
section of your website.<br />To verify your integration, click the button below to confirm that everything is working correctly.
|
||||
</p>
|
||||
<p :if={not Plausible.Verification.enabled?()} class="dark:text-gray-100">
|
||||
Paste this snippet in the <code><head></code> of your website.
|
||||
</p>
|
||||
<PlausibleWeb.Components.Generic.focus_box>
|
||||
<:title>
|
||||
Add JavaScript snippet
|
||||
</:title>
|
||||
<:subtitle>
|
||||
<p :if={Plausible.Verification.enabled?()} class="dark:text-gray-100">
|
||||
Include this snippet in the <code><head></code>
|
||||
section of your website.<br />To verify your integration, click the button below to confirm that everything is working correctly.
|
||||
</p>
|
||||
<p :if={not Plausible.Verification.enabled?()} class="dark:text-gray-100">
|
||||
Paste this snippet in the <code><head></code> of your website.
|
||||
</p>
|
||||
</:subtitle>
|
||||
|
||||
<:footer>
|
||||
<ol class="list-disc space-y-1 ml-4 mt-1 mb-4">
|
||||
<li>
|
||||
On WordPress? We have
|
||||
<.styled_link new_tab href="https://plausible.io/wordpress-analytics-plugin">
|
||||
a plugin
|
||||
</.styled_link>
|
||||
</li>
|
||||
<li>
|
||||
See more
|
||||
<.styled_link new_tab href="https://plausible.io/docs/integration-guides">
|
||||
integration guides
|
||||
</.styled_link>
|
||||
</li>
|
||||
</ol>
|
||||
</:footer>
|
||||
|
||||
<%= form_for @conn, @form_submit_url, [], fn f -> %>
|
||||
<div>
|
||||
<div class="relative">
|
||||
<%= textarea(f, :domain,
|
||||
id: "snippet_code",
|
||||
class:
|
||||
"transition overflow-hidden bg-gray-100 dark:bg-gray-900 appearance-none border border-transparent rounded w-full p-2 pr-6 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-400 dark:focus:border-gray-500 text-xs mt-4 resize-none",
|
||||
"transition overflow-hidden bg-gray-100 dark:bg-gray-900 appearance-none border border-transparent rounded w-full p-2 pr-6 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-400 dark:focus:border-gray-500 font-mono mt-4 resize-none text-xs",
|
||||
value: render_snippet(@site),
|
||||
rows: 3,
|
||||
readonly: "readonly"
|
||||
@ -32,7 +53,7 @@
|
||||
<a
|
||||
onclick="var textarea = document.getElementById('snippet_code'); textarea.focus(); textarea.select(); document.execCommand('copy');"
|
||||
href="javascript:void(0)"
|
||||
class="no-underline text-indigo-500 text-sm hover:underline"
|
||||
class="no-underline text-indigo-500 hover:underline"
|
||||
>
|
||||
<svg
|
||||
class="absolute text-indigo-500"
|
||||
@ -54,30 +75,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-2 dark:text-gray-100">
|
||||
<p class="text-sm">
|
||||
On WordPress? We have
|
||||
<.styled_link new_tab href="https://plausible.io/wordpress-analytics-plugin">
|
||||
a plugin
|
||||
</.styled_link>
|
||||
</p>
|
||||
|
||||
<p class="text-sm">
|
||||
See more
|
||||
<.styled_link new_tab href="https://plausible.io/docs/integration-guides">
|
||||
integration guides
|
||||
</.styled_link>
|
||||
</p>
|
||||
</div>
|
||||
<% button_label =
|
||||
if Plausible.Verification.enabled?() do
|
||||
"Verify your integration to start collecting data →"
|
||||
"Verify your integration to start collecting data"
|
||||
else
|
||||
"Start collecting data →"
|
||||
"Start collecting data"
|
||||
end %>
|
||||
<%= link(button_label,
|
||||
class: "button mt-4 w-full",
|
||||
to: @form_submit_url
|
||||
) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</PlausibleWeb.Components.Generic.focus_box>
|
||||
|
||||
<div class="w-full max-w-3xl mt-4 mx-auto flex"></div>
|
||||
|
@ -17,64 +17,62 @@
|
||||
current_step="Verify snippet"
|
||||
/>
|
||||
|
||||
<div class="w-full max-w-md mx-auto mt-8">
|
||||
<%= if @site.locked do %>
|
||||
<div
|
||||
class="w-full px-4 py-4 text-sm font-bold text-center text-yellow-800 bg-yellow-100 rounded transition"
|
||||
style="top: 91px"
|
||||
role="alert"
|
||||
>
|
||||
<p>This dashboard is actually locked. You are viewing it with super-admin access</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if @site.locked do %>
|
||||
<div
|
||||
:if={not Plausible.Verification.enabled?()}
|
||||
class="bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-16 relative text-center"
|
||||
class="w-full px-4 py-4 text-sm font-bold text-center text-yellow-800 bg-yellow-100 rounded transition"
|
||||
style="top: 91px"
|
||||
role="alert"
|
||||
>
|
||||
<h2 class="text-xl font-bold dark:text-gray-100">Waiting for first pageview</h2>
|
||||
<h2 class="text-xl font-bold dark:text-gray-100">on <%= @site.domain %></h2>
|
||||
<div class="my-44">
|
||||
<div class="block pulsating-circle top-1/2 left-1/2"></div>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-xs absolute left-0 bottom-0 mb-6 w-full text-center leading-normal">
|
||||
Need to see the snippet again?
|
||||
<.styled_link href={"/#{URI.encode_www_form(@site.domain)}/snippet?flow=#{@conn.params[~s|flow|]}"}>
|
||||
Click here
|
||||
</.styled_link>
|
||||
|
||||
<br /> Not working?
|
||||
<.styled_link
|
||||
new_tab
|
||||
href="https://plausible.io/docs/troubleshoot-integration#check-for-the-plausible-snippet-in-your-source-code"
|
||||
>
|
||||
Troubleshoot the integration
|
||||
</.styled_link>
|
||||
|
||||
<br />
|
||||
<span :if={ee?()}>
|
||||
Check the
|
||||
<.styled_link href={Routes.site_path(@conn, :settings_general, @site.domain)}>
|
||||
site settings
|
||||
</.styled_link>
|
||||
to invite team members, <br /> import historical stats and more.
|
||||
</span>
|
||||
<span :if={ce?()}>
|
||||
Still not working? Ask on our
|
||||
<.styled_link new_tab href="https://github.com/plausible/analytics/discussions">
|
||||
community-supported forum
|
||||
</.styled_link>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<p>This dashboard is actually locked. You are viewing it with super-admin access</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<div
|
||||
:if={not Plausible.Verification.enabled?()}
|
||||
class="bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-16 relative text-center"
|
||||
>
|
||||
<h2 class="text-xl font-bold dark:text-gray-100">Waiting for first pageview</h2>
|
||||
<h2 class="text-xl font-bold dark:text-gray-100">on <%= @site.domain %></h2>
|
||||
<div class="my-44">
|
||||
<div class="block pulsating-circle top-1/2 left-1/2"></div>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-xs absolute left-0 bottom-0 mb-6 w-full text-center leading-normal">
|
||||
Need to see the snippet again?
|
||||
<.styled_link href={"/#{URI.encode_www_form(@site.domain)}/snippet?flow=#{@conn.params[~s|flow|]}"}>
|
||||
Click here
|
||||
</.styled_link>
|
||||
|
||||
<%= if Plausible.Verification.enabled?(),
|
||||
do:
|
||||
live_render(@conn, PlausibleWeb.Live.Verification,
|
||||
session: %{
|
||||
"site_id" => @site.id,
|
||||
"domain" => @site.domain,
|
||||
"slowdown" => @conn.private[:verification_slowdown],
|
||||
"flow" => @conn.params["flow"]
|
||||
}
|
||||
) %>
|
||||
<br /> Not working?
|
||||
<.styled_link
|
||||
new_tab
|
||||
href="https://plausible.io/docs/troubleshoot-integration#check-for-the-plausible-snippet-in-your-source-code"
|
||||
>
|
||||
Troubleshoot the integration
|
||||
</.styled_link>
|
||||
|
||||
<br />
|
||||
<span :if={ee?()}>
|
||||
Check the
|
||||
<.styled_link href={Routes.site_path(@conn, :settings_general, @site.domain)}>
|
||||
site settings
|
||||
</.styled_link>
|
||||
to invite team members, <br /> import historical stats and more.
|
||||
</span>
|
||||
<span :if={ce?()}>
|
||||
Still not working? Ask on our
|
||||
<.styled_link new_tab href="https://github.com/plausible/analytics/discussions">
|
||||
community-supported forum
|
||||
</.styled_link>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= if Plausible.Verification.enabled?(),
|
||||
do:
|
||||
live_render(@conn, PlausibleWeb.Live.Verification,
|
||||
session: %{
|
||||
"site_id" => @site.id,
|
||||
"domain" => @site.domain,
|
||||
"slowdown" => @conn.private[:verification_slowdown],
|
||||
"flow" => @conn.params["flow"]
|
||||
}
|
||||
) %>
|
||||
|
@ -324,7 +324,7 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
describe "GET /login_form" do
|
||||
test "shows the login form", %{conn: conn} do
|
||||
conn = get(conn, "/login")
|
||||
assert html_response(conn, 200) =~ "Enter your email and password"
|
||||
assert html_response(conn, 200) =~ "Enter your account credentials"
|
||||
end
|
||||
end
|
||||
|
||||
@ -409,7 +409,7 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
conn = post(conn, "/login", email: "user@example.com", password: "password")
|
||||
|
||||
assert get_session(conn, :current_user_id) == nil
|
||||
assert html_response(conn, 200) =~ "Enter your email and password"
|
||||
assert html_response(conn, 200) =~ "Enter your account credentials"
|
||||
end
|
||||
|
||||
test "bad password - renders login form again", %{conn: conn} do
|
||||
@ -417,7 +417,7 @@ defmodule PlausibleWeb.AuthControllerTest do
|
||||
conn = post(conn, "/login", email: user.email, password: "wrong")
|
||||
|
||||
assert get_session(conn, :current_user_id) == nil
|
||||
assert html_response(conn, 200) =~ "Enter your email and password"
|
||||
assert html_response(conn, 200) =~ "Enter your account credentials"
|
||||
end
|
||||
|
||||
test "limits login attempts to 5 per minute" do
|
||||
|
@ -22,7 +22,7 @@ defmodule PlausibleWeb.SiteControllerTest do
|
||||
test "shows the site form", %{conn: conn} do
|
||||
conn = get(conn, "/sites/new")
|
||||
|
||||
assert html_response(conn, 200) =~ "Your website details"
|
||||
assert html_response(conn, 200) =~ "Add website info"
|
||||
end
|
||||
|
||||
test "shows onboarding steps regardless of sites provisioned", %{conn: conn1, user: user} do
|
||||
|
Loading…
Reference in New Issue
Block a user