const $ = (s) => document.querySelector(s); function toast(msg, kind = '') { const t = $('#toast'); t.textContent = msg; t.className = 'toast show ' + kind; setTimeout(() => t.classList.remove('show'), 3500); } $('#upload-form').addEventListener('submit', async (e) => { e.preventDefault(); const fd = new FormData(e.target); const btn = e.target.querySelector('button[type=submit]'); btn.disabled = true; btn.textContent = 'Uploading…'; try { const r = await fetch('/api/build/upload', { method: 'POST', body: fd }); const data = await r.json(); if (!r.ok) throw new Error(data.error || 'Upload failed'); location.href = `/builds#${data.job_id}`; } catch (err) { toast(err.message, 'error'); btn.disabled = false; btn.textContent = 'Queue Build'; } }); $('#git-form').addEventListener('submit', async (e) => { e.preventDefault(); const body = { url: e.target.url.value.trim(), branch: e.target.branch.value.trim() || null, scheme: e.target.scheme.value.trim() || null, }; const btn = e.target.querySelector('button[type=submit]'); btn.disabled = true; btn.textContent = 'Cloning…'; try { const r = await fetch('/api/build/git', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); const data = await r.json(); if (!r.ok) throw new Error(data.error || 'Clone failed'); location.href = `/builds#${data.job_id}`; } catch (err) { toast(err.message, 'error'); btn.disabled = false; btn.textContent = 'Queue Build'; } });