378 lines
12 KiB
HTML
378 lines
12 KiB
HTML
{% extends "base_authenticated.html" %} {% block title %}Create New User - QR
|
|
Code Management{% endblock %} {% block content %}
|
|
<div class="create-user-page">
|
|
<div class="page-header">
|
|
<div class="header-content">
|
|
<h1>
|
|
<i class="fas fa-user-plus"></i>
|
|
Create New User
|
|
</h1>
|
|
<p>Add a new user to the system with appropriate role permissions</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="create-user-container">
|
|
<form
|
|
id="createUserForm"
|
|
method="POST"
|
|
action="{{ url_for('create_user') }}"
|
|
>
|
|
<div class="form-section">
|
|
<h3>
|
|
<i class="fas fa-user"></i>
|
|
User Information
|
|
</h3>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="full_name">
|
|
<i class="fas fa-id-card"></i>
|
|
Full Name
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="full_name"
|
|
name="full_name"
|
|
required
|
|
placeholder="Enter full name"
|
|
/>
|
|
<small class="form-help">First and last name</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="email">
|
|
<i class="fas fa-envelope"></i>
|
|
Email Address
|
|
</label>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
required
|
|
placeholder="user@example.com"
|
|
/>
|
|
<small class="form-help">Must be unique in the system</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="username">
|
|
<i class="fas fa-user"></i>
|
|
Username
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="username"
|
|
name="username"
|
|
required
|
|
pattern="[a-zA-Z0-9_]+"
|
|
placeholder="Enter username"
|
|
/>
|
|
<small class="form-help"
|
|
>Letters, numbers, and underscores only</small
|
|
>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="role">
|
|
<i class="fas fa-user-shield"></i>
|
|
User Role
|
|
</label>
|
|
<select id="role" name="role" required>
|
|
<option value="">Select Role</option>
|
|
<option value="staff">Staff User</option>
|
|
<option value="payroll">Payroll Specialist</option>
|
|
<option value="project_manager">Project Manager</option>
|
|
<option value="admin">Administrator</option>
|
|
</select>
|
|
<small class="form-help"
|
|
>Determines user permissions and system access level</small
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="password">
|
|
<i class="fas fa-lock"></i>
|
|
Initial Password
|
|
</label>
|
|
<input
|
|
type="password"
|
|
id="password"
|
|
name="password"
|
|
required
|
|
minlength="6"
|
|
placeholder="Enter initial password"
|
|
/>
|
|
<div class="password-strength" id="passwordStrength"></div>
|
|
<small class="form-help"
|
|
>Minimum 6 characters. User should change on first login</small
|
|
>
|
|
</div>
|
|
|
|
<!-- Role Information Panel -->
|
|
<div class="info-panel" id="roleInfo" style="display: none">
|
|
<div class="info-header">
|
|
<i class="fas fa-info-circle"></i>
|
|
<span>Role Permissions</span>
|
|
</div>
|
|
<div class="info-content" id="roleContent">
|
|
<!-- Dynamic content based on selected role -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- User Creation Summary -->
|
|
<div class="creation-summary" id="creationSummary" style="display: none">
|
|
<h3>
|
|
<i class="fas fa-check-circle"></i>
|
|
User Creation Summary
|
|
</h3>
|
|
<div class="summary-grid">
|
|
<div class="summary-item">
|
|
<strong>Name:</strong> <span id="summaryName">-</span>
|
|
</div>
|
|
<div class="summary-item">
|
|
<strong>Email:</strong> <span id="summaryEmail">-</span>
|
|
</div>
|
|
<div class="summary-item">
|
|
<strong>Username:</strong> <span id="summaryUsername">-</span>
|
|
</div>
|
|
<div class="summary-item">
|
|
<strong>Role:</strong> <span id="summaryRole">-</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<a href="{{ url_for('users') }}" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left"></i>
|
|
Back to Users
|
|
</a>
|
|
<button type="button" class="btn btn-info" id="previewUser">
|
|
<i class="fas fa-eye"></i>
|
|
Preview User
|
|
</button>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-user-plus"></i>
|
|
Create User
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endblock %} {% block extra_scripts %}
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
const form = document.getElementById("createUserForm");
|
|
const roleSelect = document.getElementById("role");
|
|
const roleInfo = document.getElementById("roleInfo");
|
|
const roleContent = document.getElementById("roleContent");
|
|
const previewBtn = document.getElementById("previewUser");
|
|
const creationSummary = document.getElementById("creationSummary");
|
|
|
|
// Form inputs
|
|
const fullNameInput = document.getElementById("full_name");
|
|
const emailInput = document.getElementById("email");
|
|
const usernameInput = document.getElementById("username");
|
|
const passwordInput = document.getElementById("password");
|
|
const passwordStrength = document.getElementById("passwordStrength");
|
|
|
|
// UPDATED: Role information with new roles
|
|
const rolePermissions = {
|
|
staff: {
|
|
title: "Staff User Permissions",
|
|
permissions: [
|
|
"Create and edit QR codes",
|
|
"View all QR codes in the system",
|
|
"Download QR code images",
|
|
"Update personal profile information",
|
|
"Access dashboard and reports",
|
|
],
|
|
restrictions: [
|
|
"Cannot delete QR codes",
|
|
"Cannot manage other users",
|
|
"Cannot access admin settings",
|
|
],
|
|
},
|
|
payroll: {
|
|
title: "Payroll Specialist Permissions",
|
|
permissions: [
|
|
"Create and edit QR codes",
|
|
"View all QR codes in the system",
|
|
"Download QR code images",
|
|
"Update personal profile information",
|
|
"Access dashboard and reports",
|
|
"Same permissions as Staff (additional features coming soon)",
|
|
],
|
|
restrictions: [
|
|
"Cannot delete QR codes",
|
|
"Cannot manage other users",
|
|
"Cannot access admin settings",
|
|
],
|
|
},
|
|
project_manager: {
|
|
title: "Project Manager Permissions",
|
|
permissions: [
|
|
"Create and edit QR codes",
|
|
"View all QR codes in the system",
|
|
"Download QR code images",
|
|
"Update personal profile information",
|
|
"Access dashboard and reports",
|
|
"Same permissions as Staff (additional features coming soon)",
|
|
],
|
|
restrictions: [
|
|
"Cannot delete QR codes",
|
|
"Cannot manage other users",
|
|
"Cannot access admin settings",
|
|
],
|
|
},
|
|
admin: {
|
|
title: "Administrator Permissions",
|
|
permissions: [
|
|
"Full QR code management (create, edit, delete)",
|
|
"Complete user management capabilities",
|
|
"System configuration access",
|
|
"View all system analytics",
|
|
"Bulk operations and data export",
|
|
"Access to all admin features",
|
|
],
|
|
restrictions: ["With great power comes great responsibility!"],
|
|
},
|
|
};
|
|
|
|
// Role selection handler
|
|
roleSelect.addEventListener("change", function () {
|
|
const selectedRole = this.value;
|
|
|
|
if (selectedRole && rolePermissions[selectedRole]) {
|
|
const roleData = rolePermissions[selectedRole];
|
|
|
|
let permissionsHtml = `
|
|
<h4>${roleData.title}</h4>
|
|
<div class="permissions-section">
|
|
<h5><i class="fas fa-check-circle text-success"></i> Permissions</h5>
|
|
<ul class="permissions-list">
|
|
`;
|
|
|
|
roleData.permissions.forEach((permission) => {
|
|
permissionsHtml += `<li><i class="fas fa-check"></i> ${permission}</li>`;
|
|
});
|
|
|
|
permissionsHtml += `
|
|
</ul>
|
|
<h5><i class="fas fa-times-circle text-warning"></i> Restrictions</h5>
|
|
<ul class="restrictions-list">
|
|
`;
|
|
|
|
roleData.restrictions.forEach((restriction) => {
|
|
permissionsHtml += `<li><i class="fas fa-times"></i> ${restriction}</li>`;
|
|
});
|
|
|
|
permissionsHtml += `</ul></div>`;
|
|
|
|
roleContent.innerHTML = permissionsHtml;
|
|
roleInfo.style.display = "block";
|
|
setTimeout(() => roleInfo.classList.add("fade-in"), 100);
|
|
} else {
|
|
roleInfo.style.display = "none";
|
|
roleInfo.classList.remove("fade-in");
|
|
}
|
|
});
|
|
|
|
// Password strength indicator
|
|
passwordInput.addEventListener("input", function () {
|
|
const password = this.value;
|
|
const strength = calculatePasswordStrength(password);
|
|
|
|
passwordStrength.className = `password-strength ${strength.class}`;
|
|
passwordStrength.textContent = strength.text;
|
|
});
|
|
|
|
// Preview user functionality
|
|
previewBtn.addEventListener("click", function () {
|
|
const fullName = fullNameInput.value.trim();
|
|
const email = emailInput.value.trim();
|
|
const username = usernameInput.value.trim();
|
|
const role = roleSelect.value;
|
|
|
|
if (!fullName || !email || !username || !role) {
|
|
alert("Please fill in all required fields before previewing.");
|
|
return;
|
|
}
|
|
|
|
// Update summary
|
|
document.getElementById("summaryName").textContent = fullName;
|
|
document.getElementById("summaryEmail").textContent = email;
|
|
document.getElementById("summaryUsername").textContent = username;
|
|
|
|
// Get role display name
|
|
const roleDisplayNames = {
|
|
staff: "Staff User",
|
|
payroll: "Payroll Specialist",
|
|
project_manager: "Project Manager",
|
|
admin: "Administrator",
|
|
};
|
|
document.getElementById("summaryRole").textContent =
|
|
roleDisplayNames[role] || role;
|
|
|
|
creationSummary.style.display = "block";
|
|
setTimeout(() => creationSummary.classList.add("fade-in"), 100);
|
|
|
|
// Scroll to summary
|
|
creationSummary.scrollIntoView({ behavior: "smooth" });
|
|
});
|
|
|
|
// Form validation
|
|
form.addEventListener("submit", function (e) {
|
|
const password = passwordInput.value;
|
|
|
|
if (password.length < 6) {
|
|
e.preventDefault();
|
|
alert("Password must be at least 6 characters long.");
|
|
passwordInput.focus();
|
|
return;
|
|
}
|
|
|
|
if (!roleSelect.value) {
|
|
e.preventDefault();
|
|
alert("Please select a user role.");
|
|
roleSelect.focus();
|
|
return;
|
|
}
|
|
});
|
|
|
|
// Username validation
|
|
usernameInput.addEventListener("input", function () {
|
|
this.value = this.value.replace(/[^a-zA-Z0-9_]/g, "");
|
|
});
|
|
});
|
|
|
|
function calculatePasswordStrength(password) {
|
|
if (password.length === 0) {
|
|
return { class: "", text: "" };
|
|
}
|
|
|
|
let score = 0;
|
|
|
|
// Length
|
|
if (password.length >= 6) score += 1;
|
|
if (password.length >= 8) score += 1;
|
|
if (password.length >= 12) score += 1;
|
|
|
|
// Character variety
|
|
if (/[a-z]/.test(password)) score += 1;
|
|
if (/[A-Z]/.test(password)) score += 1;
|
|
if (/[0-9]/.test(password)) score += 1;
|
|
if (/[^a-zA-Z0-9]/.test(password)) score += 1;
|
|
|
|
if (score < 3) {
|
|
return { class: "weak", text: "Weak password" };
|
|
} else if (score < 5) {
|
|
return { class: "medium", text: "Medium strength" };
|
|
} else {
|
|
return { class: "strong", text: "Strong password" };
|
|
}
|
|
}
|
|
</script>
|
|
{% endblock %}
|