defmodule PlausibleWeb.Components.TwoFactor do
@moduledoc """
Reusable components specific to 2FA
"""
use PlausibleWeb, :component
attr :text, :string, required: true
attr :scale, :integer, default: 4
def qr_code(assigns) do
qr_code =
assigns.text
|> EQRCode.encode()
|> EQRCode.svg(%{width: 160})
assigns = assign(assigns, :code, qr_code)
~H"""
{Phoenix.HTML.raw(@code)}
"""
end
attr :id, :string, default: "verify-button"
attr :form, :any, required: true
attr :field, :any, required: true
attr :class, :string, default: ""
attr :show_button?, :boolean, default: true
attr :autofocus?, :boolean, default: false
attr :error, :string, default: nil
def verify_2fa_input(assigns) do
assigns = assign(assigns, :field, assigns[:form][assigns[:field]])
~H"""
<.otp_input
field={@field}
length={6}
oninvalid={@show_button? && "document.getElementById('#{@id}').disabled = false"}
autofocus={@autofocus? && "autofocus"}
/>
{@error}
<.button
:if={@show_button?}
type="submit"
id={@id}
mt?={false}
class="w-full [&>span.label-enabled]:block [&>span.label-disabled]:hidden [&[disabled]>span.label-enabled]:hidden [&[disabled]>span.label-disabled]:block"
>
Verify
<.spinner class="inline-block h-5 w-5 mr-2 text-white dark:text-gray-400" /> Verifying...
"""
end
attr :id, :string, required: true
attr :state_param, :string, required: true
attr :form_data, :any, required: true
attr :form_target, :string, required: true
attr :onsubmit, :string, default: nil
attr :title, :string, required: true
slot :icon, required: true
slot :inner_block, required: true
slot :buttons, required: true
def modal(assigns) do
~H"""
<.form :let={f} for={@form_data} action={@form_target} onsubmit={@onsubmit}>
{render_slot(@icon)}
{@title}
{render_slot(@inner_block, f)}
{render_slot(@buttons)}
<.button
type="button"
x-on:click={"#{@state_param} = false"}
class="w-full sm:w-auto mr-2"
theme="secondary"
>
Cancel
"""
end
end