Marwan Alwali a710d1c4d8 update
2025-09-11 19:01:55 +03:00

404 lines
18 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Account Dashboard{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item active">Account Management</li>
</ol>
<h1 class="page-header mb-0">Account Dashboard</h1>
</div>
<div class="ms-auto">
<a href="{% url 'accounts:user_form' %}" class="btn btn-primary">
<i class="fas fa-user-plus me-2"></i>Add User
</a>
</div>
</div>
<!-- Statistics Cards -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6">
<div class="card bg-primary text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<div class="fs-6 text-white-75">Total Users</div>
<div class="fs-2 fw-bold">{{ total_users|default:0 }}</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-users fa-2x text-white-50"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-success text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<div class="fs-6 text-white-75">Active Users</div>
<div class="fs-2 fw-bold">{{ active_users|default:0 }}</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-user-check fa-2x text-white-50"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-warning text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<div class="fs-6 text-white-75">Active Sessions</div>
<div class="fs-2 fw-bold">{{ active_sessions|default:0 }}</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-desktop fa-2x text-white-50"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-info text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<div class="fs-6 text-white-75">New This Month</div>
<div class="fs-2 fw-bold">{{ new_users_month|default:0 }}</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-user-plus fa-2x text-white-50"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Quick Actions -->
<div class="col-xl-4 col-lg-6">
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-bolt me-2"></i>
Quick Actions
</h4>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{% url 'accounts:user_form' %}" class="btn btn-outline-primary">
<i class="fas fa-user-plus me-2"></i>Create New User
</a>
<a href="{% url 'accounts:user_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-users me-2"></i>Manage Users
</a>
<a href="{% url 'accounts:session_list' %}" class="btn btn-outline-info">
<i class="fas fa-desktop me-2"></i>View Sessions
</a>
<a href="{% url 'accounts:session_management' %}" class="btn btn-outline-warning">
<i class="fas fa-cogs me-2"></i>Session Management
</a>
</div>
</div>
</div>
<!-- User Statistics -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-chart-pie me-2"></i>
User Statistics
</h4>
</div>
<div class="card-body">
<div class="mb-3">
<div class="d-flex justify-content-between mb-1">
<span>Active Users</span>
<span>{{ active_percentage|default:0 }}%</span>
</div>
<div class="progress">
<div class="progress-bar bg-success" style="width: {{ active_percentage|default:0 }}%"></div>
</div>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between mb-1">
<span>Staff Members</span>
<span>{{ staff_percentage|default:0 }}%</span>
</div>
<div class="progress">
<div class="progress-bar bg-primary" style="width: {{ staff_percentage|default:0 }}%"></div>
</div>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between mb-1">
<span>Administrators</span>
<span>{{ admin_percentage|default:0 }}%</span>
</div>
<div class="progress">
<div class="progress-bar bg-warning" style="width: {{ admin_percentage|default:0 }}%"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Users -->
<div class="col-xl-4 col-lg-6">
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-user-clock me-2"></i>
Recent Users
</h4>
<div class="card-toolbar">
<a href="{% url 'accounts:user_list' %}" class="btn btn-sm btn-outline-primary">
View All
</a>
</div>
</div>
<div class="card-body">
{% if recent_users %}
{% for user in recent_users %}
<div class="d-flex align-items-center mb-3">
<div class="flex-shrink-0">
<div class="avatar avatar-sm">
{% if user.profile.avatar %}
<img src="{{ user.profile.avatar.url }}" alt="{{ user.get_full_name }}" class="rounded-circle">
{% else %}
<div class="avatar-initial rounded-circle bg-primary">
{{ user.first_name|first|upper }}{{ user.last_name|first|upper }}
</div>
{% endif %}
</div>
</div>
<div class="flex-grow-1 ms-3">
<div class="fw-bold">{{ user.get_full_name|default:user.username }}</div>
<div class="small text-muted">{{ user.email }}</div>
<div class="small text-muted">
Joined {{ user.date_joined|timesince }} ago
</div>
</div>
<div class="flex-shrink-0">
{% if user.is_active %}
<span class="badge bg-success">Active</span>
{% else %}
<span class="badge bg-secondary">Inactive</span>
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<div class="text-center text-muted py-4">
<i class="fas fa-users fa-3x mb-3"></i>
<div>No recent users</div>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Active Sessions -->
<div class="col-xl-4">
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-desktop me-2"></i>
Active Sessions
</h4>
<div class="card-toolbar">
<a href="{% url 'accounts:session_list' %}" class="btn btn-sm btn-outline-primary">
View All
</a>
</div>
</div>
<div class="card-body">
{% if active_sessions_list %}
{% for session in active_sessions_list %}
<div class="d-flex align-items-center mb-3">
<div class="flex-shrink-0">
<i class="fas fa-{{ session.device_icon|default:'desktop' }} fa-lg text-primary"></i>
</div>
<div class="flex-grow-1 ms-3">
<div class="fw-bold">{{ session.user.get_full_name|default:session.user.username }}</div>
<div class="small text-muted">{{ session.ip_address }}</div>
<div class="small text-muted">
Active for {{ session.last_activity|timesince }}
</div>
</div>
<div class="flex-shrink-0">
<span class="badge bg-success">Online</span>
</div>
</div>
{% endfor %}
{% else %}
<div class="text-center text-muted py-4">
<i class="fas fa-desktop fa-3x mb-3"></i>
<div>No active sessions</div>
</div>
{% endif %}
</div>
</div>
<!-- System Status -->
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-server me-2"></i>
System Status
</h4>
</div>
<div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-3">
<span>Authentication Service</span>
<span class="badge bg-success">
<i class="fas fa-check me-1"></i>Online
</span>
</div>
<div class="d-flex justify-content-between align-items-center mb-3">
<span>Session Management</span>
<span class="badge bg-success">
<i class="fas fa-check me-1"></i>Online
</span>
</div>
<div class="d-flex justify-content-between align-items-center mb-3">
<span>User Directory</span>
<span class="badge bg-success">
<i class="fas fa-check me-1"></i>Online
</span>
</div>
<div class="d-flex justify-content-between align-items-center">
<span>Security Monitoring</span>
<span class="badge bg-success">
<i class="fas fa-check me-1"></i>Active
</span>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-history me-2"></i>
Recent Activity
</h4>
<div class="card-toolbar">
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-secondary active" onclick="filterActivity('all')">All</button>
<button type="button" class="btn btn-outline-secondary" onclick="filterActivity('login')">Logins</button>
<button type="button" class="btn btn-outline-secondary" onclick="filterActivity('user')">User Changes</button>
<button type="button" class="btn btn-outline-secondary" onclick="filterActivity('security')">Security</button>
</div>
</div>
</div>
<div class="card-body">
{% if recent_activity %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Time</th>
<th>User</th>
<th>Action</th>
<th>Details</th>
<th>IP Address</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for activity in recent_activity %}
<tr data-activity-type="{{ activity.type }}">
<td>
<div class="small">{{ activity.timestamp|date:"M d, Y" }}</div>
<div class="small text-muted">{{ activity.timestamp|time:"H:i" }}</div>
</td>
<td>
<div class="d-flex align-items-center">
<div class="avatar avatar-xs me-2">
{% if activity.user.profile.avatar %}
<img src="{{ activity.user.profile.avatar.url }}" alt="{{ activity.user.get_full_name }}" class="rounded-circle">
{% else %}
<div class="avatar-initial rounded-circle bg-secondary">
{{ activity.user.first_name|first|upper }}
</div>
{% endif %}
</div>
<div>
<div class="fw-bold">{{ activity.user.get_full_name|default:activity.user.username }}</div>
<div class="small text-muted">{{ activity.user.email }}</div>
</div>
</div>
</td>
<td>
<i class="fas fa-{{ activity.icon }} me-2 text-{{ activity.color }}"></i>
{{ activity.action }}
</td>
<td>{{ activity.details|default:"-" }}</td>
<td>
<code>{{ activity.ip_address|default:"-" }}</code>
</td>
<td>
<span class="badge bg-{{ activity.status_color }}">
{{ activity.status }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center text-muted py-5">
<i class="fas fa-history fa-3x mb-3"></i>
<h5>No Recent Activity</h5>
<p>User activity will appear here once users start interacting with the system.</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Auto-refresh data every 30 seconds
setInterval(function() {
// In a real implementation, you would fetch updated data via AJAX
console.log('Refreshing dashboard data...');
}, 30000);
});
function filterActivity(type) {
const rows = document.querySelectorAll('[data-activity-type]');
const buttons = document.querySelectorAll('.btn-group .btn');
// Update button states
buttons.forEach(btn => btn.classList.remove('active'));
event.target.classList.add('active');
// Filter rows
rows.forEach(row => {
if (type === 'all' || row.dataset.activityType === type) {
row.style.display = '';
} else {
row.style.display = 'none';
}
});
}
</script>
{% endblock %}