8 lines
4.8 KiB
JSON
8 lines
4.8 KiB
JSON
{
|
|
"html": "<button id=\"abort-btn\">\u26a0 ABORT MISSION</button>\n<div id=\"status\">Standby</div>\n<div id=\"confirm-overlay\">\n <div id=\"confirm-box\">\n <p>Abort mission?<br>Vehicle will hold position<br>and await instruction.</p>\n <div class=\"btn-row\">\n <button id=\"confirm-yes\">ABORT</button>\n <button id=\"confirm-no\">Cancel</button>\n </div>\n <div id=\"countdown\"></div>\n </div>\n</div>",
|
|
|
|
"css": "*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n:root {\n --bg: #09111a; --text0: #d8eeff; --text1: #8fb3d4;\n --red: #ff3a5a; --red-dim: #7a1a28; --green: #00e09a; --mono: 'Courier New', monospace;\n}\nbody {\n background: var(--bg); color: var(--text0); font-family: var(--mono);\n height: 100vh; display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n overflow: hidden; padding: 12px; gap: 10px;\n}\n#abort-btn {\n width: 100%; padding: 14px 0;\n background: var(--red-dim); border: 2px solid var(--red); border-radius: 6px;\n color: var(--red); font-family: var(--mono); font-size: 15px; font-weight: bold;\n letter-spacing: 0.15em; text-transform: uppercase; cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n}\n#abort-btn:hover { background: #2a0c18; box-shadow: 0 0 16px var(--red); }\n#abort-btn:active { background: var(--red); color: #fff; }\n#abort-btn:disabled { background: #1a0a10; border-color: #3a1020; color: var(--red-dim); cursor: not-allowed; box-shadow: none; }\n#confirm-overlay {\n display: none; position: fixed; inset: 0;\n background: rgba(0,0,0,0.7);\n align-items: center; justify-content: center; z-index: 10;\n}\n#confirm-overlay.active { display: flex; }\n#confirm-box {\n background: #100510; border: 2px solid var(--red); border-radius: 8px;\n padding: 18px; max-width: 220px; text-align: center;\n box-shadow: 0 0 30px var(--red);\n}\n#confirm-box p { font-size: 12px; color: var(--text0); line-height: 1.5; margin-bottom: 14px; }\n.btn-row { display: flex; gap: 8px; justify-content: center; }\n#confirm-yes {\n flex: 1; padding: 8px; background: var(--red); border: none;\n border-radius: 4px; color: #fff; font-family: var(--mono);\n font-size: 12px; font-weight: bold; cursor: pointer; letter-spacing: 0.08em;\n}\n#confirm-yes:hover { background: #ff6080; }\n#confirm-no {\n flex: 1; padding: 8px; background: transparent;\n border: 1px solid var(--text1); border-radius: 4px;\n color: var(--text1); font-family: var(--mono); font-size: 12px; cursor: pointer;\n}\n#confirm-no:hover { border-color: var(--text0); color: var(--text0); }\n#countdown { font-size: 10px; color: var(--red-dim); margin-top: 8px; }\n#status { font-size: 10px; color: var(--text1); text-align: center; min-height: 14px; }\n#status.ok { color: var(--green); }\n#status.err { color: var(--red); }",
|
|
|
|
"js": "var FASTAPI_HOST = 'http://blueos.local:8081';\nvar AUTO_DISMISS_SEC = 10;\nvar abortBtn = document.getElementById('abort-btn');\nvar overlay = document.getElementById('confirm-overlay');\nvar confirmYes = document.getElementById('confirm-yes');\nvar confirmNo = document.getElementById('confirm-no');\nvar countdownEl = document.getElementById('countdown');\nvar statusEl = document.getElementById('status');\nvar dismissTimer = null;\nvar countdownVal = AUTO_DISMISS_SEC;\n\nfunction showConfirm() {\n overlay.classList.add('active');\n countdownVal = AUTO_DISMISS_SEC;\n countdownEl.textContent = 'Auto-cancel in ' + countdownVal + 's';\n dismissTimer = setInterval(function() {\n countdownVal--;\n countdownEl.textContent = 'Auto-cancel in ' + countdownVal + 's';\n if (countdownVal <= 0) hideConfirm();\n }, 1000);\n}\n\nfunction hideConfirm() {\n overlay.classList.remove('active');\n clearInterval(dismissTimer);\n dismissTimer = null;\n countdownEl.textContent = '';\n}\n\nasync function sendAbort() {\n hideConfirm();\n abortBtn.disabled = true;\n statusEl.className = '';\n statusEl.textContent = 'Sending abort\u2026';\n try {\n var res = await fetch(FASTAPI_HOST + '/abort', {\n method: 'POST',\n headers: {'Content-Type':'application/json'},\n body: JSON.stringify({abort:true}),\n signal: AbortSignal.timeout(5000)\n });\n if (res.ok) {\n statusEl.className = 'ok';\n statusEl.textContent = 'Abort sent \u2014 vehicle holding';\n } else {\n statusEl.className = 'err';\n statusEl.textContent = 'Server error: ' + res.status;\n abortBtn.disabled = false;\n }\n } catch(err) {\n statusEl.className = 'err';\n statusEl.textContent = 'Network error \u2014 check connection';\n abortBtn.disabled = false;\n console.error('[Abort]', err);\n }\n}\n\nabortBtn.addEventListener('click', function() { if (!abortBtn.disabled) showConfirm(); });\nconfirmYes.addEventListener('click', sendAbort);\nconfirmNo.addEventListener('click', hideConfirm);"
|
|
}
|