359 lines
13 KiB
HTML
359 lines
13 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}Register - Hospital Management System{% endblock %}
|
|
|
|
{% block css %}
|
|
<style>
|
|
.register-container {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
padding: 2rem 0;
|
|
}
|
|
|
|
.register-card {
|
|
background: white;
|
|
border-radius: 15px;
|
|
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
|
|
overflow: hidden;
|
|
width: 100%;
|
|
max-width: 500px;
|
|
}
|
|
|
|
.register-header {
|
|
background: linear-gradient(135deg, #348ac7 0%, #7474bf 100%);
|
|
color: white;
|
|
padding: 2rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.register-body {
|
|
padding: 2rem;
|
|
}
|
|
|
|
.form-floating {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.btn-register {
|
|
background: linear-gradient(135deg, #348ac7 0%, #7474bf 100%);
|
|
border: none;
|
|
padding: 12px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
.btn-register:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 5px 15px rgba(52, 138, 199, 0.4);
|
|
}
|
|
|
|
.password-requirements {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.requirement {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.requirement.valid {
|
|
color: #28a745;
|
|
}
|
|
|
|
.requirement.invalid {
|
|
color: #dc3545;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="register-container">
|
|
<div class="register-card">
|
|
<div class="register-header">
|
|
<h3 class="mb-0">
|
|
<i class="fas fa-hospital-alt me-2"></i>
|
|
Hospital Management
|
|
</h3>
|
|
<p class="mb-0 mt-2 opacity-75">Create your account</p>
|
|
</div>
|
|
|
|
<div class="register-body">
|
|
{% if messages %}
|
|
{% for message in messages %}
|
|
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
|
{{ message }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
{% if form.non_field_errors %}
|
|
<div class="alert alert-danger">
|
|
{{ form.non_field_errors }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<form method="post" novalidate>
|
|
{% csrf_token %}
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
<input type="text"
|
|
class="form-control {% if form.first_name.errors %}is-invalid{% endif %}"
|
|
id="id_first_name"
|
|
name="first_name"
|
|
placeholder="First Name"
|
|
value="{{ form.first_name.value|default:'' }}"
|
|
required>
|
|
<label for="id_first_name">
|
|
<i class="fas fa-user me-2"></i>First Name
|
|
</label>
|
|
{% if form.first_name.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.first_name.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
<input type="text"
|
|
class="form-control {% if form.last_name.errors %}is-invalid{% endif %}"
|
|
id="id_last_name"
|
|
name="last_name"
|
|
placeholder="Last Name"
|
|
value="{{ form.last_name.value|default:'' }}"
|
|
required>
|
|
<label for="id_last_name">
|
|
<i class="fas fa-user me-2"></i>Last Name
|
|
</label>
|
|
{% if form.last_name.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.last_name.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-floating">
|
|
<input type="text"
|
|
class="form-control {% if form.username.errors %}is-invalid{% endif %}"
|
|
id="id_username"
|
|
name="username"
|
|
placeholder="Username"
|
|
value="{{ form.username.value|default:'' }}"
|
|
required>
|
|
<label for="id_username">
|
|
<i class="fas fa-at me-2"></i>Username
|
|
</label>
|
|
{% if form.username.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.username.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="form-floating">
|
|
<input type="email"
|
|
class="form-control {% if form.email.errors %}is-invalid{% endif %}"
|
|
id="id_email"
|
|
name="email"
|
|
placeholder="Email"
|
|
value="{{ form.email.value|default:'' }}"
|
|
required>
|
|
<label for="id_email">
|
|
<i class="fas fa-envelope me-2"></i>Email Address
|
|
</label>
|
|
{% if form.email.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.email.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="form-floating">
|
|
<input type="password"
|
|
class="form-control {% if form.password1.errors %}is-invalid{% endif %}"
|
|
id="id_password1"
|
|
name="password1"
|
|
placeholder="Password"
|
|
required>
|
|
<label for="id_password1">
|
|
<i class="fas fa-lock me-2"></i>Password
|
|
</label>
|
|
{% if form.password1.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.password1.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="form-floating">
|
|
<input type="password"
|
|
class="form-control {% if form.password2.errors %}is-invalid{% endif %}"
|
|
id="id_password2"
|
|
name="password2"
|
|
placeholder="Confirm Password"
|
|
required>
|
|
<label for="id_password2">
|
|
<i class="fas fa-lock me-2"></i>Confirm Password
|
|
</label>
|
|
{% if form.password2.errors %}
|
|
<div class="invalid-feedback">
|
|
{{ form.password2.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="password-requirements mb-3">
|
|
<small class="text-muted">Password requirements:</small>
|
|
<div id="password-requirements">
|
|
<div class="requirement" id="req-length">
|
|
<i class="fas fa-times me-2"></i>At least 8 characters
|
|
</div>
|
|
<div class="requirement" id="req-uppercase">
|
|
<i class="fas fa-times me-2"></i>One uppercase letter
|
|
</div>
|
|
<div class="requirement" id="req-lowercase">
|
|
<i class="fas fa-times me-2"></i>One lowercase letter
|
|
</div>
|
|
<div class="requirement" id="req-number">
|
|
<i class="fas fa-times me-2"></i>One number
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" id="terms_accepted" name="terms_accepted" required>
|
|
<label class="form-check-label" for="terms_accepted">
|
|
I agree to the <a href="#" data-bs-toggle="modal" data-bs-target="#termsModal">Terms of Service</a>
|
|
and <a href="#" data-bs-toggle="modal" data-bs-target="#privacyModal">Privacy Policy</a>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="d-grid">
|
|
<button type="submit" class="btn btn-primary btn-register" id="registerBtn" disabled>
|
|
<i class="fas fa-user-plus me-2"></i>Create Account
|
|
</button>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<div class="text-center">
|
|
<p class="text-muted mb-2">Already have an account?</p>
|
|
<a href="{% url 'accounts:login' %}" class="btn btn-outline-primary">
|
|
<i class="fas fa-sign-in-alt me-2"></i>Sign In
|
|
</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Terms Modal -->
|
|
<div class="modal fade" id="termsModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Terms of Service</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>By using the Hospital Management System, you agree to the following terms...</p>
|
|
<!-- Add actual terms content here -->
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Privacy Modal -->
|
|
<div class="modal fade" id="privacyModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Privacy Policy</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Your privacy is important to us. This policy explains how we collect and use your data...</p>
|
|
<!-- Add actual privacy policy content here -->
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const password1 = document.getElementById('id_password1');
|
|
const password2 = document.getElementById('id_password2');
|
|
const termsCheckbox = document.getElementById('terms_accepted');
|
|
const registerBtn = document.getElementById('registerBtn');
|
|
|
|
// Password validation
|
|
function validatePassword() {
|
|
const password = password1.value;
|
|
const requirements = {
|
|
'req-length': password.length >= 8,
|
|
'req-uppercase': /[A-Z]/.test(password),
|
|
'req-lowercase': /[a-z]/.test(password),
|
|
'req-number': /\d/.test(password)
|
|
};
|
|
|
|
let allValid = true;
|
|
Object.keys(requirements).forEach(req => {
|
|
const element = document.getElementById(req);
|
|
const icon = element.querySelector('i');
|
|
|
|
if (requirements[req]) {
|
|
element.classList.add('valid');
|
|
element.classList.remove('invalid');
|
|
icon.className = 'fas fa-check me-2';
|
|
} else {
|
|
element.classList.add('invalid');
|
|
element.classList.remove('valid');
|
|
icon.className = 'fas fa-times me-2';
|
|
allValid = false;
|
|
}
|
|
});
|
|
|
|
return allValid;
|
|
}
|
|
|
|
function updateRegisterButton() {
|
|
const passwordValid = validatePassword();
|
|
const passwordsMatch = password1.value === password2.value && password1.value !== '';
|
|
const termsAccepted = termsCheckbox.checked;
|
|
|
|
registerBtn.disabled = !(passwordValid && passwordsMatch && termsAccepted);
|
|
}
|
|
|
|
password1.addEventListener('input', updateRegisterButton);
|
|
password2.addEventListener('input', updateRegisterButton);
|
|
termsCheckbox.addEventListener('change', updateRegisterButton);
|
|
|
|
// Form submission
|
|
const form = document.querySelector('form');
|
|
form.addEventListener('submit', function() {
|
|
registerBtn.disabled = true;
|
|
registerBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Creating Account...';
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|