Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Attendance Management System - Login</title> | |
| <link rel="stylesheet" href="styles2.css"> | |
| <style> | |
| /* Login-specific styles */ | |
| .login-container { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| min-height: 100vh; | |
| background: #f8fafc; | |
| } | |
| .login-card { | |
| background: white; | |
| padding: 3rem; | |
| border-radius: 16px; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); | |
| width: 100%; | |
| max-width: 400px; | |
| } | |
| .login-title { | |
| text-align: center; | |
| font-size: 1.5rem; | |
| font-weight: 600; | |
| color: #1e293b; | |
| margin-bottom: 2rem; | |
| } | |
| .login-tabs { | |
| display: flex; | |
| background: #f1f5f9; | |
| border-radius: 8px; | |
| padding: 0.25rem; | |
| margin-bottom: 2rem; | |
| } | |
| .tab { | |
| flex: 1; | |
| padding: 0.75rem; | |
| text-align: center; | |
| border: none; | |
| background: transparent; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| font-weight: 500; | |
| color: #64748b; | |
| transition: all 0.2s; | |
| } | |
| .tab.active { | |
| background: white; | |
| color: #1e293b; | |
| box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="login-container"> | |
| <div class="login-card"> | |
| <h1 class="login-title">Attendance Management System</h1> | |
| <div class="login-tabs"> | |
| <button class="tab active" onclick="switchTab('student')">Student</button> | |
| <button class="tab" onclick="switchTab('professor')">Professor/TA</button> | |
| </div> | |
| <!-- Enhanced login form --> | |
| <form id="loginForm" style="display: block;"> | |
| <div class="form-group"> | |
| <label class="form-label" for="loginEmail">Email</label> | |
| <input type="email" id="loginEmail" class="form-input" required> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label" for="loginPassword">Password</label> | |
| <input type="password" id="loginPassword" class="form-input" required> | |
| </div> | |
| <button type="submit" class="btn btn-primary" style="width: 100%;">Login</button> | |
| <!-- Added register hyperlink underneath login button --> | |
| <div style="text-align: center; margin-top: 1rem;"> | |
| <span style="color: #64748b; font-size: 0.875rem;">Don't have an account? </span> | |
| <a href="#" onclick="showRegisterForm()" style="color: #0ea5e9; text-decoration: none; font-weight: 500; font-size: 0.875rem;">Register here</a> | |
| </div> | |
| </form> | |
| <!-- Enhanced registration form with role selection and removed toggle --> | |
| <form id="registerForm" style="display: none;"> | |
| <div class="form-group"> | |
| <label class="form-label" for="registerName">Full Name</label> | |
| <input type="text" id="registerName" class="form-input" required> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label" for="registerEmail">Email</label> | |
| <input type="email" id="registerEmail" class="form-input" required> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label" for="registerRole">Role</label> | |
| <select id="registerRole" class="form-input" required> | |
| <option value="">Select your role</option> | |
| <option value="student">Student</option> | |
| <option value="professor">Professor/TA</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label" for="registerPassword">Password</label> | |
| <input type="password" id="registerPassword" class="form-input" required> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label" for="confirmPassword">Confirm Password</label> | |
| <input type="password" id="confirmPassword" class="form-input" required> | |
| </div> | |
| <div id="passwordError" style="color: #ef4444; font-size: 0.875rem; margin-bottom: 1rem; display: none;"> | |
| Passwords do not match | |
| </div> | |
| <button type="submit" class="btn btn-primary" style="width: 100%;">Register & Setup Face</button> | |
| <!-- Added back to login link --> | |
| <div style="text-align: center; margin-top: 1rem;"> | |
| <span style="color: #64748b; font-size: 0.875rem;">Already have an account? </span> | |
| <a href="#" onclick="showLoginForm()" style="color: #0ea5e9; text-decoration: none; font-weight: 500; font-size: 0.875rem;">Login here</a> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| <!-- Enhanced Face Registration Modal with live camera --> | |
| <div id="faceRegisterModal" class="modal"> | |
| <div class="modal-content" style="max-width: 500px;"> | |
| <div class="modal-header"> | |
| <h3 class="modal-title">Register Your Face</h3> | |
| <button class="close-btn" onclick="closeFaceRegister()">×</button> | |
| </div> | |
| <div class="modal-body"> | |
| <p style="text-align: center; color: #64748b; margin-bottom: 1rem;"> | |
| Position your face within the frame and click capture to complete registration | |
| </p> | |
| <div class="camera-container" style="position: relative; background: #000; border-radius: 8px; overflow: hidden; margin-bottom: 1rem;"> | |
| <video id="faceVideo" style="width: 100%; height: 300px; object-fit: cover;" autoplay muted></video> | |
| <canvas id="faceCanvas" style="display: none;"></canvas> | |
| <div class="scan-overlay" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 200px; height: 200px; border: 2px solid #22d3ee; border-radius: 50%; opacity: 0.8;"></div> | |
| </div> | |
| <div id="captureResult" style="text-align: center; margin-bottom: 1rem; display: none;"> | |
| <div style="color: #22c55e; font-weight: 500;">✓ Face captured successfully!</div> | |
| </div> | |
| <div style="display: flex; gap: 1rem;"> | |
| <button id="captureBtn" class="btn btn-primary" style="flex: 1;" onclick="captureFace()">Capture Face</button> | |
| <button id="completeBtn" class="btn btn-success" style="flex: 1; display: none;" onclick="completeRegistration()">Complete Registration</button> | |
| <button class="btn btn-secondary" style="flex: 1;" onclick="closeFaceRegister()">Cancel</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| let currentUser = 'student'; | |
| let faceStream = null; | |
| let faceCaptured = false; | |
| function switchTab(userType) { | |
| currentUser = userType; | |
| const tabs = document.querySelectorAll('.tab'); | |
| tabs.forEach(tab => tab.classList.remove('active')); | |
| event.target.classList.add('active'); | |
| } | |
| function showRegisterForm() { | |
| document.getElementById('loginForm').style.display = 'none'; | |
| document.getElementById('registerForm').style.display = 'block'; | |
| document.querySelector('.login-tabs').style.display = 'none'; | |
| } | |
| function showLoginForm() { | |
| document.getElementById('registerForm').style.display = 'none'; | |
| document.getElementById('loginForm').style.display = 'block'; | |
| document.querySelector('.login-tabs').style.display = 'flex'; | |
| } | |
| async function showFaceRegister() { | |
| document.getElementById('faceRegisterModal').classList.add('active'); | |
| try { | |
| faceStream = await navigator.mediaDevices.getUserMedia({ | |
| video: { | |
| width: 640, | |
| height: 480, | |
| facingMode: 'user' | |
| } | |
| }); | |
| document.getElementById('faceVideo').srcObject = faceStream; | |
| } catch (error) { | |
| console.error('Error accessing camera:', error); | |
| alert('Unable to access camera. Please ensure camera permissions are granted.'); | |
| } | |
| } | |
| function closeFaceRegister() { | |
| document.getElementById('faceRegisterModal').classList.remove('active'); | |
| if (faceStream) { | |
| faceStream.getTracks().forEach(track => track.stop()); | |
| faceStream = null; | |
| } | |
| // Reset capture state | |
| faceCaptured = false; | |
| document.getElementById('captureResult').style.display = 'none'; | |
| document.getElementById('captureBtn').style.display = 'block'; | |
| document.getElementById('completeBtn').style.display = 'none'; | |
| } | |
| function captureFace() { | |
| const video = document.getElementById('faceVideo'); | |
| const canvas = document.getElementById('faceCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| canvas.width = video.videoWidth; | |
| canvas.height = video.videoHeight; | |
| ctx.drawImage(video, 0, 0); | |
| // Simulate face detection processing | |
| setTimeout(() => { | |
| faceCaptured = true; | |
| document.getElementById('captureResult').style.display = 'block'; | |
| document.getElementById('captureBtn').style.display = 'none'; | |
| document.getElementById('completeBtn').style.display = 'block'; | |
| }, 1000); | |
| } | |
| function completeRegistration() { | |
| alert('Registration completed successfully! You can now login.'); | |
| closeFaceRegister(); | |
| showLoginForm(); | |
| } | |
| document.getElementById('loginForm').addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| if (currentUser === 'student') { | |
| window.location.href = 'student.html'; | |
| } else { | |
| window.location.href = 'professor.html'; | |
| } | |
| }); | |
| document.getElementById('registerForm').addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| const password = document.getElementById('registerPassword').value; | |
| const confirmPassword = document.getElementById('confirmPassword').value; | |
| const errorDiv = document.getElementById('passwordError'); | |
| if (password !== confirmPassword) { | |
| errorDiv.style.display = 'block'; | |
| return; | |
| } | |
| errorDiv.style.display = 'none'; | |
| const selectedRole = document.getElementById('registerRole').value; | |
| sessionStorage.setItem('registeringRole', selectedRole); | |
| showFaceRegister(); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |