mitgliederverwaltung/lib/mv_web/components/layouts.ex
Moritz 8a8502724d
Some checks failed
continuous-integration/drone/push Build is failing
chore: formatting
2025-07-04 00:59:32 +02:00

136 lines
4.5 KiB
Elixir

defmodule MvWeb.Layouts do
@moduledoc """
This module holds different layouts used by your application.
See the `layouts` directory for all templates available.
The "root" layout is a skeleton rendered as part of the
application router. The "app" layout is rendered as component
in regular views and live views.
"""
use MvWeb, :html
embed_templates "layouts/*"
@doc "The main app layout (Backpex shell, topbar, sidebar, flash, content)"
attr :flash, :map, required: true
attr :socket, :any, default: nil
attr :current_url, :string, default: nil
attr :fluid?, :boolean, default: false
attr :inner_content, :any, required: true
def app(assigns) do
~H"""
<Backpex.HTML.Layout.app_shell fluid={@fluid?}>
<:topbar>
<Backpex.HTML.Layout.topbar_branding />
<Backpex.HTML.Layout.theme_selector
socket={@socket}
themes={[
{"Light", "light"},
{"Dark", "dark"}
]}
/>
<Backpex.HTML.Layout.topbar_dropdown class="mr-2 md:mr-0">
<:label>
<label tabindex="0" class="btn btn-square btn-ghost">
<.icon name="hero-user" class="size-6" />
</label>
</:label>
<li>
<.link navigate={~p"/"} class="text-error flex justify-between hover:bg-base-200">
<p>Logout</p>
<.icon name="hero-arrow-right-on-rectangle" class="size-5" />
</.link>
</li>
</Backpex.HTML.Layout.topbar_dropdown>
</:topbar>
<:sidebar>
<Backpex.HTML.Layout.sidebar_item current_url={@current_url} navigate={~p"/members"}>
<.icon name="hero-users" class="size-5" /> Members
</Backpex.HTML.Layout.sidebar_item>
</:sidebar>
<Backpex.HTML.Layout.flash_messages flash={@flash} />
{@inner_content}
</Backpex.HTML.Layout.app_shell>
"""
end
@doc """
Shows the flash group with standard titles and content.
## Examples
<.flash_group flash={@flash} />
"""
attr :flash, :map, required: true, doc: "the map of flash messages"
attr :id, :string, default: "flash-group", doc: "the optional id of flash container"
def flash_group(assigns) do
~H"""
<div id={@id} aria-live="polite">
<.flash kind={:info} flash={@flash} />
<.flash kind={:error} flash={@flash} />
<.flash
id="client-error"
kind={:error}
title={gettext("We can't find the internet")}
phx-disconnected={show(".phx-client-error #client-error") |> JS.remove_attribute("hidden")}
phx-connected={hide("#client-error") |> JS.set_attribute({"hidden", ""})}
hidden
>
{gettext("Attempting to reconnect")}
<.icon name="hero-arrow-path" class="ml-1 size-3 motion-safe:animate-spin" />
</.flash>
<.flash
id="server-error"
kind={:error}
title={gettext("Something went wrong!")}
phx-disconnected={show(".phx-server-error #server-error") |> JS.remove_attribute("hidden")}
phx-connected={hide("#server-error") |> JS.set_attribute({"hidden", ""})}
hidden
>
{gettext("Attempting to reconnect")}
<.icon name="hero-arrow-path" class="ml-1 size-3 motion-safe:animate-spin" />
</.flash>
</div>
"""
end
@doc """
Provides dark vs light theme toggle based on themes defined in app.css.
See <head> in root.html.heex which applies the theme before page load.
"""
def theme_toggle(assigns) do
~H"""
<div class="card relative flex flex-row items-center border-2 border-base-300 bg-base-300 rounded-full">
<div class="absolute w-1/3 h-full rounded-full border-1 border-base-200 bg-base-100 brightness-200 left-0 [[data-theme=light]_&]:left-1/3 [[data-theme=dark]_&]:left-2/3 transition-[left]" />
<button
phx-click={JS.dispatch("phx:set-theme", detail: %{theme: "system"})}
class="flex p-2 cursor-pointer w-1/3"
>
<.icon name="hero-computer-desktop-micro" class="size-4 opacity-75 hover:opacity-100" />
</button>
<button
phx-click={JS.dispatch("phx:set-theme", detail: %{theme: "light"})}
class="flex p-2 cursor-pointer w-1/3"
>
<.icon name="hero-sun-micro" class="size-4 opacity-75 hover:opacity-100" />
</button>
<button
phx-click={JS.dispatch("phx:set-theme", detail: %{theme: "dark"})}
class="flex p-2 cursor-pointer w-1/3"
>
<.icon name="hero-moon-micro" class="size-4 opacity-75 hover:opacity-100" />
</button>
</div>
"""
end
end