<?php
// Include database configuration
require_once '../admin/database/db_config.php';
// Include header
include_once 'includes/header.php';
// Handle session messages
$msg = null;
$error = null;
if (isset($_SESSION['success_message'])) {
$msg = $_SESSION['success_message'];
unset($_SESSION['success_message']);
}
if (isset($_SESSION['error_messages'])) {
$error = implode('<br>', $_SESSION['error_messages']);
unset($_SESSION['error_messages']);
}
// Handle user deletion
if (isset($_POST['delete_user']) && isset($_POST['user_id'])) {
$user_id = (int)$_POST['user_id'];
if ($user_id !== $_SESSION['user_id']) { // Prevent self-deletion
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $user_id);
if ($stmt->execute()) {
$msg = "User deleted successfully!";
} else {
$error = "Error deleting user: " . $conn->error;
}
} else {
$error = "You cannot delete your own account!";
}
}
// Get users with pagination
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$per_page = 10;
$offset = ($page - 1) * $per_page;
$search = isset($_GET['search']) ? $_GET['search'] : '';
$role_filter = isset($_GET['role']) ? $_GET['role'] : '';
// Build the query
$where_conditions = [];
$params = [];
$types = '';
if (!empty($search)) {
$where_conditions[] = "(username LIKE ? OR email LIKE ? OR first_name LIKE ? OR last_name LIKE ?)";
$search_param = "%$search%";
$params[] = $search_param;
$params[] = $search_param;
$params[] = $search_param;
$params[] = $search_param;
$types .= 'ssss';
}
if (!empty($role_filter)) {
$where_conditions[] = "role = ?";
$params[] = $role_filter;
$types .= 's';
}
$where_clause = !empty($where_conditions) ? "WHERE " . implode(" AND ", $where_conditions) : "";
// Count total users for pagination
$count_query = "SELECT COUNT(*) as total FROM users $where_clause";
$count_stmt = $conn->prepare($count_query);
if (!empty($params)) {
$count_stmt->bind_param($types, ...$params);
}
$count_stmt->execute();
$count_result = $count_stmt->get_result();
$total_users = $count_result->fetch_assoc()['total'];
$total_pages = ceil($total_users / $per_page);
// Get users
$query = "SELECT * FROM users $where_clause ORDER BY id DESC LIMIT ?, ?";
$stmt = $conn->prepare($query);
// Add pagination parameters
$params[] = $offset;
$params[] = $per_page;
$types .= 'ii';
if (!empty($params)) {
$stmt->bind_param($types, ...$params);
}
$stmt->execute();
$result = $stmt->get_result();
?>
<style>
/* Fix for modal focus and blinking issues */
.modal {
padding-right: 0 !important;
}
.modal-open {
overflow: auto !important;
padding-right: 0 !important;
}
.modal-dialog {
transition: transform 0.15s ease-out !important;
}
.modal-content {
border: none;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
/* Prevent form field blinking when focused */
.modal input:focus,
.modal select:focus,
.modal textarea:focus {
transition: none !important;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25) !important;
outline: none !important;
}
/* Prevent blinking during form submission */
form.submitting {
opacity: 0.7;
pointer-events: none;
}
/* Additional styles to prevent cursor jumping and blinking */
.modal-body {
overflow-y: auto;
max-height: 70vh;
}
.modal label {
display: block;
font-weight: 500;
}
.modal .form-control,
.modal .form-select {
font-size: 0.95rem;
-webkit-appearance: none;
}
/* Fix for button flickering on hover */
.modal .btn {
transition-duration: 0s !important;
}
/* Ensure consistent sizing for modals across all screens */
@media (min-width: 576px) {
.modal-dialog {
max-width: 500px;
margin: 1.75rem auto;
}
}
/* Highlight updated user row */
.highlight-row {
animation: highlight-fade 3s ease-in-out;
}
@keyframes highlight-fade {
0% { background-color: rgba(220, 232, 255, 0.7); }
70% { background-color: rgba(220, 232, 255, 0.7); }
100% { background-color: transparent; }
}
</style>
<!-- Breadcrumb -->
<nav aria-label="breadcrumb" class="mb-4">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.php">Dashboard</a></li>
<li class="breadcrumb-item active">Users Management</li>
</ol>
</nav>
<!-- Page Title and Action Buttons -->
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1 class="h3 mb-0 text-gray-800">Users Management</h1>
<small class="text-muted">
<i class="fas fa-info-circle me-1"></i> Note: Both Admin and Developer roles have full administrative access.
</small>
</div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addUserModal">
<i class="fas fa-plus me-1"></i> Add New User
</button>
</div>
<!-- Alerts for success and error messages -->
<?php if (isset($msg)): ?>
<div class="alert alert-success alert-dismissible fade show mb-4 animate__animated animate__fadeIn" role="alert">
<?php echo $msg; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if (isset($_SESSION['success_message'])): ?>
<div class="alert alert-success alert-dismissible fade show mb-4" role="alert">
<?php echo $_SESSION['success_message']; unset($_SESSION['success_message']); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if (isset($error)): ?>
<div class="alert alert-danger alert-dismissible fade show mb-4 animate__animated animate__fadeIn" role="alert">
<?php echo $error; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php
// Check for 'designation' column errors
if (isset($error) && strpos($error, "Unknown column 'designation'") !== false):
?>
<div class="alert alert-warning alert-dismissible fade show mb-4" role="alert">
<strong><i class="fas fa-exclamation-triangle me-2"></i> Database Fix Required:</strong>
Your database is missing required columns.
<a href="database/fix_missing_columns.php" class="alert-link">Click here to run the comprehensive database fix</a> to resolve all missing column issues.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if (isset($_SESSION['error_messages'])): ?>
<div class="alert alert-danger alert-dismissible fade show mb-4 animate__animated animate__fadeIn" role="alert">
<ul class="mb-0">
<?php foreach ($_SESSION['error_messages'] as $error_msg): ?>
<li><?php echo $error_msg; ?></li>
<?php endforeach; ?>
</ul>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php unset($_SESSION['error_messages']); ?>
<?php endif; ?>
<!-- Main Content -->
<div class="card mb-4 shadow-sm">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Users</h5>
<div class="d-flex">
<!-- Role Filter -->
<form method="get" class="me-2">
<input type="hidden" name="search" value="<?php echo htmlspecialchars($search); ?>">
<select class="form-select form-select-sm" name="role" onchange="this.form.submit()">
<option value="">All Roles</option>
<option value="admin" <?php echo $role_filter === 'admin' ? 'selected' : ''; ?>>Admin</option>
<option value="instructor" <?php echo $role_filter === 'instructor' ? 'selected' : ''; ?>>Instructor</option>
<option value="student" <?php echo $role_filter === 'student' ? 'selected' : ''; ?>>Student</option>
<option value="director" <?php echo $role_filter === 'director' ? 'selected' : ''; ?>>Director</option>
<option value="developer" <?php echo $role_filter === 'developer' ? 'selected' : ''; ?>>Developer</option>
</select>
</form>
<!-- Search Form -->
<form class="d-flex" method="get">
<input type="hidden" name="role" value="<?php echo htmlspecialchars($role_filter); ?>">
<div class="input-group">
<input type="text" class="form-control form-control-sm" placeholder="Search users..." name="search"
value="<?php echo htmlspecialchars($search); ?>">
<button class="btn btn-outline-primary btn-sm" type="submit">
<i class="fas fa-search"></i>
</button>
</div>
</form>
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th>ID</th>
<th>Profile</th>
<th>Username</th>
<th>Name</th>
<th>Email</th>
<th>Role</th>
<th>Joined Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if ($result->num_rows > 0): ?>
<?php while ($user = $result->fetch_assoc()): ?>
<tr id="user<?php echo $user['id']; ?>">
<td><?php echo $user['id']; ?></td>
<td>
<?php
$profile_image = null;
if (isset($user['profile_image']) && !empty($user['profile_image'])) {
// Check if the path already starts with ../
// if (strpos($user['profile_image'], '../') === 0) {
// $profile_image = $user['profile_image'];
// } else if (strpos($user['profile_image'], '/') === 0) {
// // Absolute path from web root
// $profile_image = '.' . $user['profile_image'];
// } else {
// // Relative path - add ../
// $profile_image = '../' . $user['profile_image'];
// }
$profile_image = formatUrl($user['profile_image']);
}
// Fallback to default if image doesn't exist or is empty
if (!$profile_image) {
$profile_image = '../assets/img/default-avatar.png';
}
?>
<img src="<?php echo $profile_image; ?>"
class="rounded-circle"
width="40"
height="40"
alt="Profile Image"
style="object-fit: cover; border: 2px solid #eaeaea;">
</td>
<td><?php echo htmlspecialchars($user['username']); ?></td>
<td><?php echo htmlspecialchars($user['first_name'] . ' ' . $user['last_name']); ?></td>
<td><?php echo htmlspecialchars($user['email']); ?></td>
<td>
<?php
$badge_class = 'bg-secondary';
switch($user['role']) {
case 'admin':
$badge_class = 'bg-danger';
break;
case 'instructor':
$badge_class = 'bg-primary';
break;
case 'student':
$badge_class = 'bg-success';
break;
case 'director':
$badge_class = 'bg-info';
break;
case 'developer':
$badge_class = 'bg-warning text-dark';
break;
}
?>
<span class="badge <?php echo $badge_class; ?>"><?php echo ucfirst($user['role']); ?></span>
</td>
<td><?php echo date('M d, Y', strtotime($user['created_at'])); ?></td>
<td>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-primary edit-user-btn"
data-id="<?php echo $user['id']; ?>"
title="Edit">
<i class="fas fa-edit"></i>
</button>
<?php if ($user['id'] !== $_SESSION['user_id']): ?>
<button type="button" class="btn btn-danger delete-user-btn"
data-bs-toggle="modal"
data-bs-target="#deleteUserModal<?php echo $user['id']; ?>"
title="Delete">
<i class="fas fa-trash"></i>
</button>
<?php endif; ?>
</div>
<!-- Delete User Modal -->
<div class="modal fade" id="deleteUserModal<?php echo $user['id']; ?>" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Confirm Delete</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete the user <strong><?php echo htmlspecialchars($user['username']); ?></strong>?</p>
<p class="text-danger">This action cannot be undone and will delete all data associated with this user.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<form method="POST" action="delete_user.php">
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
<button type="submit" class="btn btn-danger">Delete User</button>
</form>
</div>
</div>
</div>
</div>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="7" class="text-center py-4">
<div class="d-flex flex-column align-items-center">
<i class="fas fa-users fa-3x text-muted mb-3"></i>
<h5>No users found</h5>
<p class="text-muted">Try adjusting your search or filter criteria</p>
<button type="button" class="btn btn-primary btn-sm mt-2" data-bs-toggle="modal" data-bs-target="#addUserModal">
<i class="fas fa-plus me-1"></i> Add New User
</button>
</div>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<div class="card-footer">
<!-- Pagination -->
<?php if ($total_pages > 1): ?>
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center mb-0">
<?php if ($page > 1): ?>
<li class="page-item">
<a class="page-link" href="?page=<?php echo $page - 1; ?>&search=<?php echo urlencode($search); ?>&role=<?php echo urlencode($role_filter); ?>">
<i class="fas fa-angle-left"></i>
</a>
</li>
<?php endif; ?>
<?php
// Determine range of page numbers to show
$range = 2; // Show 2 pages before and after current page
$start_page = max(1, $page - $range);
$end_page = min($total_pages, $page + $range);
// Always show first page
if ($start_page > 1) {
echo '<li class="page-item"><a class="page-link" href="?page=1&search=' . urlencode($search) . '&role=' . urlencode($role_filter) . '">1</a></li>';
if ($start_page > 2) {
echo '<li class="page-item disabled"><span class="page-link">...</span></li>';
}
}
// Show page numbers
for ($i = $start_page; $i <= $end_page; $i++) {
echo '<li class="page-item ' . ($i === $page ? 'active' : '') . '">
<a class="page-link" href="?page=' . $i . '&search=' . urlencode($search) . '&role=' . urlencode($role_filter) . '">' . $i . '</a>
</li>';
}
// Always show last page
if ($end_page < $total_pages) {
if ($end_page < $total_pages - 1) {
echo '<li class="page-item disabled"><span class="page-link">...</span></li>';
}
echo '<li class="page-item"><a class="page-link" href="?page=' . $total_pages . '&search=' . urlencode($search) . '&role=' . urlencode($role_filter) . '">' . $total_pages . '</a></li>';
}
?>
<?php if ($page < $total_pages): ?>
<li class="page-item">
<a class="page-link" href="?page=<?php echo $page + 1; ?>&search=<?php echo urlencode($search); ?>&role=<?php echo urlencode($role_filter); ?>">
<i class="fas fa-angle-right"></i>
</a>
</li>
<?php endif; ?>
</ul>
</nav>
<?php endif; ?>
</div>
</div>
<!-- Add User Modal -->
<div class="modal fade" id="addUserModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add New User</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST" action="add_user.php" enctype="multipart/form-data">
<div class="modal-body">
<div class="row g-3">
<div class="col-md-6">
<div class="mb-3">
<label for="username" class="form-label">Username <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="email" class="form-label">Email <span class="text-danger">*</span></label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="password" class="form-label">Password <span class="text-danger">*</span></label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="confirm_password" class="form-label">Confirm Password <span class="text-danger">*</span></label>
<input type="password" class="form-control" id="confirm_password" required>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="first_name" class="form-label">First Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="first_name" name="first_name" required>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="last_name" class="form-label">Last Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="last_name" name="last_name" required>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="phone" class="form-label">Phone Number</label>
<input type="tel" class="form-control" id="phone" name="phone">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="profile_image" class="form-label">Profile Image</label>
<input type="file" class="form-control" id="profile_image" name="profile_image" accept="image/*">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="role" class="form-label">Role <span class="text-danger">*</span></label>
<select class="form-select" id="role" name="role" required>
<option value="student">Student</option>
<option value="instructor">Instructor</option>
<option value="admin">Admin</option>
<option value="director">Director</option>
<option value="developer">Developer</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="status" class="form-label">Status <span class="text-danger">*</span></label>
<select class="form-select" id="status" name="status" required>
<option value="active">Active</option>
<option value="pending">Pending</option>
<option value="suspended">Suspended</option>
</select>
</div>
</div>
<div class="col-12">
<div class="mb-3">
<label for="bio" class="form-label">Biography</label>
<textarea class="form-control" id="bio" name="bio" rows="3"></textarea>
<small class="form-text text-muted">For instructors, this will be displayed on their profile page.</small>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Create User</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit User Modal - Single instance that loads data dynamically -->
<div class="modal fade" id="editUserModal" tabindex="-1" data-bs-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit User</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div id="editModalContent">
<div class="text-center p-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2">Loading user data...</p>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Highlight updated user if coming from an update
const urlParams = new URLSearchParams(window.location.search);
const updatedUserId = urlParams.get('updated');
if (updatedUserId) {
const userRow = document.getElementById('user' + updatedUserId);
if (userRow) {
// Apply highlight style
userRow.style.backgroundColor = 'rgba(25, 135, 84, 0.1)';
userRow.style.borderLeft = '4px solid #198754';
// Scroll to the row
setTimeout(() => {
userRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
}, 300);
// Remove highlight after delay
setTimeout(() => {
userRow.style.transition = 'background-color 1s ease, border-left 1s ease';
userRow.style.backgroundColor = '';
userRow.style.borderLeft = '';
}, 3000);
}
}
// Get references to the edit modal elements
const editUserModal = document.getElementById('editUserModal');
const editModalContent = document.getElementById('editModalContent');
const editButtons = document.querySelectorAll('.edit-user-btn');
// Initialize Bootstrap modal
const editModal = new bootstrap.Modal(editUserModal);
// Add click event listeners to all edit buttons
editButtons.forEach(button => {
button.addEventListener('click', function(e) {
const userId = this.getAttribute('data-id');
// Reset modal content to show loading spinner
editModalContent.innerHTML = `
<div class="text-center p-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-2">Loading user data...</p>
</div>`;
// Show the modal
editModal.show();
// Fetch user data
fetch('get_user_data.php?id=' + userId)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(userData => {
// Create form with user data
const formHTML = `
<form id="editUserForm" method="POST" action="update_user.php" enctype="multipart/form-data">
<div class="modal-body">
<input type="hidden" name="user_id" value="${userData.id}">
<div class="mb-3">
<label class="form-label">Username</label>
<input type="text" class="form-control" name="username" value="${userData.username}" required>
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" name="email" value="${userData.email}" required>
</div>
<div class="mb-3">
<label class="form-label">First Name</label>
<input type="text" class="form-control" name="first_name" value="${userData.first_name}" required>
</div>
<div class="mb-3">
<label class="form-label">Last Name</label>
<input type="text" class="form-control" name="last_name" value="${userData.last_name}" required>
</div>
<div class="mb-3">
<label class="form-label">Phone</label>
<input type="text" class="form-control" name="phone" value="${userData.phone || ''}">
</div>
<div class="mb-3">
<label class="form-label">Biography</label>
<textarea class="form-control" name="bio" rows="3">${userData.bio || ''}</textarea>
</div>
<div class="mb-3">
<label class="form-label">Profile Image</label>
<input type="file" class="form-control" name="profile_image" accept="image/*">
<small class="form-text text-muted">Leave empty to keep current image</small>
</div>
<div class="mb-3">
<label class="form-label">New Password</label>
<input type="password" class="form-control" name="password">
<small class="form-text text-muted">Leave empty to keep current password</small>
</div>
<div class="mb-3">
<label class="form-label">Role</label>
<select class="form-select" name="role" required>
<option value="admin" ${userData.role === 'admin' ? 'selected' : ''}>Admin</option>
<option value="instructor" ${userData.role === 'instructor' ? 'selected' : ''}>Instructor</option>
<option value="student" ${userData.role === 'student' ? 'selected' : ''}>Student</option>
<option value="director" ${userData.role === 'director' ? 'selected' : ''}>Director</option>
<option value="developer" ${userData.role === 'developer' ? 'selected' : ''}>Developer</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Status</label>
<select class="form-select" name="status" required>
<option value="active" ${(userData.status || 'active') === 'active' ? 'selected' : ''}>Active</option>
<option value="pending" ${(userData.status || '') === 'pending' ? 'selected' : ''}>Pending</option>
<option value="suspended" ${(userData.status || '') === 'suspended' ? 'selected' : ''}>Suspended</option>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary edit-user-submit">Save Changes</button>
</div>
</form>`;
// Update modal content
editModalContent.innerHTML = formHTML;
// Add submit event handler to show loading state
document.getElementById('editUserForm').addEventListener('submit', function() {
const submitBtn = this.querySelector('.edit-user-submit');
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Saving...';
submitBtn.disabled = true;
});
})
.catch(error => {
console.error('Error fetching user data:', error);
editModalContent.innerHTML = `
<div class="modal-body">
<div class="alert alert-danger" role="alert">
Failed to load user data. Please try again.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>`;
});
});
});
// Password confirmation validation for add user modal
const addUserForm = document.querySelector('#addUserModal form');
const password = document.querySelector('#addUserModal #password');
const confirmPassword = document.querySelector('#addUserModal #confirm_password');
if (addUserForm) {
addUserForm.addEventListener('submit', function(event) {
if (password.value !== confirmPassword.value) {
event.preventDefault();
alert('Passwords do not match!');
confirmPassword.focus();
}
});
}
// Auto-hide alerts after 5 seconds
const alerts = document.querySelectorAll('.alert');
alerts.forEach(alert => {
setTimeout(() => {
const bsAlert = new bootstrap.Alert(alert);
bsAlert.close();
}, 5000);
});
// Role-based form fields in Add User Modal
const roleSelect = document.querySelector('#role');
const bioField = document.querySelector('#bio');
const bioLabel = document.querySelector('label[for="bio"]');
if (roleSelect && bioField) {
roleSelect.addEventListener('change', function() {
if (this.value === 'instructor') {
bioLabel.innerHTML = 'Biography <span class="text-danger">*</span>';
bioField.setAttribute('required', 'required');
} else {
bioLabel.innerHTML = 'Biography';
bioField.removeAttribute('required');
}
});
}
});
</script>
<?php
// Include footer
include_once 'includes/footer.php';
?>