var selectedColor = '#0d9488'; var slugManual = false; var isCreateMode = false; var formDirty = false; function initPage() { var params = new URLSearchParams(window.location.search); isCreateMode = params.get('mode') === 'create'; if (isCreateMode) { document.title = 'Crank — Create workspace'; document.getElementById('page-title').textContent = 'Create a new workspace'; document.getElementById('page-subtitle').textContent = 'A workspace is a shared environment for your team\'s MCP operations and agents. Each workspace gets its own MCP endpoint namespace.'; document.getElementById('section-invite').style.display = ''; document.getElementById('footer-note').style.display = ''; var btn = document.getElementById('submit-btn'); btn.textContent = 'Create workspace'; btn.disabled = true; btn.style.opacity = '0.5'; btn.style.cursor = 'not-allowed'; } else { // Edit mode — prefill from current workspace document.getElementById('section-members').style.display = ''; document.getElementById('section-danger').style.display = ''; var ws = getCurrentWs(); document.getElementById('ws-name').value = ws.name; document.getElementById('ws-slug').value = ws.slug; document.getElementById('ws-avatar-preview').textContent = ws.letter; document.getElementById('ws-avatar-preview').style.background = ws.color; selectedColor = ws.color; slugManual = true; // Activate matching color swatch document.querySelectorAll('.ws-color-swatch').forEach(function(s) { s.classList.toggle('active', s.dataset.color === ws.color); }); // Scroll to #section-members if hash present if (window.location.hash === '#section-members') { setTimeout(function() { document.getElementById('section-members').scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 100); } } // Apply language state to lang buttons var lang = localStorage.getItem('crank_lang') || 'en'; document.querySelectorAll('.lang-btn').forEach(function(btn) { btn.classList.toggle('active', btn.dataset.lang === lang); }); } function onWsNameInput(val) { var letter = val.trim() ? val.trim()[0].toUpperCase() : '?'; document.getElementById('ws-avatar-preview').textContent = letter; if (!slugManual) { var slug = val.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '').replace(/-+/g, '-').replace(/^-|-$/g, ''); document.getElementById('ws-slug').value = slug; } if (isCreateMode) validateCreateForm(); formDirty = true; } function onWsSlugInput(val) { var clean = val.toLowerCase().replace(/[^a-z0-9-]/g, '').replace(/-+/g, '-'); document.getElementById('ws-slug').value = clean; slugManual = true; if (isCreateMode) validateCreateForm(); formDirty = true; } function pickColor(el) { selectedColor = el.dataset.color; document.querySelectorAll('.ws-color-swatch').forEach(function(s) { s.classList.remove('active'); }); el.classList.add('active'); document.getElementById('ws-avatar-preview').style.background = selectedColor; formDirty = true; } function validateCreateForm() { var name = document.getElementById('ws-name').value.trim(); var slug = document.getElementById('ws-slug').value.trim(); var btn = document.getElementById('submit-btn'); var valid = name.length > 0 && slug.length > 0; btn.disabled = !valid; btn.style.opacity = valid ? '1' : '0.5'; btn.style.cursor = valid ? 'pointer' : 'not-allowed'; } function submitForm() { var name = document.getElementById('ws-name').value.trim(); var slug = document.getElementById('ws-slug').value.trim(); if (!name || !slug) return; formDirty = false; if (isCreateMode) { if (window.WS_LIST) { WS_LIST.push({ slug: slug, name: slug, role: 'Owner', letter: name[0].toUpperCase(), color: selectedColor }); } localStorage.setItem('crank_workspace', slug); window.location.href = (window.APP_BASE||'')+'index.html'; } else { // Update current workspace in WS_LIST if (window.WS_LIST) { var current = localStorage.getItem('crank_workspace') || 'acme-workspace'; var idx = WS_LIST.findIndex(function(w) { return w.slug === current; }); if (idx !== -1) { WS_LIST[idx].name = slug; WS_LIST[idx].slug = slug; WS_LIST[idx].letter = name[0].toUpperCase(); WS_LIST[idx].color = selectedColor; } } localStorage.setItem('crank_workspace', slug); // Show saved feedback var btn = document.getElementById('submit-btn'); var orig = btn.textContent; btn.textContent = 'Saved ✓'; btn.disabled = true; setTimeout(function() { btn.textContent = orig; btn.disabled = false; }, 1800); } } // Create mode invite rows function addInviteRow() { var rows = document.getElementById('invite-rows'); var div = document.createElement('div'); div.className = 'invite-row'; div.innerHTML = '' + '' + ''; rows.appendChild(div); } function removeInviteRow(btn) { btn.closest('.invite-row').remove(); } // Members management (edit mode) function toggleInviteForm() { var f = document.getElementById('invite-form'); var s = document.getElementById('invite-success'); if (f.style.display === 'none') { f.style.display = ''; s.style.display = 'none'; document.getElementById('invite-email').focus(); } else { f.style.display = 'none'; } } function sendInvite() { var email = document.getElementById('invite-email').value.trim(); if (!email || !email.includes('@')) return; document.getElementById('invite-success').style.display = ''; document.getElementById('invite-email').value = ''; } function updateRole(select, email) { console.log('Role updated:', email, '->', select.value); } function removeMember(btn, name) { if (!confirm('Remove ' + name + ' from this workspace?')) return; btn.closest('.member-row').remove(); var rows = document.querySelectorAll('#members-list .member-row'); var label = document.getElementById('members-count-label'); if (label) label.textContent = rows.length + ' member' + (rows.length !== 1 ? 's' : ''); } function revokeInvite(btn) { btn.closest('.member-row').remove(); var pending = document.getElementById('pending-invites'); if (pending && !pending.querySelector('.member-row')) pending.style.display = 'none'; } document.addEventListener('DOMContentLoaded', function() { initPage(); if (isCreateMode) document.getElementById('ws-name').focus(); }); window.addEventListener('beforeunload', function(e) { if (formDirty) { e.preventDefault(); e.returnValue = ''; } });