consolidate core and admin components
This commit is contained in:
parent
12eb4a7daa
commit
14fd43faf2
5 changed files with 198 additions and 180 deletions
|
@ -58,7 +58,7 @@ defmodule ChiyaWeb do
|
||||||
layout: {ChiyaWeb.Layouts, :app}
|
layout: {ChiyaWeb.Layouts, :app}
|
||||||
|
|
||||||
# Import admin components
|
# Import admin components
|
||||||
import ChiyaWeb.AdminComponents
|
import ChiyaWeb.CoreComponents
|
||||||
|
|
||||||
unquote(html_helpers())
|
unquote(html_helpers())
|
||||||
end
|
end
|
||||||
|
@ -69,7 +69,7 @@ defmodule ChiyaWeb do
|
||||||
use Phoenix.LiveComponent
|
use Phoenix.LiveComponent
|
||||||
|
|
||||||
# Import admin components
|
# Import admin components
|
||||||
import ChiyaWeb.AdminComponents
|
import ChiyaWeb.CoreComponents
|
||||||
|
|
||||||
unquote(html_helpers())
|
unquote(html_helpers())
|
||||||
end
|
end
|
||||||
|
@ -84,7 +84,7 @@ defmodule ChiyaWeb do
|
||||||
only: [get_csrf_token: 0, view_module: 1, view_template: 1]
|
only: [get_csrf_token: 0, view_module: 1, view_template: 1]
|
||||||
|
|
||||||
# Import admin components
|
# Import admin components
|
||||||
import ChiyaWeb.AdminComponents
|
import ChiyaWeb.CoreComponents
|
||||||
|
|
||||||
# Include general helpers for rendering HTML
|
# Include general helpers for rendering HTML
|
||||||
unquote(html_helpers())
|
unquote(html_helpers())
|
||||||
|
@ -112,7 +112,6 @@ defmodule ChiyaWeb do
|
||||||
# HTML escaping functionality
|
# HTML escaping functionality
|
||||||
import Phoenix.HTML
|
import Phoenix.HTML
|
||||||
# Core UI components and translation
|
# Core UI components and translation
|
||||||
import ChiyaWeb.CoreComponents
|
|
||||||
import ChiyaWeb.Gettext
|
import ChiyaWeb.Gettext
|
||||||
|
|
||||||
# Shortcut for generating JS commands
|
# Shortcut for generating JS commands
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
defmodule ChiyaWeb.AdminComponents do
|
|
||||||
use Phoenix.Component
|
|
||||||
|
|
||||||
use Phoenix.VerifiedRoutes,
|
|
||||||
endpoint: ChiyaWeb.Endpoint,
|
|
||||||
router: ChiyaWeb.Router,
|
|
||||||
statics: ChiyaWeb.static_paths()
|
|
||||||
|
|
||||||
import ChiyaWeb.CoreComponents
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Renders a horizontal line
|
|
||||||
"""
|
|
||||||
def line(assigns) do
|
|
||||||
~H"""
|
|
||||||
<hr class="my-6 dark:border-gray-700" />
|
|
||||||
"""
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Renders a UI for uploading files
|
|
||||||
"""
|
|
||||||
|
|
||||||
attr :upload, :map, required: true
|
|
||||||
attr :cancel_upload, :string, default: "cancel-upload"
|
|
||||||
|
|
||||||
def live_upload(assigns) do
|
|
||||||
~H"""
|
|
||||||
<div>
|
|
||||||
<.live_file_input upload={@upload} class="dark:text-gray-300" />
|
|
||||||
|
|
||||||
<section phx-drop-target={@upload.ref}>
|
|
||||||
<%= for entry <- @upload.entries do %>
|
|
||||||
<article class="upload-entry">
|
|
||||||
<figure>
|
|
||||||
<.live_img_preview entry={entry} />
|
|
||||||
<figcaption class="dark:text-gray-100"><%= entry.client_name %></figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
<div class="flex">
|
|
||||||
<%!-- entry.progress will update automatically for in-flight entries --%>
|
|
||||||
<progress value={entry.progress} max="100" class="w-full">
|
|
||||||
<%= entry.progress %>%
|
|
||||||
</progress>
|
|
||||||
|
|
||||||
<%!-- a regular click event whose handler will invoke Phoenix.LiveView.cancel_upload/3 --%>
|
|
||||||
<button
|
|
||||||
class="px-2 dark:text-white"
|
|
||||||
type="button"
|
|
||||||
phx-click="cancel-upload"
|
|
||||||
phx-value-ref={entry.ref}
|
|
||||||
aria-label="cancel"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
|
|
||||||
<%= for err <- upload_errors(@upload, entry) do %>
|
|
||||||
<p class="alert alert-danger"><%= upload_error_to_string(err) %></p>
|
|
||||||
<% end %>
|
|
||||||
</article>
|
|
||||||
<% end %>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
|
||||||
Renders the admin menu bar
|
|
||||||
"""
|
|
||||||
|
|
||||||
attr :current_user, :map, required: true
|
|
||||||
attr :settings, :map, required: true
|
|
||||||
|
|
||||||
def admin_bar(assigns) do
|
|
||||||
~H"""
|
|
||||||
<ul class="sticky top-0 backdrop-blur-sm z-10 flex items-center gap-4 py-3 px-4 sm:px-6 lg:px-8 bg-white/30 dark:bg-black/30">
|
|
||||||
<li>
|
|
||||||
<.link
|
|
||||||
href={~p"/"}
|
|
||||||
class="flex gap-3 text-sm leading-6 font-semibold text-gray-900 dark:text-gray-100 dark:hover:text-gray-300 hover:text-gray-700"
|
|
||||||
>
|
|
||||||
<%= @settings.title %>
|
|
||||||
</.link>
|
|
||||||
</li>
|
|
||||||
<li class="flex-1"></li>
|
|
||||||
<%= if @current_user do %>
|
|
||||||
<li>
|
|
||||||
<.link
|
|
||||||
href={~p"/admin"}
|
|
||||||
class="text-sm leading-6 text-gray-900 dark:text-gray-100 dark:hover:text-gray-300 hover:text-gray-700"
|
|
||||||
>
|
|
||||||
Admin
|
|
||||||
</.link>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<.link
|
|
||||||
href={~p"/user/log_out"}
|
|
||||||
method="delete"
|
|
||||||
class="text-sm leading-6 text-gray-900 dark:text-gray-100 dark:hover:text-gray-300 hover:text-gray-700"
|
|
||||||
>
|
|
||||||
Log out
|
|
||||||
</.link>
|
|
||||||
</li>
|
|
||||||
<% else %>
|
|
||||||
<li>
|
|
||||||
<.link
|
|
||||||
href={~p"/user/log_in"}
|
|
||||||
class="text-xs leading-6 text-gray-900 dark:text-gray-100 font-semibold dark:hover:text-gray-300 hover:text-gray-700"
|
|
||||||
>
|
|
||||||
Log in
|
|
||||||
</.link>
|
|
||||||
</li>
|
|
||||||
<% end %>
|
|
||||||
<li>
|
|
||||||
<.darkmode_toggle />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
"""
|
|
||||||
end
|
|
||||||
|
|
||||||
defp upload_error_to_string(:too_large), do: "Too large"
|
|
||||||
defp upload_error_to_string(:too_many_files), do: "You have selected too many files"
|
|
||||||
defp upload_error_to_string(:not_accepted), do: "You have selected an unacceptable file type"
|
|
||||||
end
|
|
|
@ -653,6 +653,118 @@ defmodule ChiyaWeb.CoreComponents do
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Renders a horizontal line
|
||||||
|
"""
|
||||||
|
def line(assigns) do
|
||||||
|
~H"""
|
||||||
|
<hr class="my-6 dark:border-gray-700" />
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Renders a UI for uploading files
|
||||||
|
"""
|
||||||
|
|
||||||
|
attr :upload, :map, required: true
|
||||||
|
attr :cancel_upload, :string, default: "cancel-upload"
|
||||||
|
|
||||||
|
def live_upload(assigns) do
|
||||||
|
~H"""
|
||||||
|
<div>
|
||||||
|
<.live_file_input upload={@upload} class="dark:text-gray-300" />
|
||||||
|
|
||||||
|
<section phx-drop-target={@upload.ref}>
|
||||||
|
<%= for entry <- @upload.entries do %>
|
||||||
|
<article class="upload-entry">
|
||||||
|
<figure>
|
||||||
|
<.live_img_preview entry={entry} />
|
||||||
|
<figcaption class="dark:text-gray-100"><%= entry.client_name %></figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<%!-- entry.progress will update automatically for in-flight entries --%>
|
||||||
|
<progress value={entry.progress} max="100" class="w-full">
|
||||||
|
<%= entry.progress %>%
|
||||||
|
</progress>
|
||||||
|
|
||||||
|
<%!-- a regular click event whose handler will invoke Phoenix.LiveView.cancel_upload/3 --%>
|
||||||
|
<button
|
||||||
|
class="px-2 dark:text-white"
|
||||||
|
type="button"
|
||||||
|
phx-click="cancel-upload"
|
||||||
|
phx-value-ref={entry.ref}
|
||||||
|
aria-label="cancel"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
|
||||||
|
<%= for err <- upload_errors(@upload, entry) do %>
|
||||||
|
<p class="alert alert-danger"><%= upload_error_to_string(err) %></p>
|
||||||
|
<% end %>
|
||||||
|
</article>
|
||||||
|
<% end %>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Renders the admin menu bar
|
||||||
|
"""
|
||||||
|
|
||||||
|
attr :current_user, :map, required: true
|
||||||
|
attr :settings, :map, required: true
|
||||||
|
|
||||||
|
def admin_bar(assigns) do
|
||||||
|
~H"""
|
||||||
|
<ul class="sticky top-0 backdrop-blur-sm z-10 flex items-center gap-4 py-3 px-4 sm:px-6 lg:px-8 bg-white/30 dark:bg-black/30">
|
||||||
|
<li>
|
||||||
|
<.link
|
||||||
|
href={~p"/"}
|
||||||
|
class="flex gap-3 text-sm leading-6 font-semibold text-gray-900 dark:text-gray-100 dark:hover:text-gray-300 hover:text-gray-700"
|
||||||
|
>
|
||||||
|
<%= @settings.title %>
|
||||||
|
</.link>
|
||||||
|
</li>
|
||||||
|
<li class="flex-1"></li>
|
||||||
|
<%= if @current_user do %>
|
||||||
|
<li>
|
||||||
|
<.link
|
||||||
|
href={~p"/admin"}
|
||||||
|
class="text-sm leading-6 text-gray-900 dark:text-gray-100 dark:hover:text-gray-300 hover:text-gray-700"
|
||||||
|
>
|
||||||
|
Admin
|
||||||
|
</.link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<.link
|
||||||
|
href={~p"/user/log_out"}
|
||||||
|
method="delete"
|
||||||
|
class="text-sm leading-6 text-gray-900 dark:text-gray-100 dark:hover:text-gray-300 hover:text-gray-700"
|
||||||
|
>
|
||||||
|
Log out
|
||||||
|
</.link>
|
||||||
|
</li>
|
||||||
|
<% else %>
|
||||||
|
<li>
|
||||||
|
<.link
|
||||||
|
href={~p"/user/log_in"}
|
||||||
|
class="text-xs leading-6 text-gray-900 dark:text-gray-100 font-semibold dark:hover:text-gray-300 hover:text-gray-700"
|
||||||
|
>
|
||||||
|
Log in
|
||||||
|
</.link>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
<li>
|
||||||
|
<.darkmode_toggle />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
## JS Commands
|
## JS Commands
|
||||||
|
|
||||||
def show(js \\ %JS{}, selector) do
|
def show(js \\ %JS{}, selector) do
|
||||||
|
@ -734,4 +846,9 @@ defmodule ChiyaWeb.CoreComponents do
|
||||||
def translate_errors(errors, field) when is_list(errors) do
|
def translate_errors(errors, field) when is_list(errors) do
|
||||||
for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts})
|
for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp upload_error_to_string(:too_large), do: "Too large"
|
||||||
|
defp upload_error_to_string(:too_many_files), do: "You have selected too many files"
|
||||||
|
defp upload_error_to_string(:not_accepted), do: "You have selected an unacceptable file type"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
defmodule ChiyaWeb.Layouts do
|
defmodule ChiyaWeb.Layouts do
|
||||||
use ChiyaWeb, :html
|
use ChiyaWeb, :html
|
||||||
|
|
||||||
import ChiyaWeb.PublicComponents
|
import ChiyaWeb.PublicComponents, only: [divider: 1]
|
||||||
|
|
||||||
embed_templates "layouts/*"
|
embed_templates "layouts/*"
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,35 @@ defmodule ChiyaWeb.PublicComponents do
|
||||||
import ChiyaWeb.Format
|
import ChiyaWeb.Format
|
||||||
import ChiyaWeb.Markdown, only: [render: 1]
|
import ChiyaWeb.Markdown, only: [render: 1]
|
||||||
import Phoenix.HTML, only: [raw: 1]
|
import Phoenix.HTML, only: [raw: 1]
|
||||||
import ChiyaWeb.CoreComponents
|
|
||||||
|
@doc """
|
||||||
|
Renders a [Hero Icon](https://heroicons.com).
|
||||||
|
|
||||||
|
Hero icons come in three styles – outline, solid, and mini.
|
||||||
|
By default, the outline style is used, but solid an mini may
|
||||||
|
be applied by using the `-solid` and `-mini` suffix.
|
||||||
|
|
||||||
|
You can customize the size and colors of the icons by setting
|
||||||
|
width, height, and background color classes.
|
||||||
|
|
||||||
|
Icons are extracted from your `priv/hero_icons` directory and bundled
|
||||||
|
within your compiled app.css by the plugin in your `assets/tailwind.config.js`.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<.icon name="hero-cake" />
|
||||||
|
<.icon name="hero-cake-solid" />
|
||||||
|
<.icon name="hero-cake-mini" />
|
||||||
|
<.icon name="hero-bolt" class="bg-blue-500 w-10 h-10" />
|
||||||
|
"""
|
||||||
|
attr :name, :string, required: true
|
||||||
|
attr :class, :string, default: nil
|
||||||
|
|
||||||
|
def icon(%{name: "hero-" <> _} = assigns) do
|
||||||
|
~H"""
|
||||||
|
<span class={[@name, @class]} />
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Renders a middot as divider
|
Renders a middot as divider
|
||||||
|
@ -164,58 +192,58 @@ defmodule ChiyaWeb.PublicComponents do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def comment_form(assigns) do
|
# def comment_form(assigns) do
|
||||||
~H"""
|
# ~H"""
|
||||||
<.simple_form :let={f} for={@changeset} action="" class="bg-theme-background -m-3">
|
# <.simple_form :let={f} for={@changeset} action="" class="bg-theme-background -m-3">
|
||||||
<.error :if={@changeset.action}>
|
# <.error :if={@changeset.action}>
|
||||||
Oops, something went wrong! Please check the errors below.
|
# Oops, something went wrong! Please check the errors below.
|
||||||
</.error>
|
# </.error>
|
||||||
<.input
|
# <.input
|
||||||
field={f[:author_name]}
|
# field={f[:author_name]}
|
||||||
type="text"
|
# type="text"
|
||||||
placeholder="Name"
|
# placeholder="Name"
|
||||||
class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/40 dark:placeholder-theme-base/60 dark:focus:border-theme-base/60 dark:focus:border-theme-base/60"
|
# class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/40 dark:placeholder-theme-base/60 dark:focus:border-theme-base/60 dark:focus:border-theme-base/60"
|
||||||
/>
|
# />
|
||||||
<.input
|
# <.input
|
||||||
field={f[:content]}
|
# field={f[:content]}
|
||||||
type="textarea"
|
# type="textarea"
|
||||||
placeholder="Content"
|
# placeholder="Content"
|
||||||
rows="3"
|
# rows="3"
|
||||||
class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/60 dark:placeholder-theme-base/60 focus:border-theme-base/60 dark:focus:border-theme-base/60"
|
# class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/60 dark:placeholder-theme-base/60 focus:border-theme-base/60 dark:focus:border-theme-base/60"
|
||||||
/>
|
# />
|
||||||
<.input field={f[:note_id]} type="hidden" />
|
# <.input field={f[:note_id]} type="hidden" />
|
||||||
<:actions>
|
# <:actions>
|
||||||
<.button>Submit Comment</.button>
|
# <.button>Submit Comment</.button>
|
||||||
</:actions>
|
# </:actions>
|
||||||
</.simple_form>
|
# </.simple_form>
|
||||||
"""
|
# """
|
||||||
end
|
# end
|
||||||
|
|
||||||
def comment_list(assigns) do
|
# def comment_list(assigns) do
|
||||||
~H"""
|
# ~H"""
|
||||||
<%= if not Enum.empty?(assigns.note.comments) do %>
|
# <%= if not Enum.empty?(assigns.note.comments) do %>
|
||||||
<.line />
|
# <.line />
|
||||||
|
|
||||||
<h2 class="mb-6 text-theme-base"><%= Enum.count(assigns.note.comments) %> Comments</h2>
|
# <h2 class="mb-6 text-theme-base"><%= Enum.count(assigns.note.comments) %> Comments</h2>
|
||||||
|
|
||||||
<aside id="comments" class="flex flex-col gap-6">
|
# <aside id="comments" class="flex flex-col gap-6">
|
||||||
<%= for comment <- assigns.note.comments do %>
|
# <%= for comment <- assigns.note.comments do %>
|
||||||
<article class="text-theme-base bg-theme-base/10 p-1">
|
# <article class="text-theme-base bg-theme-base/10 p-1">
|
||||||
<header class="flex flex-row justify-between">
|
# <header class="flex flex-row justify-between">
|
||||||
<strong class="text-theme-primary"><%= comment.author_name %></strong>
|
# <strong class="text-theme-primary"><%= comment.author_name %></strong>
|
||||||
<span class="text-theme-dim"><%= from_now(comment.inserted_at) %></span>
|
# <span class="text-theme-dim"><%= from_now(comment.inserted_at) %></span>
|
||||||
</header>
|
# </header>
|
||||||
<p><%= comment.content %></p>
|
# <p><%= comment.content %></p>
|
||||||
</article>
|
# </article>
|
||||||
<% end %>
|
# <% end %>
|
||||||
</aside>
|
# </aside>
|
||||||
<% else %>
|
# <% else %>
|
||||||
<.line />
|
# <.line />
|
||||||
|
|
||||||
<h2 class="mb-6 text-theme-base">No comments yet.</h2>
|
# <h2 class="mb-6 text-theme-base">No comments yet.</h2>
|
||||||
<% end %>
|
# <% end %>
|
||||||
"""
|
# """
|
||||||
end
|
# end
|
||||||
|
|
||||||
defp gallery_name(note), do: "gallery-#{note.id}"
|
defp gallery_name(note), do: "gallery-#{note.id}"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue