<!doctype html>

<!--
  Copyright (C) 2025 l5yth

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<html lang="en" data-theme="<%= initial_theme %>">
<head>
  <meta name="color-scheme" content="dark light">
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <% meta_title_html = Rack::Utils.escape_html(meta_title) %>
  <% meta_name_html = Rack::Utils.escape_html(meta_name) %>
  <% meta_description_html = Rack::Utils.escape_html(meta_description) %>
  <% request_path = request.path.to_s.empty? ? "/" : request.path %>
  <% canonical_url = "#{request.base_url}#{request_path}" %>
  <% canonical_html = Rack::Utils.escape_html(canonical_url) %>
  <% logo_url = "#{request.base_url}/potatomesh-logo.svg" %>
  <% logo_url_html = Rack::Utils.escape_html(logo_url) %>
  <% logo_alt_html = Rack::Utils.escape_html("#{meta_name} logo") %>
  <title><%= meta_title_html %></title>
  <meta name="application-name" content="<%= meta_name_html %>" />
  <meta name="apple-mobile-web-app-title" content="<%= meta_name_html %>" />
  <meta name="description" content="<%= meta_description_html %>" />
  <link rel="canonical" href="<%= canonical_html %>" />
  <meta property="og:title" content="<%= meta_title_html %>" />
  <meta property="og:site_name" content="<%= meta_name_html %>" />
  <meta property="og:description" content="<%= meta_description_html %>" />
  <meta property="og:type" content="website" />
  <meta property="og:url" content="<%= canonical_html %>" />
  <meta property="og:image" content="<%= logo_url_html %>" />
  <meta property="og:image:alt" content="<%= logo_alt_html %>" />
  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="<%= meta_title_html %>" />
  <meta name="twitter:description" content="<%= meta_description_html %>" />
  <meta name="twitter:image" content="<%= logo_url_html %>" />
  <meta name="twitter:image:alt" content="<%= logo_alt_html %>" />
  <link rel="icon" type="image/x-icon" href="/favicon.ico" />
  <link rel="icon" type="image/svg+xml" href="/potatomesh-logo.svg" />
  <link rel="stylesheet" href="/assets/styles/base.css" />
  <script src="/assets/js/theme.js" defer></script>
  <script src="/assets/js/background.js" defer></script>

  <!-- Leaflet CSS/JS (CDN) -->  <!-- Leaflet CSS/JS (CDN) -->
  <link
    rel="stylesheet"
    href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
    integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
    crossorigin=""
  />
  <script
    src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
    integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
    crossorigin=""
  ></script>







</head>
  <% body_classes = [] %>
  <% body_classes << "dark" if initial_theme == "dark" %>
<body class="<%= body_classes.join(" ") %>" data-app-config="<%= Rack::Utils.escape_html(app_config_json) %>" data-theme="<%= initial_theme %>">
  <div class="site-header">
    <h1 class="site-title">
      <img src="/potatomesh-logo.svg" alt="" aria-hidden="true" />
      <span class="site-title-text"><%= site_name %></span>
    </h1>
    <% if !private_mode && federation_enabled %>
      <div class="instance-selector">
        <label class="visually-hidden" for="instanceSelect">Select a region</label>
        <select id="instanceSelect" class="instance-select" aria-label="Select instance region">
          <option value=""><%= Rack::Utils.escape_html("Select region ...") %></option>
        </select>
      </div>
    <% end %>
  </div>
  <div class="row meta">
    <div class="meta-info">
      <div class="refresh-row">
        <p id="refreshInfo" class="refresh-info" aria-live="polite"><%= channel %> (<%= frequency %>) — active nodes: …</p>
        <div class="refresh-actions">
          <label class="auto-refresh-toggle"><input type="checkbox" id="autoRefresh" checked /> Auto-refresh every <%= refresh_interval_seconds %> seconds</label>
          <button id="refreshBtn" type="button">Refresh now</button>
          <span id="status" class="pill">loading…</span>
        </div>
      </div>
    </div>
    <div class="controls">
      <label><input type="checkbox" id="fitBounds" checked /> Auto-fit map</label>
      <div class="filter-input">
        <input type="text" id="filterInput" placeholder="Filter nodes" />
        <button type="button" id="filterClear" class="filter-clear" aria-label="Clear filter" hidden>&times;</button>
      </div>
      <button id="themeToggle" class="icon-button" type="button" aria-label="Toggle dark mode"><span aria-hidden="true">🌙</span></button>
      <button id="infoBtn" class="icon-button" type="button" aria-haspopup="dialog" aria-controls="infoOverlay" aria-label="Show site information"><span aria-hidden="true">ℹ️</span></button>
    </div>
  </div>

  <div id="infoOverlay" class="info-overlay" role="dialog" aria-modal="true" aria-labelledby="infoTitle" hidden>
    <div class="info-dialog" tabindex="-1">
      <button type="button" class="info-close" id="infoClose" aria-label="Close site information">×</button>
      <h2 id="infoTitle" class="info-title">About <%= site_name %></h2>
      <dl class="info-details">
        <dt>Channel</dt>
        <dd><%= channel %></dd>
        <dt>Frequency</dt>
        <dd><%= frequency %></dd>
        <dt>Map center</dt>
        <dd><%= format("%.5f, %.5f", map_center_lat, map_center_lon) %></dd>
        <dt>Visible range</dt>
        <dd>Nodes within roughly <%= max_distance_km %> km of the center are shown.</dd>
        <% if contact_link && !contact_link.empty? %>
          <dt>Chat</dt>
          <% if contact_link_url %>
            <dd><a href="<%= contact_link_url %>" target="_blank" rel="noreferrer noopener"><%= contact_link %></a></dd>
          <% else %>
            <dd><%= contact_link %></dd>
          <% end %>
        <% end %>
      </dl>
    </div>
  </div>

  <div class="map-row">
    <% unless private_mode %>
      <div id="chat" aria-label="Chat log"></div>
    <% end %>
    <div class="map-panel" id="mapPanel">
      <div id="map" role="region" aria-label="Nodes map"></div>
      <div class="map-toolbar" role="group" aria-label="Map view controls">
        <button id="mapFullscreenToggle" type="button" aria-pressed="false" aria-label="Enter full screen map view">
          <svg class="icon-fullscreen-enter" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
            <path
              d="M4 8V4h4m12 4V4h-4M4 16v4h4m12-4v4h-4"
              fill="none"
              stroke="currentColor"
              stroke-width="1.8"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
          <svg class="icon-fullscreen-exit" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
            <path
              d="M9 9L5 5m0 4V5m4 0H5m10 4 4-4m0 4V5m-4 0h4M9 15l-4 4m0-4v4m4 0H5m10-4 4 4m0-4v4m-4 0h4"
              fill="none"
              stroke="currentColor"
              stroke-width="1.8"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>
        </button>
      </div>
    </div>
  </div>

  <table id="nodes">
    <thead>
      <tr>
        <th class="nodes-col nodes-col--node-id"><button type="button" class="sort-button" data-sort-key="node_id" data-sort-label="Node ID">Node ID <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--short-name"><button type="button" class="sort-button" data-sort-key="short_name" data-sort-label="Short Name">Short <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--long-name"><button type="button" class="sort-button" data-sort-key="long_name" data-sort-label="Long Name">Long Name <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--last-seen"><button type="button" class="sort-button" data-sort-key="last_heard" data-sort-label="Last Seen">Last Seen <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--role"><button type="button" class="sort-button" data-sort-key="role" data-sort-label="Role">Role <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--hw-model"><button type="button" class="sort-button" data-sort-key="hw_model" data-sort-label="Hardware Model">HW Model <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--battery"><button type="button" class="sort-button" data-sort-key="battery_level" data-sort-label="Battery Level">Battery <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--voltage"><button type="button" class="sort-button" data-sort-key="voltage" data-sort-label="Voltage">Voltage <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--uptime"><button type="button" class="sort-button" data-sort-key="uptime_seconds" data-sort-label="Uptime">Uptime <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--channel-util"><button type="button" class="sort-button" data-sort-key="channel_utilization" data-sort-label="Channel Utilization">Channel Util <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--air-util-tx"><button type="button" class="sort-button" data-sort-key="air_util_tx" data-sort-label="Air Utilization (Tx)">Air Util Tx <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--temperature"><button type="button" class="sort-button" data-sort-key="temperature" data-sort-label="Temperature">Temperature <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--humidity"><button type="button" class="sort-button" data-sort-key="relative_humidity" data-sort-label="Humidity">Humidity <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--pressure"><button type="button" class="sort-button" data-sort-key="barometric_pressure" data-sort-label="Barometric Pressure">Pressure <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--latitude"><button type="button" class="sort-button" data-sort-key="latitude" data-sort-label="Latitude">Latitude <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--longitude"><button type="button" class="sort-button" data-sort-key="longitude" data-sort-label="Longitude">Longitude <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--altitude"><button type="button" class="sort-button" data-sort-key="altitude" data-sort-label="Altitude">Altitude <span class="sort-indicator" aria-hidden="true"></span></button></th>
        <th class="nodes-col nodes-col--last-position"><button type="button" class="sort-button" data-sort-key="position_time" data-sort-label="Last Position">Last Position <span class="sort-indicator" aria-hidden="true"></span></button></th>
      </tr>
    </thead>
    <tbody></tbody>
  </table>

  <template id="shortInfoOverlayTemplate">
    <div class="short-info-overlay" role="dialog" aria-modal="false">
      <button type="button" class="short-info-close" aria-label="Close node details">×</button>
      <div class="short-info-content"></div>
    </div>
  </template>

  <footer class="app-footer">
    <div class="footer-content">
      <span class="footer-brand">PotatoMesh</span>
      <% if version && !version.empty? %>
        <span class="mono"><%= version %></span>
      <% end %>
      <span class="footer-separator" aria-hidden="true">—</span>
      <span class="footer-links">
        GitHub:
        <a href="https://github.com/l5yth/potato-mesh" target="_blank">l5yth/potato-mesh</a>
        <% if contact_link && !contact_link.empty? %>
          <span class="footer-separator" aria-hidden="true">—</span>
          <span class="footer-contact">
            <%= site_name %> chat:
            <% if contact_link_url %>
              <a href="<%= contact_link_url %>" target="_blank"><%= contact_link %></a>
            <% else %>
              <%= contact_link %>
            <% end %>
          </span>
        <% end %>
      </span>
    </div>
  </footer>



  <script>
    const CHAT_ENABLED = <%= private_mode ? "false" : "true" %>;
  </script>
  <script type="module" src="/assets/js/app/index.js"></script>
</body>
</html>
