defmodule MvWeb.Layouts.Sidebar do @moduledoc """ Sidebar navigation component used in the drawer layout """ use MvWeb, :html attr :current_user, :map, default: nil, doc: "The current user" attr :club_name, :string, required: true, doc: "The name of the club" attr :mobile, :boolean, default: false, doc: "Whether this is mobile view" def sidebar(assigns) do ~H""" """ end defp sidebar_header(assigns) do ~H"""
Mila Logo {@club_name} <%= unless @mobile do %> <% end %>
""" end defp sidebar_menu(assigns) do ~H""" """ end attr :href, :string, required: true, doc: "Navigation path" attr :icon, :string, required: true, doc: "Heroicon name" attr :label, :string, required: true, doc: "Menu item label" defp menu_item(assigns) do ~H"""
  • <.link navigate={@href} class="flex items-center gap-3 tooltip tooltip-right focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2" data-tip={@label} role="menuitem" > <.icon name={@icon} class="size-5 shrink-0" aria-hidden="true" /> {@label}
  • """ end attr :icon, :string, required: true, doc: "Heroicon name for the menu group" attr :label, :string, required: true, doc: "Menu group label" slot :inner_block, required: true, doc: "Submenu items" defp menu_group(assigns) do ~H""" """ end attr :href, :string, required: true, doc: "Navigation path for submenu item" attr :label, :string, required: true, doc: "Submenu item label" defp menu_subitem(assigns) do ~H"""
  • <.link navigate={@href} role="menuitem" class="focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"> {@label}
  • """ end attr :current_user, :map, default: nil, doc: "The current user" defp sidebar_footer(assigns) do ~H"""
    <.theme_toggle /> <%= if @current_user do %> <.user_menu current_user={@current_user} /> <% end %>
    """ end defp theme_toggle(assigns) do ~H""" """ end attr :current_user, :map, default: nil, doc: "The current user" defp user_menu(assigns) do # Defensive check: ensure current_user and email exist # current_user might be a struct, so we need to handle both maps and structs # email might be an Ash.CiString, so we use to_string/1 (not String.to_string/1) email = case assigns.current_user do nil -> "" %{email: email_val} when not is_nil(email_val) -> to_string(email_val) _ -> "" end first_letter = if email != "" do String.first(email) |> String.upcase() else "?" end user_id = case assigns.current_user do nil -> nil %{id: id_val} when not is_nil(id_val) -> id_val _ -> nil end # Store computed values in assigns to avoid HEEx warnings assigns = assign(assigns, :email, email) assigns = assign(assigns, :first_letter, first_letter) assigns = assign(assigns, :user_id, user_id) ~H""" """ end end