html constant

String const html

HTML index page

Implementation

static const String html = r'''<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>at_activate - APKAM Enrollment Manager</title>
  <script>
      (function () {
          var theme = null;
          try { theme = localStorage.getItem('at_activate_theme'); } catch (e) {}
          if (theme !== 'light' && theme !== 'dark') {
              theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
          }
          document.documentElement.setAttribute('data-theme', theme);
      })();
  </script>
  <link rel="stylesheet" href="/styles.css">
  <!-- Favicon -->
  <link rel="icon" type="image/png" href="/favicon.png"/>
</head>
<body>
  <header class="app-bar">
      <div class="app-bar-brand">
          <img class="app-bar-logo" src="/favicon.png" alt="" width="24" height="24">
          <span class="app-bar-name">at_activate_web</span>
          <span class="app-bar-version">v1.4.0</span>
      </div>
      <div class="app-bar-end">
          <button type="button" class="theme-toggle-btn" id="theme-toggle-btn" aria-label="Dark mode" aria-pressed="false" onclick="toggleTheme()"><svg class="theme-icon-moon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M13.5 9.5A5.5 5.5 0 0 1 6.5 2.5a5.5 5.5 0 1 0 7 7z"/></svg><svg class="theme-icon-sun" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="3"/><path d="M8 1.5v1.5M8 13v1.5M1.5 8h1.5M13 8h1.5M3.4 3.4l1.1 1.1M11.5 11.5l1.1 1.1M3.4 12.6l1.1-1.1M11.5 4.5l1.1-1.1"/></svg></button>
          <button type="button" id="back-btn" class="atsign-switcher" onclick="goBack()" title="Back to Atsign selection">
              <span class="atsign-switcher-label">Switch Atsign</span>
              <span id="atsign-display" class="atsign-switcher-handle">Loading...</span>
          </button>
      </div>
  </header>

  <div class="container">
      <main>
          <div class="management-page">
              <details class="management-section management-section-yellow">
                  <summary class="management-section-summary">
                      <div>
                          <h2>Manage OTP</h2>
                          <p>Configure OTP expiry for enrollment command generation.</p>
                      </div>
                      <span class="management-section-toggle" aria-hidden="true"></span>
                  </summary>
                  <div class="management-section-body">
                      <div class="otp-management-grid">
                          <label class="api-v4-field">
                              <span>OTP Expiry</span>
                              <input type="text" id="otp-expiry-input" value="1h" placeholder='For example 2d,1h,10m,20s,999ms' />
                          </label>
                          <label class="auto-approval-checkbox">
                              <input type="checkbox" id="custom-otp-enabled" onchange="toggleCustomOtpInput()" />
                              <span>Custom OTP</span>
                          </label>
                          <label class="api-v4-field" id="custom-otp-field">
                              <span>OTP Value</span>
                              <input type="text" id="custom-otp-input" placeholder="e.g. ABC123 (6 alphanumeric chars)" maxlength="6" disabled />
                          </label>
                      </div>
                      <div class="management-command-actions">
                          <button type="button" class="btn-primary" onclick="generateOtp()">Generate OTP</button>
                      </div>
                      <div class="otp-history-section">
                          <div class="otp-inline-label">Generated OTPs</div>
                          <div class="otp-history-empty" id="otp-history-empty">No OTPs generated yet.</div>
                          <div class="otp-history-table-wrap" id="otp-history-table-wrap" hidden>
                              <table class="otp-history-table">
                                  <thead>
                                      <tr>
                                          <th>Generated At</th>
                                          <th>Expiry</th>
                                          <th>Expires At</th>
                                          <th>OTP</th>
                                          <th></th>
                                      </tr>
                                  </thead>
                                  <tbody id="otp-history-body"></tbody>
                              </table>
                          </div>
                      </div>
                  </div>
              </details>

              <details class="management-section management-section-orange">
                  <summary class="management-section-summary">
                      <div>
                          <h2>Generate Enrollment Command</h2>
                          <p>Generate an enrollment command for a NoPorts device or a Personal Agent.</p>
                      </div>
                      <span class="management-section-toggle" aria-hidden="true"></span>
                  </summary>
                  <div class="management-section-body">
                      <div class="management-command-actions">
                          <span class="management-command-label">Profiles</span>
                          <button type="button" class="api-v4-secondary" onclick="applyEnrollmentProfile('blank')">Blank</button>
                          <button type="button" class="api-v4-secondary" onclick="showNoPortsWizard()">NoPorts Device</button>
                          <button type="button" class="api-v4-secondary" onclick="showPersonalAgentWizard()">Personal Agent</button>
                      </div>
                      <div class="enrollment-command-grid">
                          <label class="api-v4-field">
                              <span class="api-v4-param-label">deviceName</span>
                              <input type="text" id="enroll-device-name" placeholder="e.g. laptop-1, server-2, pi-office" />
                          </label>
                          <label class="api-v4-field">
                              <span class="api-v4-param-label">appName</span>
                              <input type="text" id="enroll-app-name" placeholder="e.g. noports" />
                          </label>
                      </div>
                      <label class="api-v4-field api-v4-field-wide">
                          <span>Use OTP</span>
                          <select id="enrollment-otp-select"></select>
                      </label>
                      <div class="api-v4-field">
                          <span>Namespaces + Permissions</span>
                          <div id="namespace-permission-list" class="namespace-permission-list"></div>
                          <div class="management-command-actions">
                              <button type="button" class="api-v4-secondary" onclick="addNamespacePermissionRow()">Add Namespace</button>
                          </div>
                          <div class="namespace-preview" id="namespace-preview"></div>
                      </div>
                      <div class="management-command-actions">
                          <button type="button" class="btn-primary" onclick="generateEnrollmentCommand()">Generate Command</button>
                          <button type="button" class="api-v4-secondary" id="copy-enrollment-command-btn" onclick="copyEnrollmentCommand()" hidden>Copy Command</button>
                      </div>
                      <div class="otp-inline-result" id="enrollment-command-result" hidden>
                          <div class="otp-inline-label">Enrollment Command</div>
                          <code class="otp-inline-value otp-inline-command" id="enrollment-command-value"></code>
                          <div class="otp-inline-meta" id="enrollment-command-meta"></div>
                      </div>
                  </div>
              </details>

              <details class="management-section management-section-green">
                  <summary class="management-section-summary">
                      <div>
                          <h2>Auto Approval Service</h2>
                          <p>Automatically approve matching enrollments with at_activate auto.</p>
                      </div>
                      <span class="management-section-toggle" aria-hidden="true"></span>
                  </summary>
                  <div class="management-section-body">
                      <div class="auto-approval-grid">
                          <label class="api-v4-field">
                              <span>App Name Regex</span>
                              <input type="text" id="auto-approval-app-regex" placeholder="e.g. ^noports$" />
                          </label>
                          <label class="api-v4-field">
                              <span>Device Name Regex</span>
                              <input type="text" id="auto-approval-device-regex" placeholder="e.g. ^pi-.*$" />
                          </label>
                          <label class="api-v4-field">
                              <span>Limit</span>
                              <input type="number" id="auto-approval-limit" min="1" value="1" />
                          </label>
                          <label class="api-v4-field auto-approval-checkbox-field">
                              <span>Approve Existing</span>
                              <label class="auto-approval-checkbox">
                                  <input type="checkbox" id="auto-approval-approve-existing" />
                                  <span>Approve matching pending requests before listening</span>
                              </label>
                          </label>
                      </div>
                      <div class="management-command-actions">
                          <button type="button" class="btn-primary" onclick="createAutoApprovalService()">Create Service</button>
                      </div>
                      <div class="otp-history-section">
                          <div class="otp-inline-label">Configured Services</div>
                          <div class="otp-history-empty" id="auto-approval-empty">No auto approval services created yet.</div>
                          <div id="auto-approval-list" class="auto-approval-list" hidden></div>
                      </div>
                  </div>
              </details>

              <details class="management-section management-section-blue" open>
                  <summary class="management-section-summary">
                      <div>
                          <h2>APKAM Key Management</h2>
                          <p>Refresh enrollments, filter results, search records, and manage APKAM keys.</p>
                      </div>
                      <span class="management-section-toggle" aria-hidden="true"></span>
                  </summary>
                  <div class="management-section-body">
                  <div class="controls">
                      <button id="refresh-btn" onclick="loadEnrollments()">Refresh</button>
                      <div class="search-box">
                          <input type="text" id="search-input" placeholder="Search by app, device, enrollment ID, or namespace..." oninput="filterEnrollments()">
                          <button id="clear-search" onclick="clearSearch()" style="display: none;">&times;</button>
                      </div>
                  </div>

                  <div class="filter-controls">
                      <div class="filter">
                          <label>
                              <input type="checkbox" id="show-all" checked onchange="filterEnrollments()">
                              Show all
                          </label>
                          <label>
                              <input type="checkbox" id="show-approved" onchange="filterEnrollments()">
                              Approved
                          </label>
                          <label>
                              <input type="checkbox" id="show-pending" onchange="filterEnrollments()">
                              Pending
                          </label>
                          <label>
                              <input type="checkbox" id="show-revoked" onchange="filterEnrollments()">
                              Revoked
                          </label>
                          <label>
                              <input type="checkbox" id="show-denied" onchange="filterEnrollments()">
                              Denied
                          </label>
                      </div>
                      <div id="match-count" class="match-count"></div>
                  </div>

                  <div id="loading" class="loading">Loading enrollments...</div>
                  <div id="error" class="error" style="display: none;"></div>

                  <div id="enrollments-container" class="enrollments-grid">
                  </div>
                  </div>
              </details>

              <details class="management-section management-section-slate" id="history-section">
                  <summary class="management-section-summary">
                      <div>
                          <h2>History</h2>
                          <p>Recent APKAM, OTP, and auto approval activity for this Atsign.</p>
                      </div>
                      <span class="management-section-toggle" aria-hidden="true"></span>
                  </summary>
                  <div class="management-section-body">
                      <div class="otp-history-empty" id="history-empty">No history yet.</div>
                      <div id="history-list" class="history-list" hidden></div>
                      <div class="management-command-actions">
                          <button type="button" class="api-v4-secondary" id="history-load-more-btn" onclick="loadMoreHistory()" hidden>Load More</button>
                      </div>
                  </div>
              </details>
          </div>
      </main>
  </div>

  <script src="/api_v4.js"></script>
  <script src="/script.js"></script>
</body>
</html>
''';