Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Install to Reachy</title> | |
| <style> | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| max-width: 600px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| background: #f8f9fa; | |
| } | |
| .container { | |
| background: white; | |
| padding: 30px; | |
| border-radius: 10px; | |
| box-shadow: 0 2px 10px rgba(0,0,0,0.1); | |
| } | |
| .header { | |
| text-align: center; | |
| margin-bottom: 30px; | |
| } | |
| .app-icon { | |
| font-size: 48px; | |
| margin-bottom: 10px; | |
| } | |
| .install-section { | |
| margin: 20px 0; | |
| } | |
| label { | |
| display: block; | |
| margin-bottom: 5px; | |
| font-weight: 600; | |
| } | |
| input { | |
| width: 100%; | |
| padding: 10px; | |
| border: 1px solid #ddd; | |
| border-radius: 4px; | |
| font-size: 16px; | |
| box-sizing: border-box; | |
| } | |
| .install-btn { | |
| background: #0066cc; | |
| color: white; | |
| padding: 12px 24px; | |
| border: none; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| font-size: 16px; | |
| width: 100%; | |
| margin-top: 15px; | |
| } | |
| .install-btn:hover { | |
| background: #0052a3; | |
| } | |
| .install-btn:disabled { | |
| background: #ccc; | |
| cursor: not-allowed; | |
| } | |
| .status { | |
| margin-top: 15px; | |
| padding: 10px; | |
| border-radius: 4px; | |
| display: none; | |
| } | |
| .status.success { | |
| background: #d4edda; | |
| color: #155724; | |
| border: 1px solid #c3e6cb; | |
| } | |
| .status.error { | |
| background: #f8d7da; | |
| color: #721c24; | |
| border: 1px solid #f5c6cb; | |
| } | |
| .status.loading { | |
| background: #d1ecf1; | |
| color: #0c5460; | |
| border: 1px solid #bee5eb; | |
| } | |
| .github-link { | |
| text-align: center; | |
| margin-top: 20px; | |
| } | |
| .manual-install { | |
| background: #f8f9fa; | |
| padding: 15px; | |
| border-radius: 6px; | |
| margin-top: 20px; | |
| } | |
| .manual-install code { | |
| background: #e9ecef; | |
| padding: 2px 6px; | |
| border-radius: 3px; | |
| font-family: monospace; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="header"> | |
| <div class="app-icon">π€</div> | |
| <h1>Install to Reachy</h1> | |
| <p>One-click installation for your Reachy Mini</p> | |
| </div> | |
| <div class="install-section"> | |
| <label for="dashboardUrl">Reachy Dashboard URL:</label> | |
| <input type="url" id="dashboardUrl" value="http://localhost:8000" | |
| placeholder="http://your-reachy-ip:8000"> | |
| <button id="installBtn" class="install-btn" onclick="installApp()"> | |
| π₯ Install App to Reachy | |
| </button> | |
| <div id="status" class="status"></div> | |
| </div> | |
| <div class="manual-install"> | |
| <h3>Manual Installation</h3> | |
| <p>If the button doesn't work, copy and run this command:</p> | |
| <code id="curlCommand">curl -X POST http://localhost:8000/api/install -H "Content-Type: application/json" -d '{"url": "https://huggingface.co/spaces/pollen-robotics/reachy_mini_app_example", "name": "reachy_mini_app_example"}'</code> | |
| </div> | |
| <div class="github-link"> | |
| <p> | |
| <a href="https://github.com/your-username/your-repo" target="_blank"> | |
| π View Source Code on GitHub | |
| </a> | |
| </p> | |
| </div> | |
| </div> | |
| <script> | |
| // Check for auto-install parameters on page load | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const autoInstall = urlParams.get('install'); | |
| const dashboardUrl = urlParams.get('dashboard') || 'http://localhost:8000'; | |
| // Set dashboard URL from parameter | |
| if (urlParams.get('dashboard')) { | |
| document.getElementById('dashboardUrl').value = dashboardUrl; | |
| } | |
| // Auto-install if parameter is present | |
| if (autoInstall === 'true' || autoInstall === '1') { | |
| // Wait a moment for the page to fully load | |
| setTimeout(() => { | |
| installApp(true); | |
| }, 500); | |
| } | |
| }); | |
| async function installApp(isAutoInstall = false) { | |
| const dashboardUrl = document.getElementById('dashboardUrl').value.trim(); | |
| const status = document.getElementById('status'); | |
| const installBtn = document.getElementById('installBtn'); | |
| if (!dashboardUrl) { | |
| showStatus('error', 'Please enter your Reachy dashboard URL'); | |
| return; | |
| } | |
| try { | |
| installBtn.disabled = true; | |
| installBtn.innerHTML = 'β³ Installing...'; | |
| if (isAutoInstall) { | |
| showStatus('loading', 'π Auto-installing app to your Reachy...'); | |
| } else { | |
| showStatus('loading', 'Installing app to your Reachy...'); | |
| } | |
| const response = await fetch(`${dashboardUrl}/api/install`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| url: 'https://huggingface.co/spaces/pollen-robotics/reachy_mini_app_example', | |
| name: 'reachy_mini_app_example' | |
| }) | |
| }); | |
| const result = await response.json(); | |
| if (response.ok) { | |
| showStatus('success', 'β Installation started successfully! Check your Reachy dashboard for progress.'); | |
| // If auto-install, show additional success message | |
| if (isAutoInstall) { | |
| setTimeout(() => { | |
| showStatus('success', 'β Auto-installation completed! You can close this tab and check your Reachy dashboard.'); | |
| }, 2000); | |
| } | |
| } else { | |
| throw new Error(result.detail || 'Installation failed'); | |
| } | |
| } catch (error) { | |
| console.error('Installation error:', error); | |
| showStatus('error', 'β ' + error.message + (isAutoInstall ? ' - You can try manual installation below.' : '')); | |
| } finally { | |
| installBtn.disabled = false; | |
| installBtn.innerHTML = 'π₯ Install App to Reachy'; | |
| } | |
| } | |
| function showStatus(type, message) { | |
| const status = document.getElementById('status'); | |
| status.className = `status ${type}`; | |
| status.textContent = message; | |
| status.style.display = 'block'; | |
| } | |
| // Update curl command when dashboard URL changes | |
| document.getElementById('dashboardUrl').addEventListener('input', function() { | |
| const url = this.value || 'http://localhost:8000'; | |
| const curlCommand = `curl -X POST ${url}/api/install -H "Content-Type: application/json" -d '{"url": "https://github.com/your-username/your-repo", "name": "your-app-name"}'`; | |
| document.getElementById('curlCommand').textContent = curlCommand; | |
| }); | |
| </script> | |
| </body> | |
| </html> | |