451 lines
25 KiB
HTML
451 lines
25 KiB
HTML
{% extends 'base.html' %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% trans "Admin Dashboard" %} - MASAR CARGO{% endblock %}
|
|
|
|
{% block breadcrumbs %}
|
|
<div class="breadcrumb-container">
|
|
<div class="container">
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb mb-0">
|
|
<li class="breadcrumb-item"><a href="/"><i class="fa-solid fa-house me-1"></i> {% trans "Home" %}</a></li>
|
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Admin Dashboard" %}</li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container py-5">
|
|
<div class="row mb-4 align-items-center">
|
|
<div class="col">
|
|
<h2 class="fw-bold">{% trans "Administrator Dashboard" %}</h2>
|
|
<p class="text-muted">{% trans "System overview and management" %}</p>
|
|
</div>
|
|
<div class="col-auto d-flex gap-2">
|
|
<a href="/admin/core/profile/" class="btn btn-primary">
|
|
<i class="fa-solid fa-users-gear me-2"></i>{% trans "Manage Subscriptions" %}
|
|
</a>
|
|
<a href="/admin/" class="btn btn-outline-primary">
|
|
<i class="fa-solid fa-gears me-2"></i>{% trans "Go to Django Admin" %}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats Overview -->
|
|
<div class="row g-4 mb-5">
|
|
<div class="col-md-4 col-lg-2">
|
|
<div class="card border-0 shadow-sm text-center p-3 h-100">
|
|
<div class="h3 text-primary mb-1"><i class="fa-solid fa-users"></i></div>
|
|
<h4 class="fw-bold mb-0">{{ total_users }}</h4>
|
|
<p class="small text-muted mb-0">{% trans "Total Users" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 col-lg-2">
|
|
<div class="card border-0 shadow-sm text-center p-3 h-100">
|
|
<div class="h3 text-success mb-1"><i class="fa-solid fa-truck"></i></div>
|
|
<h4 class="fw-bold mb-0">{{ total_trucks }}</h4>
|
|
<p class="small text-muted mb-0">{% trans "Trucks" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 col-lg-2">
|
|
<div class="card border-0 shadow-sm text-center p-3 h-100">
|
|
<div class="h3 text-warning mb-1"><i class="fa-solid fa-box"></i></div>
|
|
<h4 class="fw-bold mb-0">{{ total_shipments }}</h4>
|
|
<p class="small text-muted mb-0">{% trans "Shipments" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 col-lg-2">
|
|
<div class="card border-0 shadow-sm text-center p-3 h-100">
|
|
<div class="h3 text-info mb-1"><i class="fa-solid fa-hand-holding-dollar"></i></div>
|
|
<h4 class="fw-bold mb-0">{{ total_bids }}</h4>
|
|
<p class="small text-muted mb-0">{% trans "Bids" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 col-lg-2">
|
|
<div class="card border-0 shadow-sm text-center p-3 h-100 bg-success bg-opacity-10">
|
|
<div class="h3 text-success mb-1"><i class="fa-solid fa-check-circle"></i></div>
|
|
<h4 class="fw-bold mb-0">{{ active_subscriptions }}</h4>
|
|
<p class="small text-muted mb-0">{% trans "Active Subs" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 col-lg-2">
|
|
<div class="card border-0 shadow-sm text-center p-3 h-100 bg-danger bg-opacity-10">
|
|
<div class="h3 text-danger mb-1"><i class="fa-solid fa-times-circle"></i></div>
|
|
<h4 class="fw-bold mb-0">{{ expired_subscriptions }}</h4>
|
|
<p class="small text-muted mb-0">{% trans "Expired Subs" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pending Truck Approvals Section -->
|
|
<div class="card border-0 shadow-sm mb-5">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="fw-bold mb-0">{% trans "Pending Truck Approvals" %}</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th>{% trans "Owner" %}</th>
|
|
<th>{% trans "Truck Details" %}</th>
|
|
<th>{% trans "Plate No" %}</th>
|
|
<th class="text-end">{% trans "Actions" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for truck in pending_trucks %}
|
|
<tr>
|
|
<td>{{ truck.owner.username }}<br><small class="text-muted">{{ truck.owner.email }}</small></td>
|
|
<td>
|
|
<strong>{{ truck.display_truck_type }}</strong><br>
|
|
<small>{{ truck.display_model }} ({{ truck.year }}) - {{ truck.display_color }}</small>
|
|
</td>
|
|
<td>{{ truck.plate_no }}</td>
|
|
<td class="text-end">
|
|
<button type="button" class="btn btn-outline-info btn-sm me-2 view-truck-btn"
|
|
data-bs-toggle="modal" data-bs-target="#truckDetailsModal"
|
|
data-truck-type="{{ truck.display_truck_type }}"
|
|
data-truck-model="{{ truck.display_model }}"
|
|
data-truck-year="{{ truck.year }}"
|
|
data-truck-plate="{{ truck.plate_no }}"
|
|
data-truck-capacity="{{ truck.display_load_capacity }}"
|
|
data-truck-color="{{ truck.display_color }}"
|
|
data-truck-owner="{{ truck.owner.username }}"
|
|
data-truck-expiry="{{ truck.registration_expiry_date }}"
|
|
data-truck-picture="{% if truck.truck_picture %}{{ truck.truck_picture.url }}{% endif %}"
|
|
data-reg-front="{% if truck.registration_front %}{{ truck.registration_front.url }}{% endif %}"
|
|
data-reg-back="{% if truck.registration_back %}{{ truck.registration_back.url }}{% endif %}"
|
|
data-license-front="{% if truck.driver_license_front %}{{ truck.driver_license_front.url }}{% endif %}"
|
|
data-license-back="{% if truck.driver_license_back %}{{ truck.driver_license_back.url }}{% endif %}">
|
|
<i class="fa-solid fa-eye me-1"></i> {% trans "View" %}
|
|
</button>
|
|
<a href="{% url 'approve_truck' truck.id %}" class="btn btn-success btn-sm">
|
|
<i class="fa-solid fa-check me-1"></i> {% trans "Approve" %}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="4" class="text-center py-4 text-muted">{% trans "No trucks awaiting approval." %}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Approved Trucks Management -->
|
|
<div class="card border-0 shadow-sm mb-5">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="fw-bold mb-0">{% trans "Manage Approved Trucks" %}</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th>{% trans "Owner" %}</th>
|
|
<th>{% trans "Truck Details" %}</th>
|
|
<th>{% trans "Plate No" %}</th>
|
|
<th class="text-end">{% trans "Actions" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for truck in approved_trucks %}
|
|
<tr>
|
|
<td>{{ truck.owner.username }}</td>
|
|
<td>
|
|
<strong>{{ truck.display_truck_type }}</strong><br>
|
|
<small>{{ truck.display_model }} ({{ truck.year }})</small>
|
|
</td>
|
|
<td>{{ truck.plate_no }}</td>
|
|
<td class="text-end">
|
|
<button type="button" class="btn btn-outline-info btn-sm me-2 view-truck-btn"
|
|
data-bs-toggle="modal" data-bs-target="#truckDetailsModal"
|
|
data-truck-type="{{ truck.display_truck_type }}"
|
|
data-truck-model="{{ truck.display_model }}"
|
|
data-truck-year="{{ truck.year }}"
|
|
data-truck-plate="{{ truck.plate_no }}"
|
|
data-truck-capacity="{{ truck.display_load_capacity }}"
|
|
data-truck-color="{{ truck.display_color }}"
|
|
data-truck-owner="{{ truck.owner.username }}"
|
|
data-truck-expiry="{{ truck.registration_expiry_date }}"
|
|
data-truck-picture="{% if truck.truck_picture %}{{ truck.truck_picture.url }}{% endif %}"
|
|
data-reg-front="{% if truck.registration_front %}{{ truck.registration_front.url }}{% endif %}"
|
|
data-reg-back="{% if truck.registration_back %}{{ truck.registration_back.url }}{% endif %}"
|
|
data-license-front="{% if truck.driver_license_front %}{{ truck.driver_license_front.url }}{% endif %}"
|
|
data-license-back="{% if truck.driver_license_back %}{{ truck.driver_license_back.url }}{% endif %}">
|
|
<i class="fa-solid fa-eye me-1"></i> {% trans "View" %}
|
|
</button>
|
|
<a href="{% url 'suspend_truck' truck.id %}" class="btn btn-outline-danger btn-sm">
|
|
<i class="fa-solid fa-ban me-1"></i> {% trans "Suspend" %}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="4" class="text-center py-4 text-muted">{% trans "No approved trucks yet." %}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Truck Details Modal -->
|
|
<div class="modal fade" id="truckDetailsModal" tabindex="-1" aria-labelledby="truckDetailsModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-xl">
|
|
<div class="modal-content border-0 shadow">
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title fw-bold" id="truckDetailsModalLabel">{% trans "Truck Details" %}</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="row g-4">
|
|
<div class="col-md-6">
|
|
<h6 class="fw-bold text-primary mb-3">{% trans "General Information" %}</h6>
|
|
<table class="table table-sm table-borderless">
|
|
<tr>
|
|
<td class="text-muted" style="width: 40%;">{% trans "Type" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-type"></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">{% trans "Model" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-model"></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">{% trans "Year" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-year"></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">{% trans "Plate No" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-plate"></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">{% trans "Capacity" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-capacity"></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">{% trans "Color" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-color"></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">{% trans "Expiry Date" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-expiry"></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">{% trans "Owner" %}:</td>
|
|
<td class="fw-bold" id="modal-truck-owner"></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6 class="fw-bold text-primary mb-3">{% trans "Truck Image" %}</h6>
|
|
<div class="text-center bg-light rounded p-2 mb-3">
|
|
<img id="modal-truck-img" src="" alt="Truck" class="img-fluid rounded shadow-sm" style="max-height: 200px; display: none;">
|
|
<p id="no-truck-img" class="text-muted py-5 mb-0" style="display: none;">{% trans "No image provided" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr class="my-4">
|
|
<h6 class="fw-bold text-primary mb-3">{% trans "Documents & Registration" %}</h6>
|
|
<div class="row g-3">
|
|
<div class="col-md-3">
|
|
<p class="small text-muted mb-1">{% trans "Registration (Front Face)" %}</p>
|
|
<div class="bg-light rounded text-center p-2">
|
|
<a id="modal-reg-front-link" href="#" target="_blank">
|
|
<img id="modal-reg-front-img" src="" alt="Reg Front" class="img-fluid rounded" style="max-height: 120px; display: none;">
|
|
</a>
|
|
<p id="no-reg-front" class="text-muted py-3 mb-0" style="display: none;">{% trans "Not available" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<p class="small text-muted mb-1">{% trans "Registration (Back Face)" %}</p>
|
|
<div class="bg-light rounded text-center p-2">
|
|
<a id="modal-reg-back-link" href="#" target="_blank">
|
|
<img id="modal-reg-back-img" src="" alt="Reg Back" class="img-fluid rounded" style="max-height: 120px; display: none;">
|
|
</a>
|
|
<p id="no-reg-back" class="text-muted py-3 mb-0" style="display: none;">{% trans "Not available" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<p class="small text-muted mb-1">{% trans "Driver License (Front Face)" %}</p>
|
|
<div class="bg-light rounded text-center p-2">
|
|
<a id="modal-license-front-link" href="#" target="_blank">
|
|
<img id="modal-license-front-img" src="" alt="License Front" class="img-fluid rounded" style="max-height: 120px; display: none;">
|
|
</a>
|
|
<p id="no-license-front" class="text-muted py-3 mb-0" style="display: none;">{% trans "Not available" %}</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<p class="small text-muted mb-1">{% trans "Driver License (Back Face)" %}</p>
|
|
<div class="bg-light rounded text-center p-2">
|
|
<a id="modal-license-back-link" href="#" target="_blank">
|
|
<img id="modal-license-back-img" src="" alt="License Back" class="img-fluid rounded" style="max-height: 120px; display: none;">
|
|
</a>
|
|
<p id="no-license-back" class="text-muted py-3 mb-0" style="display: none;">{% trans "Not available" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-5">
|
|
<h4 class="fw-bold mb-4">{% trans "Quick Actions" %}</h4>
|
|
<div class="row g-3">
|
|
<div class="col-md-4">
|
|
<a href="{% url 'admin_financials' %}" class="card border-0 shadow-sm p-3 text-decoration-none text-dark h-100 hover-card">
|
|
<div class="d-flex align-items-center">
|
|
<div class="rounded-circle bg-light p-3 me-3 text-info">
|
|
<i class="fa-solid fa-money-bill-trend-up"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="mb-0 fw-bold">{% trans "Financial Overview" %}</h6>
|
|
<small class="text-muted">{% trans "Track payments and platform revenue" %}</small>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<a href="/" class="card border-0 shadow-sm p-3 text-decoration-none text-dark h-100 hover-card">
|
|
<div class="d-flex align-items-center">
|
|
<div class="rounded-circle bg-light p-3 me-3 text-primary">
|
|
<i class="fa-solid fa-house"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="mb-0 fw-bold">{% trans "View Landing Page" %}</h6>
|
|
<small class="text-muted">{% trans "See how the site looks to visitors" %}</small>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<a href="{% url 'admin_financials' %}" class="card border-0 shadow-sm p-3 text-decoration-none text-dark h-100 hover-card">
|
|
<div class="d-flex align-items-center">
|
|
<div class="rounded-circle bg-light p-3 me-3 text-info">
|
|
<i class="fa-solid fa-money-bill-trend-up"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="mb-0 fw-bold">{% trans "Financial Overview" %}</h6>
|
|
<small class="text-muted">{% trans "Track payments and platform revenue" %}</small>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<a href="/admin/core/shipment/" class="card border-0 shadow-sm p-3 text-decoration-none text-dark h-100 hover-card">
|
|
<div class="d-flex align-items-center">
|
|
<div class="rounded-circle bg-light p-3 me-3 text-warning">
|
|
<i class="fa-solid fa-clipboard-list"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="mb-0 fw-bold">{% trans "Manage Shipments" %}</h6>
|
|
<small class="text-muted">{% trans "Approve or moderate shipments" %}</small>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<a href="{% url 'admin_financials' %}" class="card border-0 shadow-sm p-3 text-decoration-none text-dark h-100 hover-card">
|
|
<div class="d-flex align-items-center">
|
|
<div class="rounded-circle bg-light p-3 me-3 text-info">
|
|
<i class="fa-solid fa-money-bill-trend-up"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="mb-0 fw-bold">{% trans "Financial Overview" %}</h6>
|
|
<small class="text-muted">{% trans "Track payments and platform revenue" %}</small>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<a href="/admin/auth/user/" class="card border-0 shadow-sm p-3 text-decoration-none text-dark h-100 hover-card">
|
|
<div class="d-flex align-items-center">
|
|
<div class="rounded-circle bg-light p-3 me-3 text-success">
|
|
<i class="fa-solid fa-user-gear"></i>
|
|
</div>
|
|
<div>
|
|
<h6 class="mb-0 fw-bold">{% trans "Manage Users" %}</h6>
|
|
<small class="text-muted">{% trans "Review registered profiles" %}</small>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const viewBtns = document.querySelectorAll('.view-truck-btn');
|
|
viewBtns.forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const data = this.dataset;
|
|
|
|
// Populate text fields
|
|
document.getElementById('modal-truck-type').textContent = data.truckType;
|
|
document.getElementById('modal-truck-model').textContent = data.truckModel;
|
|
document.getElementById('modal-truck-year').textContent = data.truckYear;
|
|
document.getElementById('modal-truck-plate').textContent = data.truckPlate;
|
|
document.getElementById('modal-truck-capacity').textContent = data.truckCapacity;
|
|
document.getElementById('modal-truck-color').textContent = data.truckColor;
|
|
document.getElementById('modal-truck-owner').textContent = data.truckOwner;
|
|
document.getElementById('modal-truck-expiry').textContent = data.truckExpiry || '{% trans "N/A" %}';
|
|
|
|
// Populate images
|
|
const imgFields = [
|
|
{ id: 'modal-truck-img', noId: 'no-truck-img', src: data.truckPicture },
|
|
{ id: 'modal-reg-front-img', noId: 'no-reg-front', src: data.regFront, linkId: 'modal-reg-front-link' },
|
|
{ id: 'modal-reg-back-img', noId: 'no-reg-back', src: data.regBack, linkId: 'modal-reg-back-link' },
|
|
{ id: 'modal-license-front-img', noId: 'no-license-front', src: data.licenseFront, linkId: 'modal-license-front-link' },
|
|
{ id: 'modal-license-back-img', noId: 'no-license-back', src: data.licenseBack, linkId: 'modal-license-back-link' }
|
|
];
|
|
|
|
imgFields.forEach(field => {
|
|
const img = document.getElementById(field.id);
|
|
const noTxt = document.getElementById(field.noId);
|
|
|
|
if (field.src && field.src !== '') {
|
|
img.src = field.src;
|
|
img.style.display = 'inline-block';
|
|
noTxt.style.display = 'none';
|
|
if (field.linkId) {
|
|
document.getElementById(field.linkId).href = field.src;
|
|
}
|
|
} else {
|
|
img.style.display = 'none';
|
|
noTxt.style.display = 'block';
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.hover-card:hover {
|
|
background-color: #f1f8ff !important;
|
|
transform: translateY(-5px);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.modal-content {
|
|
border-radius: 1rem;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.modal-header {
|
|
border-bottom: none;
|
|
}
|
|
</style>
|
|
{% endblock %} |