Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Login & Register</title> | |
<style> | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
} | |
body { | |
min-height: 100vh; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
background: linear-gradient(45deg, #6b5b95, #feb236); | |
} | |
.container { | |
background: rgba(255, 255, 255, 0.95); | |
border-radius: 20px; | |
padding: 40px; | |
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2); | |
width: 400px; | |
} | |
.form-group { | |
margin-bottom: 20px; | |
} | |
h2 { | |
text-align: center; | |
color: #333; | |
margin-bottom: 30px; | |
} | |
input { | |
width: 100%; | |
padding: 12px; | |
border: 2px solid #ddd; | |
border-radius: 8px; | |
font-size: 16px; | |
transition: all 0.3s ease; | |
outline: none; | |
} | |
input:focus { | |
border-color: #6b5b95; | |
} | |
button { | |
width: 100%; | |
padding: 12px; | |
background: #6b5b95; | |
color: white; | |
border: none; | |
border-radius: 8px; | |
font-size: 16px; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
} | |
button:hover { | |
background: #574a7a; | |
} | |
.switch-form { | |
text-align: center; | |
margin-top: 20px; | |
} | |
.switch-form a { | |
color: #6b5b95; | |
text-decoration: none; | |
font-weight: 600; | |
} | |
.alert { | |
padding: 10px; | |
margin: 10px 0; | |
border-radius: 8px; | |
display: none; | |
} | |
.alert-success { | |
background: #d4edda; | |
color: #155724; | |
border: 1px solid #c3e6cb; | |
} | |
.alert-error { | |
background: #f8d7da; | |
color: #721c24; | |
border: 1px solid #f5c6cb; | |
} | |
.password-requirements { | |
font-size: 12px; | |
color: #666; | |
margin-top: 5px; | |
} | |
.loading { | |
display: none; | |
text-align: center; | |
margin-top: 10px; | |
} | |
.loading::after { | |
content: "..."; | |
animation: dots 1s steps(5, end) infinite; | |
} | |
@keyframes dots { | |
0%, 20% { content: "."; } | |
40% { content: ".."; } | |
60%, 100% { content: "..."; } | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<div id="loginForm"> | |
<h2>Login</h2> | |
<div class="alert alert-error" id="loginError"></div> | |
<form onsubmit="handleLogin(event)"> | |
<div class="form-group"> | |
<input type="email" id="loginEmail" placeholder="Email" required> | |
</div> | |
<div class="form-group"> | |
<input type="password" id="loginPassword" placeholder="Password" required> | |
</div> | |
<button type="submit">Login</button> | |
<div class="loading" id="loginLoading">Processing</div> | |
</form> | |
<div class="switch-form"> | |
Don't have an account? <a href="#" onclick="toggleForms()">Register</a> | |
</div> | |
</div> | |
<div id="registerForm" style="display: none;"> | |
<h2>Register</h2> | |
<div class="alert alert-success" id="registerSuccess"></div> | |
<div class="alert alert-error" id="registerError"></div> | |
<form onsubmit="handleRegister(event)"> | |
<div class="form-group"> | |
<input type="email" id="registerEmail" placeholder="Email" required> | |
</div> | |
<div class="form-group"> | |
<input type="password" id="registerPassword" placeholder="Password" required> | |
<div class="password-requirements"> | |
Password must be at least 8 characters long and contain letters and numbers | |
</div> | |
</div> | |
<div class="form-group"> | |
<input type="password" id="confirmPassword" placeholder="Confirm Password" required> | |
</div> | |
<button type="submit">Register</button> | |
<div class="loading" id="registerLoading">Processing</div> | |
</form> | |
<div class="switch-form"> | |
Already have an account? <a href="#" onclick="toggleForms()">Login</a> | |
</div> | |
</div> | |
</div> | |
<script> | |
// Mock user database | |
let users = []; | |
function toggleForms() { | |
const loginForm = document.getElementById('loginForm'); | |
const registerForm = document.getElementById('registerForm'); | |
if (loginForm.style.display === 'none') { | |
loginForm.style.display = 'block'; | |
registerForm.style.display = 'none'; | |
} else { | |
loginForm.style.display = 'none'; | |
registerForm.style.display = 'block'; | |
} | |
// Clear all alerts and forms | |
clearAlerts(); | |
document.querySelectorAll('form').forEach(form => form.reset()); | |
} | |
function clearAlerts() { | |
document.querySelectorAll('.alert').forEach(alert => { | |
alert.style.display = 'none'; | |
}); | |
document.querySelectorAll('.loading').forEach(loading => { | |
loading.style.display = 'none'; | |
}); | |
} | |
function validatePassword(password) { | |
const minLength = 8; | |
const hasLetter = /[a-zA-Z]/.test(password); | |
const hasNumber = /\d/.test(password); | |
return password.length >= minLength && hasLetter && hasNumber; | |
} | |
async function handleRegister(event) { | |
event.preventDefault(); | |
clearAlerts(); | |
const email = document.getElementById('registerEmail').value; | |
const password = document.getElementById('registerPassword').value; | |
const confirmPassword = document.getElementById('confirmPassword').value; | |
const loading = document.getElementById('registerLoading'); | |
const success = document.getElementById('registerSuccess'); | |
const error = document.getElementById('registerError'); | |
if (!validatePassword(password)) { | |
error.textContent = 'Password must be at least 8 characters long and contain both letters and numbers'; | |
error.style.display = 'block'; | |
return; | |
} | |
if (password !== confirmPassword) { | |
error.textContent = 'Passwords do not match'; | |
error.style.display = 'block'; | |
return; | |
} | |
if (users.some(user => user.email === email)) { | |
error.textContent = 'Email already registered'; | |
error.style.display = 'block'; | |
return; | |
} | |
loading.style.display = 'block'; | |
// Simulate API call | |
await new Promise(resolve => setTimeout(resolve, 1500)); | |
users.push({ email, password }); | |
loading.style.display = 'none'; | |
success.textContent = 'Registration successful! Please login.'; | |
success.style.display = 'block'; | |
// Clear form | |
event.target.reset(); | |
// Switch to login form after 2 seconds | |
setTimeout(toggleForms, 2000); | |
} | |
async function handleLogin(event) { | |
event.preventDefault(); | |
clearAlerts(); | |
const email = document.getElementById('loginEmail').value; | |
const password = document.getElementById('loginPassword').value; | |
const loading = document.getElementById('loginLoading'); | |
const error = document.getElementById('loginError'); | |
loading.style.display = 'block'; | |
// Simulate API call | |
await new Promise(resolve => setTimeout(resolve, 1500)); | |
const user = users.find(u => u.email === email && u.password === password); | |
loading.style.display = 'none'; | |
if (user) { | |
alert('Login successful!'); | |
event.target.reset(); | |
} else { | |
error.textContent = 'Invalid email or password'; | |
error.style.display = 'block'; | |
} | |
} | |
</script> | |
</body> | |
</html> |