37794-vm/core/templates/core/driver_dashboard.html

350 lines
20 KiB
HTML

{% extends 'base.html' %}
{% load i18n %}
{% block content %}
<div class="container py-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="mb-0">{% trans "Driver Dashboard" %}</h1>
<a href="{% url 'scan_qr' %}" class="btn btn-primary rounded-pill px-4">
<i class="bi bi-qr-code-scan me-2"></i> {% trans "Scan Parcel" %}
</a>
</div>
{% if not is_approved %}
<div class="alert alert-warning shadow-sm border-0 d-flex align-items-center mb-4" role="alert" style="border-radius: 12px;">
<i class="bi bi-hourglass-split fs-3 me-3 text-warning"></i>
<div>
<h5 class="alert-heading mb-1">{% trans "Account Pending Approval" %}</h5>
<p class="mb-0 text-muted">{% trans "Your driver account is currently under review by our administrators. You will be notified once your documents are verified and your account is approved to accept shipments." %}</p>
</div>
</div>
{% endif %}
<ul class="nav nav-pills mb-4" id="pills-tab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="pills-available-tab" data-bs-toggle="pill" data-bs-target="#pills-available" type="button" role="tab">{% trans "Available Shipments" %}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-my-tab" data-bs-toggle="pill" data-bs-target="#pills-my" type="button" role="tab">{% trans "Active Deliveries" %}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-history-tab" data-bs-toggle="pill" data-bs-target="#pills-history" type="button" role="tab">{% trans "Transaction History" %}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-cancelled-tab" data-bs-toggle="pill" data-bs-target="#pills-cancelled" type="button" role="tab">{% trans "Cancelled Shipments" %}</button>
</li>
</ul>
<div class="tab-content" id="pills-tabContent">
<!-- Available Shipments -->
<div class="tab-pane fade show active" id="pills-available" role="tabpanel">
{% if is_approved %}
<!-- Toolbar -->
<div class="d-flex justify-content-between align-items-center mb-4">
<h5 class="mb-0 text-muted">{% trans "Browse Shipments" %}</h5>
<div class="btn-group" role="group" aria-label="View toggle">
<button type="button" class="btn btn-outline-primary active" id="btn-grid-view">
<i class="bi bi-grid"></i> {% trans "Grid" %}
</button>
<button type="button" class="btn btn-outline-primary" id="btn-list-view">
<i class="bi bi-list"></i> {% trans "List" %}
</button>
</div>
</div>
{% if available_parcels %}
<!-- Grid View -->
<div id="view-grid" class="row g-4">
{% for parcel in available_parcels %}
<div class="col-md-6 col-lg-4">
<div class="card border-0 shadow-sm h-100" style="border-radius: 15px;">
<div class="card-body">
<h5 class="card-title">{{ parcel.description|truncatechars:30 }}</h5>
<p class="card-text mb-1 small"><strong>{% trans "Pickup" %}:</strong> {{ parcel.pickup_governate.name }} / {{ parcel.pickup_city.name }}</p>
<p class="card-text mb-3 small"><strong>{% trans "Delivery" %}:</strong> {{ parcel.delivery_governate.name }} / {{ parcel.delivery_city.name }}</p>
<div class="d-flex justify-content-between align-items-center mb-2">
<span class="text-muted small"><strong>{% trans "Distance" %}:</strong> {{ parcel.distance_km }} km</span>
<span class="text-muted small"><strong>{% trans "Weight" %}:</strong> {{ parcel.weight }} kg</span>
</div>
<!-- Bid/Price Highlight -->
<div class="bg-light p-2 rounded text-center mb-3 border border-primary border-opacity-25">
<small class="text-uppercase text-muted fw-bold" style="font-size: 0.7rem;">{% trans "Shipper's Offer (Bid)" %}</small>
<div class="text-primary fw-bold fs-4">{{ parcel.price }} <span class="fs-6">OMR</span></div>
</div>
<form action="{% url 'accept_parcel' parcel.id %}" method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-masarx-primary w-100">{% trans "Accept Shipment" %}</button>
</form>
</div>
</div>
</div>
{% endfor %}
</div>
<!-- List View (Initially Hidden) -->
<div id="view-list" class="d-none">
<div class="d-flex flex-column gap-3">
{% for parcel in available_parcels %}
<div class="card border-0 shadow-sm rounded-3">
<div class="card-body p-3">
<div class="row align-items-center">
<div class="col-md-8 mb-3 mb-md-0">
<h5 class="card-title mb-2">{{ parcel.description|truncatechars:80 }}</h5>
<div class="d-flex flex-wrap gap-3 text-muted small">
<span class="d-flex align-items-center gap-1">
<i class="bi bi-geo-alt-fill text-primary"></i>
<strong>{% trans "From" %}:</strong> {{ parcel.pickup_governate.name }} / {{ parcel.pickup_city.name }}
</span>
<span class="d-flex align-items-center gap-1">
<i class="bi bi-geo-alt-fill text-danger"></i>
<strong>{% trans "To" %}:</strong> {{ parcel.delivery_governate.name }} / {{ parcel.delivery_city.name }}
</span>
<span class="d-flex align-items-center gap-1">
<i class="bi bi-signpost-2"></i> {{ parcel.distance_km }} km
</span>
<span class="d-flex align-items-center gap-1">
<i class="bi bi-box-seam"></i> {{ parcel.weight }} kg
</span>
</div>
</div>
<div class="col-md-4 text-md-end">
<div class="d-flex flex-column align-items-md-end gap-2">
<div class="text-primary fw-bold fs-5">{{ parcel.price }} OMR</div>
<form action="{% url 'accept_parcel' parcel.id %}" method="POST" class="w-100 w-md-auto">
{% csrf_token %}
<button type="submit" class="btn btn-masarx-primary btn-sm w-100">{% trans "Accept" %}</button>
</form>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<!-- Pagination -->
{% if available_parcels.has_other_pages %}
<nav aria-label="Page navigation" class="mt-5">
<ul class="pagination justify-content-center">
{% if available_parcels.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ available_parcels.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&laquo;</span>
</li>
{% endif %}
{% for i in available_parcels.paginator.page_range %}
{% if available_parcels.number == i %}
<li class="page-item active"><span class="page-link">{{ i }}</span></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if available_parcels.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ available_parcels.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&raquo;</span>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<p class="text-center py-5">{% trans "No shipments available at the moment." %}</p>
{% endif %}
{% else %}
<!-- Not Approved State for Tab Pane -->
<div class="text-center py-5">
<i class="bi bi-lock-fill display-4 text-muted mb-3"></i>
<h4 class="text-muted">{% trans "Access Restricted" %}</h4>
<p class="text-muted">{% trans "Please wait for administrator approval to view available shipments." %}</p>
</div>
{% endif %}
</div>
<!-- My Deliveries (Active) -->
<div class="tab-pane fade" id="pills-my" role="tabpanel">
{% if my_parcels %}
<div class="row g-4">
{% for parcel in my_parcels %}
<div class="col-md-6 col-lg-4">
<div class="card border-0 shadow-sm h-100" style="border-radius: 15px;">
<div class="card-body">
<div class="d-flex justify-content-between mb-2">
<span class="badge bg-light text-dark">#{{ parcel.tracking_number }}</span>
<span class="badge bg-primary">{{ parcel.get_status_display }}</span>
</div>
<h5 class="card-title">{{ parcel.description|truncatechars:30 }}</h5>
<p class="card-text mb-1 small"><strong>{% trans "To" %}:</strong> {{ parcel.delivery_governate.name }} / {{ parcel.delivery_city.name }}</p>
<p class="card-text mb-3 small"><strong>{% trans "Receiver" %}:</strong> {{ parcel.receiver_name }}</p>
<form action="{% url 'update_status' parcel.id %}" method="POST" class="d-flex gap-2">
{% csrf_token %}
<select name="status" class="form-select form-select-sm">
{% for code, label in parcel.STATUS_CHOICES %}
{% if code != 'pending' and code != 'cancelled' %}
<option value="{{ code }}" {% if parcel.status == code %}selected{% endif %}>{{ label }}</option>
{% endif %}
{% endfor %}
</select>
<button type="submit" class="btn btn-sm btn-outline-primary">{% trans "Update" %}</button>
</form>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<p class="text-center py-5">{% trans "You haven't accepted any shipments yet." %}</p>
{% endif %}
</div>
<!-- Transaction History (Delivered Only) -->
<div class="tab-pane fade" id="pills-history" role="tabpanel">
{% if completed_parcels %}
<div class="card shadow-sm border-0" style="border-radius: 15px;">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light">
<tr>
<th class="ps-4">{% trans "Date" %}</th>
<th>{% trans "Tracking ID" %}</th>
<th>{% trans "From" %}</th>
<th>{% trans "To" %}</th>
<th>{% trans "Distance" %}</th>
<th>{% trans "Price" %}</th>
<th>{% trans "Status" %}</th>
</tr>
</thead>
<tbody>
{% for parcel in completed_parcels %}
<tr>
<td class="ps-4">{{ parcel.created_at|date:"Y-m-d" }}</td>
<td><span class="badge bg-light text-dark">#{{ parcel.tracking_number }}</span></td>
<td>{{ parcel.pickup_governate.name }} / {{ parcel.pickup_city.name }}</td>
<td>{{ parcel.delivery_governate.name }} / {{ parcel.delivery_city.name }}</td>
<td>{{ parcel.distance_km }} km</td>
<td>{{ parcel.price }} OMR</td>
<td>
<span class="badge bg-success">
{{ parcel.get_status_display }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% else %}
<div class="text-center py-5">
<p class="lead">{% trans "No completed deliveries yet." %}</p>
</div>
{% endif %}
</div>
<!-- Cancelled Shipments -->
<div class="tab-pane fade" id="pills-cancelled" role="tabpanel">
{% if cancelled_parcels %}
<div class="card shadow-sm border-0" style="border-radius: 15px;">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light">
<tr>
<th class="ps-4">{% trans "Date" %}</th>
<th>{% trans "Tracking ID" %}</th>
<th>{% trans "From" %}</th>
<th>{% trans "To" %}</th>
<th>{% trans "Distance" %}</th>
<th>{% trans "Price" %}</th>
<th>{% trans "Status" %}</th>
</tr>
</thead>
<tbody>
{% for parcel in cancelled_parcels %}
<tr>
<td class="ps-4">{{ parcel.created_at|date:"Y-m-d" }}</td>
<td><span class="badge bg-light text-dark">#{{ parcel.tracking_number }}</span></td>
<td>{{ parcel.pickup_governate.name }} / {{ parcel.pickup_city.name }}</td>
<td>{{ parcel.delivery_governate.name }} / {{ parcel.delivery_city.name }}</td>
<td>{{ parcel.distance_km }} km</td>
<td>{{ parcel.price }} OMR</td>
<td>
<span class="badge bg-danger">
{{ parcel.get_status_display }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% else %}
<div class="text-center py-5">
<p class="lead">{% trans "No cancelled shipments." %}</p>
</div>
{% endif %}
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const gridViewBtn = document.getElementById('btn-grid-view');
const listViewBtn = document.getElementById('btn-list-view');
const gridView = document.getElementById('view-grid');
const listView = document.getElementById('view-list');
function setView(view) {
if (view === 'list') {
if (gridView) gridView.classList.add('d-none');
if (listView) listView.classList.remove('d-none');
if (listViewBtn) listViewBtn.classList.add('active');
if (gridViewBtn) gridViewBtn.classList.remove('active');
localStorage.setItem('driverDashboardView', 'list');
} else {
if (listView) listView.classList.add('d-none');
if (gridView) gridView.classList.remove('d-none');
if (gridViewBtn) gridViewBtn.classList.add('active');
if (listViewBtn) listViewBtn.classList.remove('active');
localStorage.setItem('driverDashboardView', 'grid');
}
}
// Check local storage or default to grid
const savedView = localStorage.getItem('driverDashboardView');
if (savedView) {
setView(savedView);
}
// Bind events
if (gridViewBtn) gridViewBtn.addEventListener('click', () => setView('grid'));
if (listViewBtn) listViewBtn.addEventListener('click', () => setView('list'));
});
</script>
{% endblock %}