lib/monitorex/layouts.ex

defmodule Monitorex.Layouts do
  @moduledoc """
  LiveView layouts for the Monitorex dashboard.

  Provides a root layout with sidebar navigation, flash messages, and
  a main content area. Fully responsive — sidebar collapses on mobile.
  """

  use Phoenix.LiveView

  @doc """
  Renders the root layout HTML document.

  Includes:
    * HTML5 doctype and responsive viewport meta
    * Title "Monitorex"
    * CSS and JS asset links
    * Sidebar navigation with icons for Outbound, Inbound, and Cluster nodes
    * Flash group rendering
    * Main content area yielding `@inner_content`
  """
  def root(assigns) do
    ~H"""
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Monitorex</title>
        <link rel="stylesheet" href={"/dashboard-assets/app.css"} />
        <script defer src={"/dashboard-assets/app.js"}></script>
      </head>
      <body>
        <button id="nav-toggle" class="nav-toggle" aria-label="Toggle navigation">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <line x1="3" y1="6" x2="21" y2="6" />
            <line x1="3" y1="12" x2="21" y2="12" />
            <line x1="3" y1="18" x2="21" y2="18" />
          </svg>
        </button>

        <nav>
          <a href="/" class="nav-brand">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <path d="M22 12h-4l-3 9L9 3l-3 9H2" />
            </svg>
            Monitorex
          </a>

          <div class="nav-section-label">Dashboard</div>
          <div class="nav-links">
            <a href="/">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 002 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z" />
                <polyline points="3.27 6.96 12 12.01 20.73 6.96" />
                <line x1="12" y1="22.08" x2="12" y2="12" />
              </svg>
              Outbound
            </a>
            <a href="/outbound_recent">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
              </svg>
              Outbound Recent
            </a>
            <a href="/timeline">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
                <line x1="9" y1="3" x2="9" y2="21" />
                <line x1="3" y1="9" x2="21" y2="9" />
              </svg>
              Timeline
            </a>
          </div>

          <div class="nav-section-label">Inbound</div>
          <div class="nav-links">
            <a href="/inbound">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" />
              </svg>
              Overview
            </a>
            <a href="/inbound_consumers">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2" />
                <circle cx="9" cy="7" r="4" />
                <path d="M23 21v-2a4 4 0 00-3-3.87" />
                <path d="M16 3.13a4 4 0 010 7.75" />
              </svg>
              Consumers
            </a>
            <a href="/inbound_recent">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <circle cx="12" cy="12" r="10" />
                <polyline points="12 6 12 12 16 14" />
              </svg>
              Recent
            </a>
          </div>

          <div class="nav-section-label">Cluster</div>
          <div class="nav-links">
            <a href="/cluster">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <rect x="2" y="2" width="8" height="8" rx="2" />
                <rect x="14" y="2" width="8" height="8" rx="2" />
                <rect x="2" y="14" width="8" height="8" rx="2" />
                <rect x="14" y="14" width="8" height="8" rx="2" />
              </svg>
              Nodes
            </a>
          </div>
        </nav>

        <main>
          <.flash_group flash={@flash} />
          <%= @inner_content %>
        </main>
      </body>
    </html>
    """
  end

  def flash_group(assigns) do
    ~H"""
    <div class="flash-group">
      <%= for {kind, msg} <- Enum.filter(@flash, fn {_k, v} -> v end) do %>
        <div class={"flash flash-#{kind}"} role="alert">
          <%= msg %>
        </div>
      <% end %>
    </div>
    """
  end
end