UNPKG

@web-terminal/terminal

Version:

Embeddable web terminal component

444 lines (380 loc) 16.4 kB
<!DOCTYPE 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>