@web-terminal/terminal
Version:
Embeddable web terminal component
444 lines (380 loc) • 16.4 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Terminal - Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.header {
text-align: center;
margin-bottom: 40px;
color: white;
}
.header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
.header p {
font-size: 1.1rem;
opacity: 0.9;
}
.badge {
background: #28a745;
color: white;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
margin-left: 10px;
}
.demo-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin-bottom: 40px;
}
@media (max-width: 768px) {
.demo-grid {
grid-template-columns: 1fr;
}
}
.config-panel, .info-panel {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
.config-panel h2, .info-panel h2 {
color: #333;
margin-bottom: 20px;
font-size: 1.5rem;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #555;
}
.form-group input, .form-group select {
width: 100%;
padding: 12px;
border: 2px solid #e1e5e9;
border-radius: 8px;
font-size: 14px;
transition: border-color 0.3s ease;
}
.form-group input:focus, .form-group select:focus {
outline: none;
border-color: #667eea;
}
.form-group small {
display: block;
margin-top: 5px;
color: #666;
font-size: 12px;
}
.btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
width: 100%;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
}
.status {
margin-top: 15px;
padding: 10px;
border-radius: 6px;
font-size: 14px;
display: none;
}
.status.success {
background: #d4edda;
color: #155724;
}
.status.error {
background: #f8d7da;
color: #721c24;
}
.info-panel {
background: #f8f9fa;
}
.info-panel h3 {
color: #495057;
margin-bottom: 10px;
font-size: 1.1rem;
}
.code-block {
background: #2d3748;
color: #e2e8f0;
padding: 15px;
border-radius: 6px;
font-family: 'Courier New', monospace;
font-size: 13px;
margin: 15px 0;
overflow-x: auto;
white-space: pre-wrap;
}
.version-info {
background: #e3f2fd;
border: 1px solid #90caf9;
border-radius: 6px;
padding: 15px;
margin-top: 20px;
}
.version-info h4 {
color: #1976d2;
margin-bottom: 10px;
}
.loading {
opacity: 0.6;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🖥️ Web Terminal</h1>
<p>Interactive demo</p>
<span class="badge" id="version-badge">Loading...</span>
</div>
<div class="demo-grid">
<!-- Configuration Panel -->
<div class="config-panel">
<h2>⚙️ Terminal Configuration</h2>
<form id="terminalConfig">
<div class="form-group">
<label for="githubAppName">GitHub App Name *</label>
<input type="text" id="githubAppName" value="terminal-local" required>
<small>Name of your GitHub OAuth application</small>
</div>
<div class="form-group">
<label for="githubClientId">GitHub Client ID *</label>
<input type="text" id="githubClientId" value="123" required>
<small>OAuth App Client ID from GitHub Developer Settings</small>
</div>
<div class="form-group">
<label for="backendDomain">Backend Domain</label>
<input type="text" id="backendDomain" placeholder="mydomain.com">
<small>Required for production. Leave empty for localhost development</small>
</div>
<div class="form-group">
<label for="vmType">VM Type</label>
<select id="vmType">
<option value="cka">CKA Kubernetes Workshop</option>
</select>
<small>Type of virtual machine environment</small>
</div>
<div class="form-group">
<label for="debug">Debug Mode</label>
<select id="debug">
<option value="auto">Auto (localhost = true)</option>
<option value="true">Enabled</option>
<option value="false">Disabled</option>
</select>
<small>Enable console logging for troubleshooting</small>
</div>
<button type="submit" class="btn" id="initTerminal">
🚀 Initialize Terminal
</button>
<div id="status" class="status"></div>
</form>
<div class="version-info">
<h4>📦 Package Information</h4>
<div id="package-info">Loading package information...</div>
</div>
</div>
<!-- Information Panel -->
<div class="info-panel">
<h2>📚 Usage Information</h2>
<h3>🚀 Usage</h3>
<div class="code-block" id="usage-code">Loading...</div>
<h3>🔗 CDN URLs</h3>
<ul id="cdn-urls">
<li>Loading...</li>
</ul>
</div>
</div>
</div>
<!-- Terminal script will be loaded dynamically -->
<script>
var currentTerminal = null;
var packageInfo = null;
document.addEventListener('DOMContentLoaded', function() {
fetchPackageInfo();
document.getElementById('terminalConfig').addEventListener('submit', function(e) {
e.preventDefault();
initializeTerminal();
});
});
function fetchPackageInfo() {
console.log('Fetching package information...');
// Check if we're running locally by trying to load local terminal.js
var isLocal = window.location.protocol === 'file:' ||
window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1';
if (isLocal) {
console.log('Running locally - using local terminal.js');
updateUI('local-dev');
loadLocalTerminalScript();
return;
}
// Running on server - fetch from npm
fetch('https://registry.npmjs.org/@web-terminal/terminal')
.then(function(response) {
return response.json();
})
.then(function(data) {
packageInfo = data;
var latestVersion = data['dist-tags'].latest;
console.log('Latest version:', latestVersion);
updateUI(latestVersion);
loadTerminalScript(latestVersion);
})
.catch(function(error) {
console.error('Error fetching package info:', error);
updateUI('latest');
loadTerminalScript('latest');
});
}
function updateUI(version) {
document.getElementById('version-badge').textContent = version;
var usageCode, cdnUrls;
if (version === 'local-dev') {
// Local development mode
usageCode = '<script src="./terminal.js"><\/script>\n\n<script>\nconst terminal = new WebTerminalEmbed({\n githubAppName: \'your-app-name\',\n githubClientId: \'your-client-id\',\n backendDomain: \'your-domain.com\'\n});\n<\/script>';
cdnUrls =
'<li><strong>Local Development:</strong> <code>./terminal.js</code></li>' +
'<li><strong>Production CDN:</strong> <code>https://cdn.jsdelivr.net/npm/@web-terminal/terminal@latest/terminal.min.js</code></li>' +
'<li><strong>Package Info:</strong> <a href="https://www.npmjs.com/package/@web-terminal/terminal" target="_blank">npmjs.com/package/@web-terminal/terminal</a></li>';
} else {
// Production mode
usageCode = '<script src="https://cdn.jsdelivr.net/npm/@web-terminal/terminal@' + version + '/terminal.min.js"><\/script>\n\n<script>\nconst terminal = new WebTerminalEmbed({\n githubAppName: \'your-app-name\',\n githubClientId: \'your-client-id\',\n backendDomain: \'your-domain.com\'\n});\n<\/script>';
cdnUrls =
'<li><strong>Latest:</strong> <code>https://cdn.jsdelivr.net/npm/@web-terminal/terminal@latest/terminal.min.js</code></li>' +
'<li><strong>Specific Version:</strong> <code>https://cdn.jsdelivr.net/npm/@web-terminal/terminal@' + version + '/terminal.min.js</code></li>' +
'<li><strong>Package Info:</strong> <a href="https://www.npmjs.com/package/@web-terminal/terminal" target="_blank">npmjs.com/package/@web-terminal/terminal</a></li>';
}
document.getElementById('usage-code').textContent = usageCode;
document.getElementById('cdn-urls').innerHTML = cdnUrls;
var packageInfoDiv = document.getElementById('package-info');
if (version === 'local-dev') {
packageInfoDiv.innerHTML =
'<strong>Version:</strong> Local Development<br>' +
'<strong>Source:</strong> ./terminal.js<br>' +
'<strong>Mode:</strong> Development';
} else if (packageInfo) {
var publishDate = new Date(packageInfo.time[version]).toLocaleDateString();
packageInfoDiv.innerHTML =
'<strong>Version:</strong> ' + version + '<br>' +
'<strong>Published:</strong> ' + publishDate + '<br>' +
'<strong>Description:</strong> ' + (packageInfo.description || 'Web Terminal Embed') + '<br>' +
'<strong>License:</strong> ' + (packageInfo.license || 'MIT');
} else {
packageInfoDiv.innerHTML = '<strong>Version:</strong> ' + version;
}
}
function loadLocalTerminalScript() {
var script = document.createElement('script');
script.src = './terminal.js'; // Use local file
script.onload = function() {
console.log('Local terminal script loaded successfully');
};
script.onerror = function() {
console.error('Failed to load local terminal script, falling back to npm');
// Fallback to npm version if local file doesn't exist
loadTerminalScript('latest');
};
document.head.appendChild(script);
}
function loadTerminalScript(version) {
var script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/@web-terminal/terminal@' + version + '/terminal.min.js';
script.onload = function() {
console.log('Terminal script loaded successfully');
};
script.onerror = function() {
console.error('Failed to load terminal script');
var status = document.getElementById('status');
status.textContent = 'Failed to load terminal library';
status.className = 'status error';
status.style.display = 'block';
};
document.head.appendChild(script);
}
function initializeTerminal() {
var status = document.getElementById('status');
var btn = document.getElementById('initTerminal');
if (typeof WebTerminalEmbed === 'undefined') {
showStatus('❌ Terminal library not loaded yet. Please wait and try again.', 'error');
return;
}
var config = {
githubAppName: document.getElementById('githubAppName').value.trim(),
githubClientId: document.getElementById('githubClientId').value.trim(),
backendDomain: document.getElementById('backendDomain').value.trim() || undefined,
vmType: document.getElementById('vmType').value,
debug: document.getElementById('debug').value === 'auto' ? undefined :
document.getElementById('debug').value === 'true'
};
if (!config.githubAppName || !config.githubClientId) {
showStatus('Please fill in required fields (GitHub App Name and Client ID)', 'error');
return;
}
btn.disabled = true;
btn.textContent = '⏳ Initializing...';
showStatus('Initializing terminal...', 'success');
try {
if (currentTerminal && typeof currentTerminal.destroy === 'function') {
currentTerminal.destroy();
}
currentTerminal = new WebTerminalEmbed(config);
showStatus('✅ Terminal initialized successfully! Look for the ">_" button in the bottom-right corner.', 'success');
} catch (error) {
console.error('Terminal initialization error:', error);
showStatus('❌ Error: ' + error.message, 'error');
} finally {
btn.disabled = false;
btn.textContent = '🚀 Initialize Terminal';
}
}
function showStatus(message, type) {
var status = document.getElementById('status');
status.textContent = message;
status.className = 'status ' + type;
status.style.display = 'block';
if (type === 'success') {
setTimeout(function() {
status.style.display = 'none';
}, 5000);
}
}
</script>
</body>
</html>