Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>App Preview</title> | |
| <style> | |
| body { margin: 0; font-family: sans-serif; background: #000; color: #fff; height: 100vh; display: flex; flex-direction: column; } | |
| #header { padding: 15px; background: #1a1a2e; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #333; } | |
| #content { flex: 1; position: relative; } | |
| iframe { width: 100%; height: 100%; border: none; } | |
| #tabs { display: flex; background: #1a1a2e; border-top: 1px solid #333; } | |
| .tab { flex: 1; padding: 15px; text-align: center; cursor: pointer; font-size: 12px; opacity: 0.6; } | |
| .tab.active { opacity: 1; border-top: 2px solid #ff6b6b; color: #ff6b6b; } | |
| #password-gate { position: absolute; inset: 0; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 100; } | |
| input { padding: 10px; border-radius: 5px; border: 1px solid #444; background: #222; color: #fff; margin-bottom: 10px; } | |
| button { padding: 10px 20px; background: #ff6b6b; border: none; border-radius: 5px; color: #fff; cursor: pointer; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="header"> | |
| <span id="app-name">App</span> | |
| <span id="section-title">Loading...</span> | |
| <div style="width: 20px;"></div> | |
| </div> | |
| <div id="content"> | |
| <div id="password-gate" style="display: none;"> | |
| <h3>Section Locked</h3> | |
| <input type="password" id="pass-input" placeholder="Enter password"> | |
| <button onclick="checkPassword()">Unlock</button> | |
| </div> | |
| <iframe id="app-frame"></iframe> | |
| </div> | |
| <div id="tabs"></div> | |
| <script> | |
| let currentApp = null; | |
| let currentSectionIdx = 0; | |
| function loadApp() { | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const appId = urlParams.get('id'); | |
| const userApps = JSON.parse(localStorage.getItem('userSubmittedApps') || '[]'); | |
| currentApp = userApps.find(a => a.id === appId); | |
| if (!currentApp) { | |
| document.body.innerHTML = '<div style="padding:20px; text-align:center;">App not found</div>'; | |
| return; | |
| } | |
| document.getElementById('app-name').innerText = currentApp.name; | |
| renderTabs(); | |
| switchSection(0); | |
| } | |
| function renderTabs() { | |
| const tabsContainer = document.getElementById('tabs'); | |
| tabsContainer.innerHTML = currentApp.sections.map((s, idx) => ` | |
| <div class="tab ${idx === 0 ? 'active' : ''}" onclick="switchSection(${idx})"> | |
| ${s.title} | |
| </div> | |
| `).join(''); | |
| } | |
| function switchSection(idx) { | |
| currentSectionIdx = idx; | |
| const section = currentApp.sections[idx]; | |
| document.getElementById('section-title').innerText = section.title; | |
| document.querySelectorAll('.tab').forEach((t, i) => { | |
| t.classList.toggle('active', i === idx); | |
| }); | |
| const gate = document.getElementById('password-gate'); | |
| if (section.data.password) { | |
| gate.style.display = 'flex'; | |
| document.getElementById('app-frame').src = 'about:blank'; | |
| } else { | |
| gate.style.display = 'none'; | |
| loadSectionContent(section); | |
| } | |
| } | |
| function checkPassword() { | |
| const input = document.getElementById('pass-input').value; | |
| const section = currentApp.sections[currentSectionIdx]; | |
| if (input === section.data.password) { | |
| document.getElementById('password-gate').style.display = 'none'; | |
| loadSectionContent(section); | |
| } else { | |
| alert('Wrong password'); | |
| } | |
| } | |
| function loadSectionContent(section) { | |
| const iframe = document.getElementById('app-frame'); | |
| if (section.type === 'web') { | |
| iframe.src = section.data.url; | |
| } else if (section.type === 'html') { | |
| const doc = iframe.contentWindow.document; | |
| doc.open(); | |
| doc.write(section.data.html || ''); | |
| doc.close(); | |
| } | |
| } | |
| window.onload = loadApp; | |
| </script> | |
| </body> | |
| </html> | |