146 lines
6.0 KiB
HTML
146 lines
6.0 KiB
HTML
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>User</th>
|
|
<th>Role</th>
|
|
<th>Department</th>
|
|
<th>Contact</th>
|
|
<th>Status</th>
|
|
<th>Last Login</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for user in users %}
|
|
<tr>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
{% if user.profile_picture %}
|
|
<img src="{{ user.profile_picture.url }}"
|
|
alt="{{ user.get_display_name }}"
|
|
class="rounded-circle me-2"
|
|
width="32" height="32">
|
|
{% else %}
|
|
<div class="bg-primary text-white rounded-circle d-flex align-items-center justify-content-center me-2"
|
|
style="width: 32px; height: 32px; font-size: 14px;">
|
|
{{ user.first_name|first|default:user.username|first|upper }}{{ user.last_name|first|upper }}
|
|
</div>
|
|
{% endif %}
|
|
<div>
|
|
<div class="fw-bold">{{ user.get_display_name }}</div>
|
|
<small class="text-muted">{{ user.username }}</small>
|
|
{% if user.employee_id %}
|
|
<br><small class="text-muted">ID: {{ user.employee_id }}</small>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-secondary">{{ user.role|title }}</span>
|
|
</td>
|
|
<td>
|
|
{% if user.department %}
|
|
{{ user.department }}
|
|
{% if user.job_title %}
|
|
<br><small class="text-muted">{{ user.job_title }}</small>
|
|
{% endif %}
|
|
{% else %}
|
|
<span class="text-muted">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<i class="fas fa-envelope"></i> {{ user.email }}
|
|
</div>
|
|
{% if user.phone_number %}
|
|
<div>
|
|
<i class="fas fa-phone"></i> {{ user.phone_number }}
|
|
</div>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div>
|
|
{% if user.is_active %}
|
|
<span class="badge bg-success">Active</span>
|
|
{% else %}
|
|
<span class="badge bg-danger">Inactive</span>
|
|
{% endif %}
|
|
</div>
|
|
{% if not user.is_approved %}
|
|
<div class="mt-1">
|
|
<span class="badge bg-warning">Pending Approval</span>
|
|
</div>
|
|
{% endif %}
|
|
{% if user.is_account_locked %}
|
|
<div class="mt-1">
|
|
<span class="badge bg-danger">Locked</span>
|
|
</div>
|
|
{% endif %}
|
|
{% if user.two_factor_enabled %}
|
|
<div class="mt-1">
|
|
<span class="badge bg-info">2FA</span>
|
|
</div>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if user.last_login %}
|
|
{{ user.last_login|timesince }} ago
|
|
{% else %}
|
|
<span class="text-muted">Never</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="btn-group btn-group-sm" role="group">
|
|
<a href="{% url 'accounts:user_detail' user.pk %}"
|
|
class="btn btn-outline-primary"
|
|
title="View Details">
|
|
<i class="fas fa-eye"></i>
|
|
</a>
|
|
<button type="button"
|
|
class="btn btn-outline-secondary"
|
|
title="Edit User">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
<button type="button"
|
|
class="btn btn-outline-info"
|
|
title="View Sessions"
|
|
hx-get="{% url 'accounts:session_list' %}?user_id={{ user.id }}"
|
|
hx-target="#session-modal-body"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#sessionModal">
|
|
<i class="fas fa-desktop"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="7" class="text-center text-muted py-4">
|
|
<i class="fas fa-users fa-2x mb-2"></i>
|
|
<br>No users found.
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Session Modal -->
|
|
<div class="modal fade" id="sessionModal" tabindex="-1" aria-labelledby="sessionModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="sessionModalLabel">
|
|
<i class="fas fa-desktop"></i> User Sessions
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body" id="session-modal-body">
|
|
<!-- Session content will be loaded here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|