defmodule Legendary.CoreWeb.Helpers do
@moduledoc """
HTML helpers for our styled (Tailwind) forms.
"""
use Phoenix.HTML
use Phoenix.Component
alias Phoenix.Flash
alias Legendary.AuthWeb.CoreComponents
import ShorterMaps
defdelegate current_user(a), to: Legendary.AuthWeb.Helpers
defdelegate has_role?(a, b), to: Legendary.AuthWeb.Helpers
def changeset_error_block(changeset) do
assigns = %{changeset: changeset}
~H"""
<CoreComponents.changeset_error_block changeset={@changeset} />
"""
end
def flash_block(%{assigns: assigns}) do
~H"""
<div class="fixed w-full px-4 z-50 mt-20">
<%= [info: "green", error: "red"] |> Enum.map(fn {level, color} -> %>
<%= if Flash.get(@flash, level) do %>
<div class={
"relative bg-#{color}-100 lg:w-1/2 w-full p-5 object-right rounded shadow-xl m-auto mb-5 js-flash"
}>
<div class={"flex justify-between text-#{color}-700"}>
<div class="flex space-x-3">
<div class="flex-1 leading-tight text-sm font-medium">
<%= Flash.get(@flash, level) %>
</div>
</div>
<div class="flex-none js-flash-closer">
×
</div>
</div>
</div>
<% end %>
<% end) %>
</div>
"""
end
def styled_input(form, field, opts \\ [], options \\ nil, block_list \\ []) do
{inner_block, _} = Keyword.pop(block_list, :do, []) || []
{type, rest_opts} = Keyword.pop(opts, :type, input_type(form, field))
{class, rest_opts} = Keyword.pop(rest_opts, :class)
{label_text, rest_opts} = Keyword.pop(rest_opts, :label)
{input_helper, _rest_opts} = Keyword.pop(rest_opts, :input_helper, input_type(form, field))
error_class =
if Keyword.get_values(form.errors || [], field) |> Enum.any?() do
" border border-red-500"
else
""
end
assigns =
~M{class, inner_block, error_class, field, input_helper, label_text, type, options, opts, form}
~H"""
<CoreComponents.styled_input
class={@class}
error_class={@error_class}
field={@field}
input_helper={@input_helper}
label_text={@label_text}
type={@type}
options={@options}
form={@form}
{@opts}
>
<%= @inner_block %>
</CoreComponents.styled_input>
"""
end
def styled_button(inner_block, opts \\ []) do
assigns = ~M{inner_block, opts}
~H"""
<CoreComponents.styled_button {@opts}>
<%= @inner_block %>
</CoreComponents.styled_button>
"""
end
def styled_button_link(inner_block, opts) do
{href, opts} = Keyword.pop(opts, :to, "#")
rest =
opts
|> Enum.into(%{})
|> Map.merge(~M{href})
assigns = ~M{inner_block, rest}
~H"""
<CoreComponents.styled_button_link {@rest}>
<%= @inner_block %>
</CoreComponents.styled_button_link>
"""
end
def styled_button_live_patch(inner_block, opts) do
{to, opts} = Keyword.pop(opts, :to, "#")
assigns = ~M{inner_block, opts, to}
~H"""
<CoreComponents.styled_button_live_patch opts={@opts} to={@to}>
<%= @inner_block %>
</CoreComponents.styled_button_live_patch>
"""
end
def styled_button_live_redirect(inner_block, opts) do
{to, opts} = Keyword.pop(opts, :to, "#")
assigns = ~M{inner_block, opts, to}
~H"""
<CoreComponents.styled_button_live_redirect opts={@opts} to={@to}>
<%= @inner_block %>
</CoreComponents.styled_button_live_redirect>
"""
end
def paginator(~M{first, current_page, last} = assigns) do
pages =
[first, current_page - 1, current_page, current_page + 1, last]
|> Enum.sort()
|> Enum.filter(&(&1 >= first && &1 <= last))
|> Enum.dedup()
assigns = assigns |> Map.put(:pages, pages)
~H"""
<%= for page_number <- @pages do %>
<%= @callback.(@first..@last, page_number) %>
<% end %>
"""
end
def group_rounding_class(
first..last,
current,
[first_class, middle_class, last_class] \\ ["rounded-l", "", "rounded-r"]
) do
cond do
first == last -> "#{first_class} #{last_class}"
current == first -> first_class
current == last -> last_class
true -> middle_class
end
end
@spec floating_form(any, atom | %{action: any}, [{:do, any}, ...]) :: {:safe, [...]}
def floating_form(title, changeset, do: inner_block) do
assigns = ~M{changeset, inner_block, title}
~H"""
<CoreComponents.floating_form changeset={@changeset} title={@title}>
<%= @inner_block %>
</CoreComponents.floating_form>
"""
end
def floating_page_wrapper(do: inner_block) do
assigns = ~M{inner_block}
~H"""
<CoreComponents.floating_page_wrapper>
<%= @inner_block %>
</CoreComponents.floating_page_wrapper>
"""
end
def pow_extension_enabled?(extension) do
{extensions, _rest} = Application.get_env(:core, :pow) |> Keyword.pop(:extensions, [])
Enum.any?(extensions, &(&1 == extension))
end
end