408 lines
24 KiB
HTML
408 lines
24 KiB
HTML
{% extends 'base.html' %}
|
|
{% load i18n core_tags %}
|
|
|
|
{% block content %}
|
|
<div class="container py-5">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h1>{% trans "My Shipments" %}</h1>
|
|
<a href="{% url 'shipment_request' %}" class="btn btn-masarx-primary">{% trans "New Shipment" %}</a>
|
|
</div>
|
|
|
|
<!-- Tabs -->
|
|
<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-active-tab" data-bs-toggle="pill" data-bs-target="#pills-active" type="button" role="tab">{% trans "Active Shipments" %}</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">
|
|
|
|
<!-- Active Shipments -->
|
|
<div class="tab-pane fade show active" id="pills-active" role="tabpanel">
|
|
|
|
<!-- Toolbar -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h5 class="mb-0 text-muted">{% trans "Current 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 active_parcels %}
|
|
|
|
<!-- Grid View -->
|
|
<div id="view-grid" class="row g-4">
|
|
{% for parcel in active_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 {% if parcel.status == 'delivered' %}bg-success{% elif parcel.status == 'cancelled' %}bg-danger{% else %}bg-warning{% endif %}">
|
|
{{ parcel.get_status_display }}
|
|
</span>
|
|
</div>
|
|
<h5 class="card-title">{{ parcel.description|truncatechars:30 }}</h5>
|
|
<p class="card-text mb-1 small text-muted"><i class="fas fa-map-marker-alt"></i> <strong>{% trans "From" %}:</strong> {{ parcel.pickup_governate.name }} / {{ parcel.pickup_city.name }}</p>
|
|
<p class="card-text mb-1 small text-muted"><i class="fas fa-flag-checkered"></i> <strong>{% trans "To" %}:</strong> {{ parcel.delivery_governate.name }} / {{ parcel.delivery_city.name }}</p>
|
|
<p class="card-text mb-3 small text-muted"><i class="fas fa-road"></i> <strong>{% trans "Distance" %}:</strong> {{ parcel.distance_km }} km</p>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<span class="text-primary fw-bold">{{ parcel.price }} OMR</span>
|
|
<span class="badge {% if parcel.payment_status == 'paid' %}bg-success{% else %}bg-secondary{% endif %}">
|
|
{{ parcel.get_payment_status_display }}
|
|
</span>
|
|
</div>
|
|
|
|
{% if parcel.status == 'pending' %}
|
|
<div class="d-flex gap-2 mb-2">
|
|
<a href="{% url 'edit_parcel' parcel.id %}" class="btn btn-sm btn-outline-info w-100" title="{% trans 'Edit Shipment' %}">
|
|
<i class="fas fa-edit me-1"></i> {% trans "Edit" %}
|
|
</a>
|
|
<a href="{% url 'cancel_parcel' parcel.id %}" class="btn btn-sm btn-outline-danger w-100" title="{% trans 'Cancel Shipment' %}" onclick="return confirm('{% trans "Are you sure you want to cancel this shipment?" %}');">
|
|
<i class="fas fa-times me-1"></i> {% trans "Cancel" %}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if parcel.payment_status == 'pending' %}
|
|
{% if payments_enabled %}
|
|
<a href="{% url 'initiate_payment' parcel.id %}" class="btn btn-sm btn-outline-primary w-100 mb-2">
|
|
<i class="fas fa-credit-card me-1"></i> {% trans "Pay Now" %}
|
|
</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
<div class="d-flex gap-2 mb-3">
|
|
<a href="{% url 'generate_parcel_label' parcel.id %}" class="btn btn-sm btn-outline-dark w-100" target="_blank">
|
|
<i class="fas fa-print me-1"></i> {% trans "Label" %}
|
|
</a>
|
|
{% if parcel.payment_status == 'paid' %}
|
|
<a href="{% url 'generate_invoice' parcel.id %}" class="btn btn-sm btn-outline-secondary w-100" target="_blank">
|
|
<i class="fas fa-file-invoice me-1"></i> {% trans "Invoice" %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<hr>
|
|
<p class="card-text small mb-0"><strong>{% trans "Receiver" %}:</strong> {{ parcel.receiver_name }}</p>
|
|
<p class="card-text small"><strong>{% trans "Carrier" %}:</strong> {% if parcel.carrier %}{{ parcel.carrier.get_full_name|default:parcel.carrier.username }}{% else %}{% trans "Waiting for pickup" %}{% endif %}</p>
|
|
</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 active_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-7 mb-3 mb-md-0">
|
|
<div class="d-flex align-items-center gap-2 mb-2">
|
|
<h5 class="card-title mb-0">{{ parcel.description|truncatechars:60 }}</h5>
|
|
<span class="badge bg-light text-dark small">#{{ parcel.tracking_number }}</span>
|
|
</div>
|
|
<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-truck"></i>
|
|
{% if parcel.carrier %}{{ parcel.carrier.get_full_name|default:parcel.carrier.username }}{% else %}{% trans "Waiting" %}{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-5 text-md-end">
|
|
<div class="d-flex flex-column align-items-md-end gap-2">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<span class="text-primary fw-bold fs-5">{{ parcel.price }} OMR</span>
|
|
<span class="badge {% if parcel.status == 'delivered' %}bg-success{% elif parcel.status == 'cancelled' %}bg-danger{% else %}bg-warning{% endif %}">
|
|
{{ parcel.get_status_display }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="d-flex gap-2 w-100 justify-content-md-end">
|
|
{% if parcel.status == 'pending' %}
|
|
<a href="{% url 'edit_parcel' parcel.id %}" class="btn btn-sm btn-outline-info" title="{% trans 'Edit' %}">
|
|
<i class="fas fa-edit"></i>
|
|
</a>
|
|
<a href="{% url 'cancel_parcel' parcel.id %}" class="btn btn-sm btn-outline-danger" title="{% trans 'Cancel' %}" onclick="return confirm('{% trans "Are you sure you want to cancel this shipment?" %}');">
|
|
<i class="fas fa-times"></i>
|
|
</a>
|
|
{% endif %}
|
|
|
|
<a href="{% url 'generate_parcel_label' parcel.id %}" class="btn btn-sm btn-outline-dark" target="_blank" title="{% trans 'Print Label' %}">
|
|
<i class="fas fa-print"></i>
|
|
</a>
|
|
{% if parcel.payment_status == 'paid' %}
|
|
<a href="{% url 'generate_invoice' parcel.id %}" class="btn btn-sm btn-outline-secondary" target="_blank" title="{% trans 'Invoice' %}">
|
|
<i class="fas fa-file-invoice"></i>
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if parcel.payment_status == 'pending' and payments_enabled %}
|
|
<a href="{% url 'initiate_payment' parcel.id %}" class="btn btn-sm btn-outline-primary flex-grow-1 flex-md-grow-0">
|
|
<i class="fas fa-credit-card me-1"></i> {% trans "Pay Now" %}
|
|
</a>
|
|
{% else %}
|
|
<span class="badge {% if parcel.payment_status == 'paid' %}bg-success{% else %}bg-secondary{% endif %} p-2">
|
|
{{ parcel.get_payment_status_display }}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{% if active_parcels.has_other_pages %}
|
|
<nav aria-label="Page navigation" class="mt-5">
|
|
<ul class="pagination justify-content-center">
|
|
{% if active_parcels.has_previous %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ active_parcels.previous_page_number }}" aria-label="Previous">
|
|
<span aria-hidden="true">«</span>
|
|
</a>
|
|
</li>
|
|
{% else %}
|
|
<li class="page-item disabled">
|
|
<span class="page-link" aria-hidden="true">«</span>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for i in active_parcels.paginator.page_range %}
|
|
{% if active_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 active_parcels.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ active_parcels.next_page_number }}" aria-label="Next">
|
|
<span aria-hidden="true">»</span>
|
|
</a>
|
|
</li>
|
|
{% else %}
|
|
<li class="page-item disabled">
|
|
<span class="page-link" aria-hidden="true">»</span>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
|
|
{% else %}
|
|
<div class="text-center py-5">
|
|
<p class="lead">{% trans "You have no active shipments." %}</p>
|
|
<a href="{% url 'shipment_request' %}" class="btn btn-masarx-primary">{% trans "Send your first shipment" %}</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Transaction History (Delivered Only) -->
|
|
<div class="tab-pane fade" id="pills-history" role="tabpanel">
|
|
{% if delivered_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 "Description" %}</th>
|
|
<th>{% trans "Carrier" %}</th>
|
|
<th>{% trans "Distance" %}</th>
|
|
<th>{% trans "Bid/Price" %}</th>
|
|
<th>{% trans "Status" %}</th>
|
|
<th>{% trans "Action" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for parcel in delivered_parcels %}
|
|
{% get_rating parcel as rating %}
|
|
<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.description|truncatechars:30 }}</td>
|
|
<td>
|
|
{% if parcel.carrier %}
|
|
{{ parcel.carrier.get_full_name|default:parcel.carrier.username }}
|
|
{% else %}
|
|
-
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ parcel.distance_km }} km</td>
|
|
<td>{{ parcel.price }} OMR</td>
|
|
<td>
|
|
<span class="badge bg-success">
|
|
{{ parcel.get_status_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<a href="{% url 'generate_parcel_label' parcel.id %}" class="btn btn-sm btn-outline-dark me-2" target="_blank" title="{% trans 'Print Label' %}">
|
|
<i class="fas fa-print"></i>
|
|
</a>
|
|
{% if parcel.payment_status == 'paid' %}
|
|
<a href="{% url 'generate_invoice' parcel.id %}" class="btn btn-sm btn-outline-secondary me-2" target="_blank" title="{% trans 'Invoice' %}">
|
|
<i class="fas fa-file-invoice"></i>
|
|
</a>
|
|
{% endif %}
|
|
{% if parcel.status == 'delivered' and parcel.carrier %}
|
|
{% if not rating %}
|
|
<a href="{% url 'rate_driver' parcel.id %}" class="btn btn-sm btn-outline-warning">
|
|
<i class="fas fa-star"></i> {% trans "Rate Driver" %}
|
|
</a>
|
|
{% else %}
|
|
<span class="text-warning" title="{{ rating.comment }}">
|
|
{{ rating.rating }} <i class="fas fa-star"></i>
|
|
</span>
|
|
{% endif %}
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-5">
|
|
<p class="lead">{% trans "No completed transactions 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 "Description" %}</th>
|
|
<th>{% trans "Carrier" %}</th>
|
|
<th>{% trans "Distance" %}</th>
|
|
<th>{% trans "Bid/Price" %}</th>
|
|
<th>{% trans "Status" %}</th>
|
|
<th>{% trans "Action" %}</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.description|truncatechars:30 }}</td>
|
|
<td>
|
|
{% if parcel.carrier %}
|
|
{{ parcel.carrier.get_full_name|default:parcel.carrier.username }}
|
|
{% else %}
|
|
-
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ parcel.distance_km }} km</td>
|
|
<td>{{ parcel.price }} OMR</td>
|
|
<td>
|
|
<span class="badge bg-danger">
|
|
{{ parcel.get_status_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<!-- Actions available for cancelled parcels -->
|
|
<!-- Maybe view label or invoice if paid? -->
|
|
<a href="{% url 'generate_parcel_label' parcel.id %}" class="btn btn-sm btn-outline-dark me-2" target="_blank" title="{% trans 'Print Label' %}">
|
|
<i class="fas fa-print"></i>
|
|
</a>
|
|
{% if parcel.payment_status == 'paid' %}
|
|
<a href="{% url 'generate_invoice' parcel.id %}" class="btn btn-sm btn-outline-secondary me-2" target="_blank" title="{% trans 'Invoice' %}">
|
|
<i class="fas fa-file-invoice"></i>
|
|
</a>
|
|
{% endif %}
|
|
</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('shipperDashboardView', '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('shipperDashboardView', 'grid');
|
|
}
|
|
}
|
|
|
|
// Check local storage or default to grid
|
|
const savedView = localStorage.getItem('shipperDashboardView');
|
|
if (savedView) {
|
|
setView(savedView);
|
|
}
|
|
|
|
// Bind events
|
|
if (gridViewBtn) gridViewBtn.addEventListener('click', () => setView('grid'));
|
|
if (listViewBtn) listViewBtn.addEventListener('click', () => setView('list'));
|
|
});
|
|
</script>
|
|
{% endblock %} |