Add root terminal

This commit is contained in:
Peter Stockings
2025-12-24 11:03:44 +11:00
parent 0c89a0f745
commit 4f34696c72
2 changed files with 91 additions and 1 deletions

View File

@@ -591,6 +591,33 @@
</div>
</div>
</section>
<!-- Root Terminal -->
<section id="root-terminal" class="station" data-label="[ STATION: ROOT_TERMINAL ]">
<div class="station-header">
<h2>Server Shell Access</h2>
<a href="#top" class="back-to-top">[^ BACK_TO_TOP]</a>
</div>
<div class="panel terminal-box" style="margin-top: 0; border-color: #ff555566;">
<div class="terminal-header" style="border-bottom-color: #ff555566;">
<div class="terminal-label" style="color: #ff5555;">ROOT@DOKKU:~$</div>
<button class="copy-btn" onclick="copyLogs('terminal-output')"
style="border-color: #ff555566; color: #ff5555;">COPY BUFFER</button>
</div>
<div id="terminal-output" class="terminal-body"
style="height: 400px; font-size: 13px; background: #000;">
<div class="log-line log-info">Dokku Terminal initialized. Ready for commands.</div>
</div>
<div style="display: flex; background: #000; padding: 10px; border-top: 1px solid #ff555566;">
<span style="color: #00ff88; font-weight: 700; margin-right: 10px;">$</span>
<input type="text" id="terminal-input" placeholder="Enter command..." spellcheck="false"
autocomplete="off"
style="background: transparent; color: #c9d1d9; border: none; outline: none; flex: 1; font-family: inherit; font-size: 13px;"
onkeydown="if(event.key === 'Enter') runCommand()">
</div>
</div>
</section>
</div>
<script>
@@ -598,7 +625,7 @@
const el = document.getElementById(id);
const text = el.innerText;
navigator.clipboard.writeText(text).then(() => {
const btn = event.target;
const btn = event.currentTarget || event.target;
const orig = btn.innerText;
btn.innerText = 'COPIED';
setTimeout(() => { btn.innerText = orig; }, 2000);
@@ -675,6 +702,47 @@
}
}
async function runCommand() {
const input = document.getElementById('terminal-input');
const output = document.getElementById('terminal-output');
const command = input.value.trim();
if (!command) return;
// Add command to terminal
const cmdLine = document.createElement('div');
cmdLine.className = 'log-line';
cmdLine.innerHTML = `<span style="color: #00ff88;">$ ${command}</span>`;
output.appendChild(cmdLine);
input.value = '';
output.scrollTop = output.scrollHeight;
try {
const response = await fetch('/api/terminal/exec', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ command })
});
const result = await response.json();
const resultLine = document.createElement('div');
resultLine.className = result.error ? 'log-line log-error' : 'log-line';
resultLine.style.whiteSpace = 'pre-wrap';
resultLine.innerText = result.output;
output.appendChild(resultLine);
output.scrollTop = output.scrollHeight;
} catch (err) {
const errLine = document.createElement('div');
errLine.className = 'log-line log-error';
errLine.innerText = `FATAL ERROR: ${err.message}`;
output.appendChild(errLine);
output.scrollTop = output.scrollHeight;
}
}
// Auto-scroll logic
document.querySelectorAll('.terminal-body').forEach(el => {
el.scrollTop = el.scrollHeight;