// static/js/projects.js v7 async function loadPublishedProjects() { if (!currentToken) return; try { var res = await fetch('/api/projects', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({token: currentToken}) }); var data = await res.json(); var grid = document.getElementById('projects-grid'); if (!grid) return; grid.innerHTML = ''; if (data.projects && data.projects.length) { data.projects.forEach(function(p) { var card = document.createElement('div'); card.style.cssText = 'background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--r-lg);padding:var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-3)'; var date = new Date(p.created_at).toLocaleDateString(); var url = location.origin + p.url; card.innerHTML = '

' + p.name + '

' + date + '
' + url + '
'; grid.appendChild(card); }); } else { grid.innerHTML = '

No projects yet

Tap Publish to deploy your code

'; } } catch (e) { showToast('Error loading projects', 'error'); } } var publishingProjectID = null; async function publishCurrentWorkspace(existingName, existingId) { publishingProjectID = existingId || null; var modal = document.getElementById('publish-modal'); modal.style.display = 'flex'; document.getElementById('publish-project-name').value = existingName || ''; var list = document.getElementById('publish-file-list'); list.innerHTML = ' Loading...'; try { var wsRes = await fetch('/api/files', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({token: currentToken}) }); var wsData = await wsRes.json(); var prev = []; if (existingId) { var pubRes = await fetch('/api/project/files', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({token: currentToken, project_id: existingId}) }); var pubData = await pubRes.json(); if (pubData.files) prev = pubData.files; } list.innerHTML = ''; if (wsData.files && wsData.files.length) { wsData.files.forEach(function(f) { var lbl = document.createElement('label'); lbl.style.cssText = 'display:flex;align-items:center;gap:8px;color:var(--text-1);cursor:pointer;font-size:13px;font-family:var(--font-mono);min-height:var(--touch-min)'; var cb = document.createElement('input'); cb.type = 'checkbox'; cb.value = f; cb.className = 'publish-cb'; if (!existingId || prev.includes(f)) cb.checked = true; lbl.appendChild(cb); lbl.appendChild(document.createTextNode(f)); list.appendChild(lbl); }); } else { list.innerHTML = 'Workspace is empty'; } } catch (e) { list.innerHTML = 'Failed to load files'; } } function closePublishModal() { document.getElementById('publish-modal').style.display = 'none'; } async function confirmPublish() { var name = document.getElementById('publish-project-name').value.trim(); if (!name) { showToast('Enter project name', 'warning'); return; } var checks = document.querySelectorAll('.publish-cb'); var files = Array.from(checks).filter(function(c) { return c.checked; }).map(function(c) { return c.value; }); if (!files.length) { showToast('Select at least one file', 'warning'); return; } var htmlFiles = files.filter(function(f) { return f.endsWith('.html'); }); var mainHtml = htmlFiles.includes('index.html') ? 'index.html' : (htmlFiles[0] || 'index.html'); var btn = document.getElementById('publish-confirm-btn'); btn.innerHTML = ' Publishing...'; btn.disabled = true; try { var res = await fetch('/api/publish', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ token: currentToken, project_name: name, project_id: publishingProjectID, files: files, main_html_file: mainHtml }) }); var data = await res.json(); if (data.success) { showToast('Published!', 'success'); closePublishModal(); loadPublishedProjects(); } else showToast(data.error || 'Failed', 'error'); } catch (e) { showToast('Network error', 'error'); } btn.innerHTML = ' Publish'; btn.disabled = false; }