Show a persistent red hint in the reservations section that users must delete their reservation to free the station for others, with matching DE/EN i18n entries.
521 lines
24 KiB
HTML
521 lines
24 KiB
HTML
<!doctype html>
|
|
<html lang="de" data-theme="dark">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>ARCG RemoteStation</title>
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@500;700;800&family=Source+Sans+3:wght@400;500;600&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
<link rel="stylesheet" href="/styles.css" />
|
|
</head>
|
|
<body>
|
|
<div class="page-bg"></div>
|
|
<main class="app-shell reveal">
|
|
<header class="topbar">
|
|
<div class="brand">
|
|
<a class="brand-home-link" href="/rms" aria-label="Zur RMS-Statusseite">
|
|
<div class="brand-mark" id="brandMark">
|
|
<img id="brandLogo" alt="ARCG Logo" hidden />
|
|
<span id="brandFallback">ARCG</span>
|
|
</div>
|
|
</a>
|
|
<div>
|
|
<p class="eyebrow">Amateur Radio Club Graz</p>
|
|
<h1>RemoteStation Control</h1>
|
|
<p id="pageCrumb" class="eyebrow">LOGIN</p>
|
|
</div>
|
|
</div>
|
|
<div class="topbar-actions">
|
|
<a id="currentUserLink" class="ghost-btn" href="/rms/user" hidden>👤 -</a>
|
|
<button id="userMenuButton" class="ghost-btn" type="button" aria-expanded="false" aria-label="Menue oeffnen">☰</button>
|
|
<button id="languageMenuButton" class="ghost-btn" type="button" aria-expanded="false" aria-label="Sprache waehlen">🌐</button>
|
|
<div id="languageMenu" class="language-menu" hidden>
|
|
<select id="menuLanguageSelect" aria-label="Sprache"></select>
|
|
</div>
|
|
<div id="userMenu" class="user-menu" hidden>
|
|
<button id="menuRms" type="button">📡 Status</button>
|
|
<button id="menuSwr" type="button">📈 SWR</button>
|
|
<button id="menuUser" type="button" hidden>⚙ Einstellungen</button>
|
|
<button id="menuHelp" type="button">❓ Hilfe</button>
|
|
<button id="menuPlugins" type="button">🧩 Plugins</button>
|
|
<button id="menuPluginConfig" type="button" hidden>⚙ Plugin Konfig</button>
|
|
<button id="menuProviders" type="button" hidden>🔌 Provider</button>
|
|
<button id="menuUsers" type="button" hidden>👥 User Admin</button>
|
|
<button id="menuApprovals" type="button" hidden>✅ Freigaben</button>
|
|
<button id="menuActivity" type="button" hidden>📜 Aktivitaet</button>
|
|
<button id="menuAdmin" type="button" hidden>🛠 Admin</button>
|
|
<hr class="menu-separator" />
|
|
<button id="logoutBtn" type="button" class="danger">Logout</button>
|
|
</div>
|
|
<button id="themeToggle" class="ghost-btn" type="button" aria-label="Theme wechseln">☀</button>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="view auth-view" id="authView">
|
|
<article class="card login-card stagger" id="authCard">
|
|
<h2>Anmeldung</h2>
|
|
<p class="muted">Anmeldung nur per E-Mail-Adresse. Du bekommst einen Login- oder Bestaetigungslink.</p>
|
|
<p id="maintenanceBanner" class="message" hidden></p>
|
|
|
|
<form id="authForm" class="stack">
|
|
<label class="field">
|
|
<span>E-Mail</span>
|
|
<input id="email" type="email" autocomplete="email" required />
|
|
</label>
|
|
<label class="field">
|
|
<span>Bestaetigungsart</span>
|
|
<select id="authMethodSelect"></select>
|
|
</label>
|
|
<div class="actions">
|
|
<button type="submit" id="loginBtn">Link senden</button>
|
|
</div>
|
|
<div id="otpWrap" class="stack" hidden>
|
|
<label class="field">
|
|
<span>OTP-Code</span>
|
|
<input id="otpCode" type="text" inputmode="numeric" maxlength="6" placeholder="123456" />
|
|
</label>
|
|
<div class="actions">
|
|
<button type="button" id="verifyOtpBtn">Code bestaetigen</button>
|
|
</div>
|
|
</div>
|
|
<p id="authMessage" class="message"></p>
|
|
</form>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="view" id="rmsView" hidden>
|
|
<article class="card page-overview">
|
|
<div class="section-head">
|
|
<h2 id="pageTitle">RMS Status</h2>
|
|
<span id="pageHint" class="pill">Station steuern</span>
|
|
</div>
|
|
</article>
|
|
|
|
<section class="grid-layout" id="pageRms" hidden>
|
|
<article class="card status-card stagger" id="statusCard">
|
|
<div class="section-head">
|
|
<h2>Stationsstatus</h2>
|
|
<span class="pill" id="stationOnlinePill">Pruefe...</span>
|
|
</div>
|
|
<dl class="status-grid">
|
|
<div>
|
|
<dt>Station</dt>
|
|
<dd id="stationName">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Status</dt>
|
|
<dd id="usageStatus">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Aktiver Benutzer</dt>
|
|
<dd id="activeBy">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Seit</dt>
|
|
<dd id="startedAt">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Bis</dt>
|
|
<dd id="endsAt">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Restzeit</dt>
|
|
<dd id="remainingUsage">-</dd>
|
|
</div>
|
|
</dl>
|
|
|
|
<div class="actions" id="stationActions">
|
|
<button id="activateBtn" type="button">Station aktivieren</button>
|
|
<button id="deactivateBtn" type="button" class="danger">Station deaktivieren</button>
|
|
<button id="refreshBtn" type="button" class="ghost-btn">Aktualisieren</button>
|
|
</div>
|
|
|
|
<section id="activationProgress" class="progress-wrap" hidden>
|
|
<div class="progress-head">
|
|
<strong>SWR-Check laeuft</strong>
|
|
<span id="progressText">0%</span>
|
|
</div>
|
|
<div class="progress-track" aria-hidden="true">
|
|
<div id="progressFill" class="progress-fill"></div>
|
|
</div>
|
|
<p id="progressEta" class="muted">Geschaetzte Restzeit: -</p>
|
|
</section>
|
|
|
|
<section id="openwebrxPanel" class="links-wrap" hidden>
|
|
<div class="section-head">
|
|
<h3>OpenWebRX</h3>
|
|
</div>
|
|
<div class="actions">
|
|
<button id="openwebrxOpenBtn" type="button" class="ghost-btn">OpenWebRX laden</button>
|
|
<a id="openwebrxSessionLink" class="link-btn primary-btn" target="_blank" rel="noopener noreferrer" hidden>SDR oeffnen</a>
|
|
</div>
|
|
<p id="openwebrxMessage" class="message"></p>
|
|
<div id="openwebrxSessionAccess" class="stack" hidden>
|
|
<p class="muted">Session Key (Ticket): <code id="openwebrxSessionTicket">-</code></p>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="reservationPanel" class="links-wrap" hidden>
|
|
<div class="section-head">
|
|
<h3>Reservierungen</h3>
|
|
</div>
|
|
<div class="actions">
|
|
<button id="reserveNextBtn" type="button" class="ghost-btn">Naechsten Slot reservieren</button>
|
|
</div>
|
|
<p id="reservationWarning" class="message error">Um die Station fuer andere freizugeben muss die Reservierung geloescht werden.</p>
|
|
<div id="reservationList" class="stack"></div>
|
|
<p id="reservationMessage" class="message"></p>
|
|
</section>
|
|
|
|
<section id="controlsPanel" class="links-wrap" hidden>
|
|
<div class="section-head">
|
|
<h3>Controls</h3>
|
|
<span id="openwebrxTxStatePill" class="pill">TX: unbekannt</span>
|
|
</div>
|
|
<div class="controls-grid">
|
|
<div class="rotor-layout">
|
|
<div class="rotor-main">
|
|
<p id="rotorCurrent" class="muted controls-inline">Rotor: -</p>
|
|
<div class="actions controls-inline">
|
|
<input id="rotorTarget" type="number" min="0" max="360" step="1" placeholder="Azimuth (0-360)" />
|
|
<button id="rotorSetBtn" type="button" class="ghost-btn">Rotor setzen</button>
|
|
</div>
|
|
<div id="rotorPresets" class="actions controls-inline">
|
|
<button type="button" class="ghost-btn" data-azimuth="0">N</button>
|
|
<button type="button" class="ghost-btn" data-azimuth="45">NE</button>
|
|
<button type="button" class="ghost-btn" data-azimuth="90">E</button>
|
|
<button type="button" class="ghost-btn" data-azimuth="135">SE</button>
|
|
<button type="button" class="ghost-btn" data-azimuth="180">S</button>
|
|
<button type="button" class="ghost-btn" data-azimuth="225">SW</button>
|
|
<button type="button" class="ghost-btn" data-azimuth="270">W</button>
|
|
<button type="button" class="ghost-btn" data-azimuth="315">NW</button>
|
|
</div>
|
|
</div>
|
|
<div id="rotorCompass" class="rotor-compass" aria-label="Rotor Kompass">
|
|
<span class="rotor-mark rotor-mark-n">0</span>
|
|
<span class="rotor-mark rotor-mark-e">90</span>
|
|
<span class="rotor-mark rotor-mark-s">180</span>
|
|
<span class="rotor-mark rotor-mark-w">270</span>
|
|
<div id="rotorCompassArrow" class="rotor-arrow" aria-hidden="true"></div>
|
|
<div class="rotor-center" aria-hidden="true"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p id="controlsMessage" class="message"></p>
|
|
</section>
|
|
|
|
<p id="statusMessage" class="message"></p>
|
|
</article>
|
|
|
|
<article class="card stagger" id="swrSummaryCard">
|
|
<div class="section-head">
|
|
<h2>SWR Uebersicht</h2>
|
|
<button id="refreshSwrBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
<p class="muted" id="swrSummaryGeneratedAt">Stand: -</p>
|
|
<p class="muted" id="swrSummaryOverall">Gesamt: -</p>
|
|
<div id="swrSummaryBands" class="stack"></div>
|
|
<div class="actions">
|
|
<button id="runSwrCheckBtn" type="button">SWR Test starten</button>
|
|
</div>
|
|
<p id="swrSummaryMessage" class="message"></p>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageSwr" hidden>
|
|
<article class="card admin-card stagger">
|
|
<div class="section-head swr-page-head">
|
|
<h2>SWR Test-Daten</h2>
|
|
<div class="swr-page-actions">
|
|
<div class="actions">
|
|
<button id="runSwrCheckPageBtn" type="button">SWR Test starten</button>
|
|
<button id="refreshSwrPageBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
<p id="swrPageMessage" class="message swr-page-head-message"></p>
|
|
</div>
|
|
</div>
|
|
<section id="activationProgressSwr" class="progress-wrap" hidden>
|
|
<div class="progress-head">
|
|
<strong>SWR-Check laeuft</strong>
|
|
<span id="progressTextSwr">0%</span>
|
|
</div>
|
|
<div class="progress-track" aria-hidden="true">
|
|
<div id="progressFillSwr" class="progress-fill"></div>
|
|
</div>
|
|
<p id="progressEtaSwr" class="muted">Geschaetzte Restzeit: -</p>
|
|
</section>
|
|
<p id="swrPageGeneratedAt" class="muted">Stand: -</p>
|
|
<p id="swrPageOverall" class="muted">Gesamt: -</p>
|
|
<div id="swrPageBands" class="stack"></div>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageUser" hidden>
|
|
<article class="card stagger" id="userSettingsCard">
|
|
<h2>Benutzer-Einstellungen</h2>
|
|
<p class="muted">Hier findest du nur deine persoenlichen Einstellungen.</p>
|
|
<dl class="status-grid">
|
|
<div>
|
|
<dt>E-Mail</dt>
|
|
<dd id="settingsEmail">-</dd>
|
|
</div>
|
|
<div>
|
|
<dt>Rolle</dt>
|
|
<dd id="settingsRole">-</dd>
|
|
</div>
|
|
</dl>
|
|
<label class="field" style="margin-top: 0.6rem">
|
|
<span>Praeferierte Authentifizierung</span>
|
|
<select id="settingsAuthMethodSelect"></select>
|
|
</label>
|
|
<label class="field" style="margin-top: 0.6rem">
|
|
<span>Sprache</span>
|
|
<select id="settingsLanguageSelect"></select>
|
|
</label>
|
|
<div class="actions">
|
|
<button id="settingsSaveAuthMethodBtn" type="button">Authentifizierung speichern</button>
|
|
<button id="settingsSaveLanguageBtn" type="button" class="ghost-btn">Sprache speichern</button>
|
|
<button id="settingsThemeBtn" type="button">Theme wechseln</button>
|
|
<button id="settingsRefreshBtn" type="button" class="ghost-btn">Status neu laden</button>
|
|
</div>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageHelp" hidden>
|
|
<article class="card admin-card stagger" id="helpCard">
|
|
<div class="section-head">
|
|
<h2 id="helpTitle">Hilfe</h2>
|
|
<button id="refreshHelpBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
<section class="plugin-block">
|
|
<h3 id="helpQuickStartTitle">Schnellstart</h3>
|
|
<ol id="helpQuickStartSteps" class="stack"></ol>
|
|
</section>
|
|
<div id="helpSections" class="stack"></div>
|
|
<p id="helpMessage" class="message"></p>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pagePlugins" hidden>
|
|
<article class="card admin-card stagger" id="pluginControlsCard">
|
|
<div class="section-head">
|
|
<h2>Plugin Controls</h2>
|
|
<span class="pill">Dynamisch</span>
|
|
</div>
|
|
<div id="pluginControls" class="stack"></div>
|
|
<p id="pluginMessage" class="message"></p>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pagePluginConfig" hidden>
|
|
<article class="card admin-card stagger" id="pluginsConfigCard" hidden>
|
|
<div class="section-head">
|
|
<h2>Plugin Konfiguration</h2>
|
|
<button id="refreshPluginsPageBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
<h3>Plugin Verwaltung</h3>
|
|
<div id="pluginsAdminConfig" class="stack"></div>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageProviders" hidden>
|
|
<article class="card admin-card stagger" id="providersCard">
|
|
<div class="section-head">
|
|
<h2>Provider Verwaltung</h2>
|
|
<button id="refreshProvidersBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
<h3>Capability Matrix</h3>
|
|
<div id="providersCapabilityMatrix" class="stack"></div>
|
|
<hr class="separator" />
|
|
<h3>Provider Zuordnung</h3>
|
|
<div id="providersAdminConfig" class="stack"></div>
|
|
<p id="providersMessage" class="message"></p>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageAdmin" hidden>
|
|
<article class="card admin-card stagger" id="adminCard" hidden>
|
|
<div class="section-head">
|
|
<h2>Admin</h2>
|
|
<span class="pill">Steuerung</span>
|
|
</div>
|
|
|
|
<div class="actions">
|
|
<button id="setOnlineBtn" type="button">Online setzen</button>
|
|
<button id="setOfflineBtn" type="button" class="danger">Offline setzen</button>
|
|
<button id="forceReleaseBtn" type="button" class="ghost-btn">Force Release</button>
|
|
<button id="refreshAuditBtn" type="button" class="ghost-btn">Audit laden</button>
|
|
</div>
|
|
|
|
<div class="stack" style="margin-top: 1rem">
|
|
<label class="field">
|
|
<span>Benutzerrolle aendern</span>
|
|
<input id="roleEmail" type="email" placeholder="user@example.com" />
|
|
</label>
|
|
<div class="actions">
|
|
<button id="setRoleAdminBtn" type="button">Als Admin setzen</button>
|
|
<button id="setRoleOperatorBtn" type="button" class="ghost-btn">Als Operator setzen</button>
|
|
</div>
|
|
</div>
|
|
|
|
<p id="adminMessage" class="message"></p>
|
|
<pre id="auditLog" class="audit-log"></pre>
|
|
|
|
<hr class="separator" />
|
|
<div class="section-head">
|
|
<h3>Branding</h3>
|
|
<span class="pill">Logo Upload</span>
|
|
</div>
|
|
<div class="stack" style="margin-top: 0.6rem">
|
|
<label class="field">
|
|
<span>Logo Light Theme</span>
|
|
<input id="logoLightFile" type="file" accept=".png,.jpg,.jpeg,.svg,.webp,image/png,image/jpeg,image/svg+xml,image/webp" />
|
|
</label>
|
|
<div class="actions">
|
|
<button id="uploadLogoLightBtn" type="button" class="ghost-btn">Light-Logo hochladen</button>
|
|
<button id="removeLogoLightBtn" type="button" class="danger">Light-Logo entfernen</button>
|
|
</div>
|
|
<label class="field">
|
|
<span>Logo Dark Theme</span>
|
|
<input id="logoDarkFile" type="file" accept=".png,.jpg,.jpeg,.svg,.webp,image/png,image/jpeg,image/svg+xml,image/webp" />
|
|
</label>
|
|
<div class="actions">
|
|
<button id="uploadLogoDarkBtn" type="button" class="ghost-btn">Dark-Logo hochladen</button>
|
|
<button id="removeLogoDarkBtn" type="button" class="danger">Dark-Logo entfernen</button>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="separator" />
|
|
<div class="section-head">
|
|
<h3>Wartungsmodus</h3>
|
|
<span class="pill" id="maintenanceStatePill">Unbekannt</span>
|
|
</div>
|
|
<label class="field" style="margin-top: 0.6rem">
|
|
<span>Hinweistext</span>
|
|
<input id="maintenanceMessageInput" type="text" placeholder="Wartungsmodus aktiv. Login ist derzeit deaktiviert." />
|
|
</label>
|
|
<div class="actions">
|
|
<button id="maintenanceEnableBtn" type="button" class="danger">Wartungsmodus aktivieren</button>
|
|
<button id="maintenanceDisableBtn" type="button" class="ghost-btn">Wartungsmodus deaktivieren</button>
|
|
</div>
|
|
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageUsers" hidden>
|
|
<article class="card admin-card stagger">
|
|
<div class="section-head">
|
|
<h2>Benutzerverwaltung</h2>
|
|
<div class="actions">
|
|
<label class="field compact-field">
|
|
<span>Suche</span>
|
|
<input id="usersFilterQuery" type="text" placeholder="mail@domain" />
|
|
</label>
|
|
<label class="field compact-field">
|
|
<span>Rolle</span>
|
|
<select id="usersFilterRole">
|
|
<option value="all">Alle</option>
|
|
<option value="admin">Admin</option>
|
|
<option value="approver">Approver</option>
|
|
<option value="operator">Operator</option>
|
|
</select>
|
|
</label>
|
|
<label class="field compact-field">
|
|
<span>Status</span>
|
|
<select id="usersFilterStatus">
|
|
<option value="all">Alle</option>
|
|
<option value="active">Aktiv</option>
|
|
<option value="pending_approval">Pending Approval</option>
|
|
<option value="pending_verification">Pending Verification</option>
|
|
<option value="denied">Denied</option>
|
|
</select>
|
|
</label>
|
|
<button id="refreshUsersBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
</div>
|
|
<div id="usersAdmin" class="stack"></div>
|
|
<p id="usersMessage" class="message"></p>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageApprovals" hidden>
|
|
<article class="card admin-card stagger">
|
|
<div class="section-head">
|
|
<h2>Freigaben</h2>
|
|
<div class="actions">
|
|
<label class="field compact-field">
|
|
<span>Suche</span>
|
|
<input id="approvalsFilterQuery" type="text" placeholder="mail@domain" />
|
|
</label>
|
|
<label class="field compact-field">
|
|
<span>Status</span>
|
|
<select id="approvalsFilterStatus">
|
|
<option value="all">Alle</option>
|
|
<option value="pending">Pending</option>
|
|
<option value="approved">Approved</option>
|
|
<option value="rejected">Rejected</option>
|
|
</select>
|
|
</label>
|
|
<button id="approvalsFilterOpenBtn" type="button" class="ghost-btn">Nur offen</button>
|
|
<button id="approvalsFilterAllBtn" type="button" class="ghost-btn">Alle</button>
|
|
<button id="refreshApprovalsBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
</div>
|
|
<div id="approvalsList" class="stack"></div>
|
|
<p id="approvalsMessage" class="message"></p>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid-layout" id="pageActivity" hidden>
|
|
<article class="card admin-card stagger">
|
|
<div class="section-head">
|
|
<h2>Aktivitaetslog</h2>
|
|
<div class="actions">
|
|
<label class="field compact-field">
|
|
<span>Suche</span>
|
|
<input id="activityFilterQuery" type="text" placeholder="mail oder text" />
|
|
</label>
|
|
<label class="field compact-field">
|
|
<span>Typ</span>
|
|
<select id="activityFilterType">
|
|
<option value="all">Alle</option>
|
|
<option value="auth.request_access">Link angefordert</option>
|
|
<option value="station.activate.start">Start Aktivierung</option>
|
|
<option value="station.activate.done">Aktivierung ok</option>
|
|
<option value="station.activate.failed">Aktivierung Fehler</option>
|
|
<option value="station.deactivate">Manuell beendet</option>
|
|
<option value="station.deactivate.timeout">Automatisch beendet</option>
|
|
</select>
|
|
</label>
|
|
<button id="refreshActivityBtn" type="button" class="ghost-btn">Neu laden</button>
|
|
</div>
|
|
</div>
|
|
<div id="activityLogList" class="stack"></div>
|
|
<p id="activityMessage" class="message"></p>
|
|
</article>
|
|
</section>
|
|
</section>
|
|
|
|
<nav id="mobileNav" class="mobile-nav" hidden>
|
|
<button id="mobileNavRms" type="button">📡 RMS</button>
|
|
<button id="mobileNavSwr" type="button">📈 SWR</button>
|
|
<button id="mobileNavUser" type="button" hidden>⚙ Einst.</button>
|
|
<button id="mobileNavHelp" type="button">❓ Hilfe</button>
|
|
<button id="mobileNavPlugins" type="button">🧩 Plugins</button>
|
|
<button id="mobileNavPluginConfig" type="button" hidden>⚙ PluginCfg</button>
|
|
<button id="mobileNavUsers" type="button" hidden>👥 User</button>
|
|
<button id="mobileNavApprovals" type="button" hidden>✅ Freigaben</button>
|
|
<button id="mobileNavActivity" type="button" hidden>📜 Log</button>
|
|
<button id="mobileNavAdmin" type="button" hidden>🛠 Admin</button>
|
|
</nav>
|
|
</main>
|
|
|
|
<script src="/app.js" defer></script>
|
|
</body>
|
|
</html>
|