diff --git a/database.sqlite-shm b/database.sqlite-shm index cf50792c..cfb6ac3c 100644 Binary files a/database.sqlite-shm and b/database.sqlite-shm differ diff --git a/database.sqlite-wal b/database.sqlite-wal index 8159e1e4..e530162e 100644 Binary files a/database.sqlite-wal and b/database.sqlite-wal differ diff --git a/public/claude-ide/projects-landing.css b/public/claude-ide/projects-landing.css index ed05810d..8dfd483e 100644 --- a/public/claude-ide/projects-landing.css +++ b/public/claude-ide/projects-landing.css @@ -417,3 +417,115 @@ body.sessions-page { padding-top: 80px; } } + +/* === Login Modal === */ +.modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.8); + justify-content: center; + align-items: center; + z-index: 10000; +} + +.modal-content { + background: #1a1a1a; + border: 1px solid #333; + border-radius: 12px; + padding: 0; + width: 100%; + max-width: 400px; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 24px; + border-bottom: 1px solid #333; +} + +.modal-header h2 { + margin: 0; + font-size: 18px; + color: #e0e0e0; +} + +.modal-close { + background: none; + border: none; + color: #888; + font-size: 24px; + cursor: pointer; + padding: 0; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-close:hover { + color: #fff; +} + +.modal-body { + padding: 24px; +} + +.form-group { + margin-bottom: 16px; +} + +.form-group label { + display: block; + margin-bottom: 6px; + color: #aaa; + font-size: 13px; +} + +.form-group input { + width: 100%; + padding: 10px 12px; + background: #0d0d0d; + border: 1px solid #333; + border-radius: 6px; + color: #e0e0e0; + font-size: 14px; +} + +.form-group input:focus { + outline: none; + border-color: #4a9eff; +} + +.btn-primary { + width: 100%; + padding: 12px; + background: #4a9eff; + color: white; + border: none; + border-radius: 6px; + font-size: 14px; + font-weight: 600; + cursor: pointer; +} + +.btn-primary:hover { + background: #3a8eef; +} + +.login-error { + margin-bottom: 16px; + padding: 10px 12px; + background: rgba(255, 107, 107, 0.1); + border: 1px solid #ff6b6b; + border-radius: 6px; + color: #ff6b6b; + font-size: 13px; +} diff --git a/public/claude-ide/projects-landing.js b/public/claude-ide/projects-landing.js index 975ec59d..34df7a95 100644 --- a/public/claude-ide/projects-landing.js +++ b/public/claude-ide/projects-landing.js @@ -27,10 +27,73 @@ async function checkAuth() { const data = await res.json(); if (!data.authenticated) { - window.location.href = '/claude/login.html'; + // Show login modal instead of redirecting + showLoginModal(); + return; + } + + // Update nav with username + if (data.username) { + document.querySelector('.nav-logo').textContent = `Claude Code (${data.username})`; } } catch (error) { - console.error('Auth check failed:', error); + console.error('[checkAuth] Error:', error); + showLoginModal(); + } +} + +// Show login modal +function showLoginModal() { + const modal = document.getElementById('login-modal'); + if (modal) { + modal.style.display = 'flex'; + } +} + +// Close login modal +function closeLoginModal() { + const modal = document.getElementById('login-modal'); + if (modal) { + modal.style.display = 'none'; + } +} + +// Handle login form submission +async function handleLogin(event) { + event.preventDefault(); + + const username = document.getElementById('login-username').value; + const password = document.getElementById('login-password').value; + const errorDiv = document.getElementById('login-error'); + + try { + const res = await fetch('/claude/api/login', { + method: 'POST', + credentials: 'same-origin', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username, password }) + }); + + const data = await res.json(); + + if (data.success) { + // Login successful + closeLoginModal(); + loadProjects(); + + // Update nav with username + if (data.username) { + document.querySelector('.nav-logo').textContent = `Claude Code (${data.username})`; + } + } else { + // Show error + errorDiv.textContent = data.error || 'Login failed'; + errorDiv.style.display = 'block'; + } + } catch (error) { + console.error('[handleLogin] Error:', error); + errorDiv.textContent = 'Login failed. Please try again.'; + errorDiv.style.display = 'block'; } } diff --git a/public/claude-landing.html b/public/claude-landing.html index 8062eb71..3b0ed886 100644 --- a/public/claude-landing.html +++ b/public/claude-landing.html @@ -65,6 +65,30 @@ + +
+