Mobile-emulator / appforge_preview.html
ngzbydze
Add app previewer and improve app installation flow
eb53162
<!DOCTYPE html>
<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>