document.addEventListener('DOMContentLoaded', loadApps);
async function loadApps() {
const res = await fetch('/api/apps');
if (res.status === 401) { location.href = '/login'; return; }
const apps = await res.json();
const grid = document.getElementById('apps');
const empty = document.getElementById('empty');
if (apps.length === 0) {
grid.style.display = 'none';
empty.style.display = 'block';
return;
}
grid.innerHTML = apps.map(app => `
${app.latest_icon
? `

`
: app.name.charAt(0).toUpperCase()}
${esc(app.name)}
${esc(app.bundle_id)}
v${esc(app.latest_version || '?')}${app.latest_build_number ? ` (${esc(app.latest_build_number)})` : ''} · ${timeAgo(app.latest_uploaded_at)}
`).join('');
}
async function showApp(appId) {
const res = await fetch(`/api/apps/${appId}`);
const app = await res.json();
const modal = document.getElementById('modal');
const body = document.getElementById('modal-body');
const icon = app.builds[0]?.icon_filename;
body.innerHTML = `
Builds (${app.builds.length})
${app.builds.map(b => `
`).join('')}
`;
modal.style.display = 'flex';
modal.onclick = (e) => { if (e.target === modal) closeModal(); };
}
function closeModal() {
document.getElementById('modal').style.display = 'none';
}
async function deleteBuild(buildId, appId) {
if (!confirm('Delete this build?')) return;
await fetch(`/api/builds/${buildId}`, { method: 'DELETE' });
closeModal();
loadApps();
}
async function deleteApp(appId) {
if (!confirm('Delete this app and all its builds?')) return;
await fetch(`/api/apps/${appId}`, { method: 'DELETE' });
closeModal();
loadApps();
}
function esc(s) {
if (!s) return '';
const d = document.createElement('div');
d.textContent = s;
return d.innerHTML;
}
function formatSize(bytes) {
if (!bytes) return '';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}
function timeAgo(dateStr) {
if (!dateStr) return '';
const d = new Date(dateStr + 'Z');
const now = new Date();
const diff = (now - d) / 1000;
if (diff < 60) return 'just now';
if (diff < 3600) return Math.floor(diff / 60) + 'm ago';
if (diff < 86400) return Math.floor(diff / 3600) + 'h ago';
if (diff < 604800) return Math.floor(diff / 86400) + 'd ago';
return d.toLocaleDateString();
}