Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Login - Law Bot</title> | |
| <link rel="stylesheet" href="/static/css/styles.css"> | |
| <style> | |
| .auth-container { | |
| max-width: 400px; | |
| margin: 50px auto; | |
| padding: 2rem; | |
| background: rgba(255, 255, 255, 0.1); | |
| backdrop-filter: blur(10px); | |
| border-radius: 12px; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| color: white; | |
| } | |
| .auth-container h2 { | |
| text-align: center; | |
| margin-bottom: 1.5rem; | |
| } | |
| .form-group { | |
| margin-bottom: 1rem; | |
| } | |
| .form-group label { | |
| display: block; | |
| margin-bottom: 0.5rem; | |
| } | |
| .form-group input { | |
| width: 100%; | |
| padding: 0.75rem; | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| border-radius: 6px; | |
| background: rgba(0, 0, 0, 0.2); | |
| color: white; | |
| } | |
| .btn { | |
| width: 100%; | |
| padding: 0.75rem; | |
| background: #9b87f5; | |
| color: white; | |
| border: none; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| font-size: 1rem; | |
| transition: background 0.3s; | |
| } | |
| .btn:hover { | |
| background: #7e69d6; | |
| } | |
| .links { | |
| margin-top: 1rem; | |
| text-align: center; | |
| font-size: 0.9rem; | |
| } | |
| .links a { | |
| color: #D6BCFA; | |
| text-decoration: none; | |
| } | |
| .links a:hover { | |
| text-decoration: underline; | |
| } | |
| /* Phase 2: Portal Overlay */ | |
| #portalOverlay { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(10, 10, 15, 0.95); | |
| backdrop-filter: blur(20px); | |
| z-index: 9999; | |
| display: none; | |
| justify-content: center; | |
| align-items: center; | |
| flex-direction: column; | |
| color: white; | |
| opacity: 0; | |
| transition: opacity 0.5s ease; | |
| } | |
| #portalOverlay.show { | |
| display: flex; | |
| opacity: 1; | |
| } | |
| .portal-pulse { | |
| width: 80px; | |
| height: 80px; | |
| background: #9b87f5; | |
| border-radius: 50%; | |
| margin-bottom: 20px; | |
| animation: portalPulse 2s infinite; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| box-shadow: 0 0 30px rgba(155, 135, 245, 0.5); | |
| } | |
| .portal-pulse svg { | |
| width: 40px; | |
| height: 40px; | |
| color: white; | |
| } | |
| @keyframes portalPulse { | |
| 0% { | |
| transform: scale(0.95); | |
| box-shadow: 0 0 0 0 rgba(155, 135, 245, 0.7); | |
| } | |
| 70% { | |
| transform: scale(1.1); | |
| box-shadow: 0 0 0 20px rgba(155, 135, 245, 0); | |
| } | |
| 100% { | |
| transform: scale(0.95); | |
| box-shadow: 0 0 0 0 rgba(155, 135, 245, 0); | |
| } | |
| } | |
| .portal-message { | |
| font-size: 1.5rem; | |
| font-weight: 500; | |
| letter-spacing: 1px; | |
| text-align: center; | |
| } | |
| .portal-sub { | |
| font-size: 0.9rem; | |
| opacity: 0.6; | |
| margin-top: 10px; | |
| text-transform: uppercase; | |
| letter-spacing: 3px; | |
| } | |
| .btn:disabled { | |
| opacity: 0.7; | |
| cursor: not-allowed; | |
| background: #64748b; | |
| } | |
| .professional-footer { | |
| margin-top: 2rem; | |
| padding: 1.5rem 0; | |
| text-align: center; | |
| border-top: 1px solid rgba(155, 135, 245, 0.1); | |
| color: rgba(255, 255, 255, 0.5); | |
| font-size: 0.85rem; | |
| width: 100%; | |
| } | |
| .professional-footer a { | |
| color: #9b87f5; | |
| text-decoration: none; | |
| font-weight: 500; | |
| } | |
| .professional-footer a:hover { | |
| text-decoration: underline; | |
| } | |
| </style> | |
| </head> | |
| <body class="dark"> | |
| <div id="portalOverlay"> | |
| <div class="portal-pulse"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" /> | |
| </svg> | |
| </div> | |
| <div class="portal-message" id="portalMessage">INITIALIZING TERMINAL</div> | |
| <div class="portal-sub">Secure Professional Access</div> | |
| </div> | |
| <div class="auth-container"> | |
| <h2>Login</h2> | |
| <form id="loginForm"> | |
| <div class="form-group"> | |
| <label for="username">Username</label> | |
| <input type="text" id="username" required> | |
| </div> | |
| <div class="form-group"> | |
| <label for="password">Password</label> | |
| <input type="password" id="password" required> | |
| </div> | |
| <button type="submit" class="btn">Login</button> | |
| </form> | |
| <div class="links"> | |
| <a href="/register" id="registerLink">Don't have an account? Register</a><br> | |
| <a href="/forgot-password">Forgot Password?</a> | |
| </div> | |
| <footer class="professional-footer"> | |
| © 2026 Law Bot AI. All Rights Reserved. | |
| <br> | |
| Developed & Managed by <a href="https://www.linkedin.com/in/vishwanath77" target="_blank">Vishwanath</a> | |
| </footer> | |
| </div> | |
| <script> | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const role = urlParams.get('role'); | |
| if (role) { | |
| document.getElementById('registerLink').href = `/register?role=${role}`; | |
| } | |
| document.getElementById('loginForm').addEventListener('submit', async (e) => { | |
| e.preventDefault(); | |
| const username = document.getElementById('username').value; | |
| const password = document.getElementById('password').value; | |
| try { | |
| const response = await fetch('/api/login', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ username, password, role }) | |
| }); | |
| const loginBtn = document.querySelector('.btn'); | |
| const originalBtnText = loginBtn.innerText; | |
| loginBtn.disabled = true; | |
| loginBtn.innerText = 'Verifying...'; | |
| const data = await response.json(); | |
| if (response.ok) { | |
| localStorage.setItem('token', data.access_token); | |
| const rolePages = { | |
| 'Admin': '/users', | |
| 'Judge': 'judgedashboard.html', | |
| 'Advocate/Lawyer': 'advocatedashboard.html', | |
| 'Woman': 'woman.html', | |
| 'Citizen': 'citizen.html', | |
| 'Student': 'studentdashboard.html', | |
| 'Minor': 'minor.html' | |
| }; | |
| const roleMessages = { | |
| 'Admin': 'Authenticating Admin Privileges. Accessing Management Center...', | |
| 'Judge': 'Initializing Judicial Terminal...', | |
| 'Advocate/Lawyer': 'Welcome back, Counselor. Securing portal...', | |
| 'Woman': 'Welcome to Shakti Empowerment Hub...', | |
| 'Citizen': 'Accessing Law Bot Public Terminal...', | |
| 'Student': 'Setting up your legal study environment...', | |
| 'Minor': 'Hello! Getting Law Bot ready for you...' | |
| }; | |
| let userRole = data.role; | |
| if (data.role === 'Admin' && role) { | |
| userRole = role; | |
| } else if (!userRole && role) { | |
| userRole = role; | |
| } | |
| // Show professional portal overlay | |
| const overlay = document.getElementById('portalOverlay'); | |
| const msgEl = document.getElementById('portalMessage'); | |
| msgEl.innerText = roleMessages[userRole] || 'Access Granted. Entering Portal...'; | |
| overlay.classList.add('show'); | |
| // Brief delay for the aesthetic "Secure Entry" feel before redirect | |
| setTimeout(() => { | |
| if (userRole && rolePages[userRole]) { | |
| window.location.href = rolePages[userRole]; | |
| } else { | |
| window.location.href = '/'; | |
| } | |
| }, 1200); | |
| } else { | |
| loginBtn.disabled = false; | |
| loginBtn.innerText = originalBtnText; | |
| alert(data.detail || 'Login failed'); | |
| } | |
| } catch (error) { | |
| console.error('Error:', error); | |
| alert('An error occurred'); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |