Files
urllists/static/templates/register.html
2025-11-30 12:19:31 +00:00

274 lines
9.6 KiB
HTML

{% extends "base.html" %}
{% block title %}Register - {{ app_name }}{% endblock %}
{% block content %}
<div class="min-h-screen flex items-center justify-center -mt-8">
<div class="w-full max-w-md">
<div class="card p-6 md:p-8">
<h2 class="text-3xl font-bold mb-2 text-center">Create Account</h2>
<p class="text-center text-slate-400 mb-6">Join {{ app_name }} today</p>
<div id="errorMsg" class="hidden mb-4 alert alert-error"></div>
<div id="successMsg" class="hidden mb-4 alert alert-success"></div>
<form id="registerForm" class="space-y-4" novalidate>
<div class="form-group">
<label for="email" class="form-label">Email Address</label>
<input
type="email"
name="email"
id="email"
required
class="form-input"
placeholder="you@example.com"
autocomplete="email"
maxlength="254"
>
<span id="emailError" class="text-xs text-red-400 mt-1 hidden"></span>
</div>
<div class="form-group">
<label for="password" class="form-label">Password</label>
<input
type="password"
name="password"
id="password"
required
class="form-input"
placeholder="••••••••"
autocomplete="new-password"
minlength="8"
maxlength="128"
>
<p class="mt-2 text-xs text-slate-400">Minimum 8 characters</p>
<span id="passwordError" class="text-xs text-red-400 mt-1 hidden"></span>
</div>
<div class="form-group">
<label for="passwordConfirm" class="form-label">Confirm Password</label>
<input
type="password"
name="passwordConfirm"
id="passwordConfirm"
required
class="form-input"
placeholder="••••••••"
autocomplete="new-password"
minlength="8"
maxlength="128"
>
<span id="confirmError" class="text-xs text-red-400 mt-1 hidden"></span>
</div>
<div class="flex items-start">
<input
type="checkbox"
name="terms"
id="terms"
required
class="w-4 h-4 bg-slate-700 border border-slate-600 rounded cursor-pointer mt-1"
>
<label for="terms" class="ml-2 text-sm text-slate-400 cursor-pointer">
I agree to the Terms of Service
</label>
</div>
<span id="termsError" class="text-xs text-red-400 mt-1 hidden block"></span>
<button
type="submit"
class="btn-primary w-full mt-6"
id="submitBtn"
>
Create Account
</button>
</form>
<div class="mt-6 text-center">
<p class="text-slate-400">
Already have an account?
<a href="{{ url_for('login') }}" class="text-sky-400 hover:text-sky-300 font-semibold transition-colors">
Sign in
</a>
</p>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
if (isAuthenticated()) {
window.location.href = "{{ url_for('dashboard') }}";
}
});
const registerForm = document.getElementById('registerForm');
const errorMsg = document.getElementById('errorMsg');
const successMsg = document.getElementById('successMsg');
const submitBtn = document.getElementById('submitBtn');
function showError(message) {
errorMsg.textContent = message;
errorMsg.classList.remove('hidden');
successMsg.classList.add('hidden');
}
function showSuccess(message) {
successMsg.textContent = message;
successMsg.classList.remove('hidden');
errorMsg.classList.add('hidden');
}
function clearMessages() {
errorMsg.classList.add('hidden');
successMsg.classList.add('hidden');
}
function validateEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email) && email.length <= 254;
}
function validateForm() {
clearMessages();
const email = document.getElementById('email').value.trim();
const password = document.getElementById('password').value;
const passwordConfirm = document.getElementById('passwordConfirm').value;
const terms = document.getElementById('terms').checked;
const emailError = document.getElementById('emailError');
const passwordError = document.getElementById('passwordError');
const confirmError = document.getElementById('confirmError');
const termsError = document.getElementById('termsError');
let isValid = true;
// Validate email
if (!email) {
emailError.textContent = 'Email is required';
emailError.classList.remove('hidden');
isValid = false;
} else if (!validateEmail(email)) {
emailError.textContent = 'Please enter a valid email address';
emailError.classList.remove('hidden');
isValid = false;
} else {
emailError.classList.add('hidden');
}
// Validate password
if (!password) {
passwordError.textContent = 'Password is required';
passwordError.classList.remove('hidden');
isValid = false;
} else if (password.length < 8) {
passwordError.textContent = 'Password must be at least 8 characters';
passwordError.classList.remove('hidden');
isValid = false;
} else {
passwordError.classList.add('hidden');
}
// Validate password confirmation
if (!passwordConfirm) {
confirmError.textContent = 'Please confirm your password';
confirmError.classList.remove('hidden');
isValid = false;
} else if (password !== passwordConfirm) {
confirmError.textContent = 'Passwords do not match';
confirmError.classList.remove('hidden');
isValid = false;
} else {
confirmError.classList.add('hidden');
}
// Validate terms
if (!terms) {
termsError.textContent = 'You must agree to the Terms of Service';
termsError.classList.remove('hidden');
isValid = false;
} else {
termsError.classList.add('hidden');
}
return isValid;
}
registerForm.addEventListener('submit', async (e) => {
e.preventDefault();
// Validate form
if (!validateForm()) {
showError('Please correct the errors above');
return;
}
// Get form values
const email = document.getElementById('email').value.trim().toLowerCase();
const password = document.getElementById('password').value;
// Disable submit button
submitBtn.disabled = true;
submitBtn.textContent = 'Creating account...';
const data = {
email: email,
password: password
};
try {
const response = await fetch('/api/auth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (response.ok) {
showSuccess('Account created successfully! Redirecting to login...');
setTimeout(() => {
window.location.href = "{{ url_for('login') }}";
}, 1500);
} else {
const error = await response.json();
const errorDetail = error.detail || 'Registration failed. Please try again.';
// Handle specific error cases
if (typeof errorDetail === 'string' && errorDetail.includes('already exists')) {
showError('This email is already registered. Please use a different email or try logging in.');
} else {
showError(errorDetail);
}
submitBtn.disabled = false;
submitBtn.textContent = 'Create Account';
}
} catch (error) {
console.error('Registration error:', error);
showError('An error occurred during registration. Please try again.');
submitBtn.disabled = false;
submitBtn.textContent = 'Create Account';
}
});
// Clear inline errors on input
document.getElementById('email').addEventListener('input', () => {
document.getElementById('emailError').classList.add('hidden');
});
document.getElementById('password').addEventListener('input', () => {
document.getElementById('passwordError').classList.add('hidden');
});
document.getElementById('passwordConfirm').addEventListener('input', () => {
document.getElementById('confirmError').classList.add('hidden');
});
document.getElementById('terms').addEventListener('change', () => {
document.getElementById('termsError').classList.add('hidden');
});
</script>
{% endblock %}