ixg_platform/templates/portal/dashboard.html
ixgadmin 19d67555da Add public buyer self-registration
A UK buyer can now create their own account at /portal/signup/. The screen
creates a Keycloak user through a least-privilege service account
(ixg-provisioning: manage-users, view-users) and the matching Django row as
a buyer, then sends them through the normal sign-in flow to the portal.

Staff status is derived from the role in the OIDC backend rather than
asserted, so a self-registered buyer is not staff and does not become staff
on a later sign-in. The platform root and the RBAC middleware now route
each role to its own portal, which also fixes a redirect loop that the
staff fix exposed for non-staff buyers.
2026-09-21 11:30:29 +00:00

80 lines
No EOL
2.8 KiB
HTML

{% extends 'portal/base_portal.html' %}
{% block title %}Dashboard - IXG Buyer Portal{% endblock %}
{% block content %}
{% if welcome %}
<div class="alert alert-success" role="alert">
<i class="bi bi-check-circle"></i> Your account is ready. Welcome to the IXG buyer portal.
</div>
{% endif %}
<div class="page-header d-flex justify-content-between align-items-center">
<h2>Buyer Dashboard</h2>
<span class="text-secondary">Batches available: <strong>{{ total_batches }}</strong></span>
</div>
<div class="row g-3 mb-4">
<div class="col-md-4">
<div class="stat-card">
<div class="stat-value text-primary">{{ total_batches }}</div>
<div class="stat-label">Total Batches</div>
</div>
</div>
<div class="col-md-4">
<div class="stat-card">
<div class="stat-value text-success">{{ active_shipments }}</div>
<div class="stat-label">Active Shipments</div>
</div>
</div>
<div class="col-md-4">
<div class="stat-card">
<div class="stat-value text-info">{{ documents|length }}</div>
<div class="stat-label">Recent Documents</div>
</div>
</div>
</div>
<div class="row g-3">
<div class="col-md-7">
<div class="stat-card">
<h6 class="mb-3">Recent Batches</h6>
<table class="table table-sm mb-0">
<thead><tr><th>Reference</th><th>Grade</th><th>Status</th><th>Harvest Date</th></tr></thead>
<tbody>
{% for b in recent_batches %}
<tr>
<td><a href="{% url 'portal:batch_detail' b.pk %}">{{ b.batch_reference }}</a></td>
<td>{{ b.grade|default:'-' }}</td>
<td><span class="badge bg-secondary badge-status">{{ b.get_status_display }}</span></td>
<td>{{ b.harvest_date|date:'d/m/Y'|default:'-' }}</td>
</tr>
{% empty %}
<tr><td colspan="4" class="text-muted">No batches</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="col-md-5">
<div class="stat-card mb-3">
<h6 class="mb-3">Recent Documents</h6>
{% for d in documents %}
<div class="border-bottom pb-2 mb-2">
<a href="{% url 'portal:document_download' d.id %}" target="_blank"><strong>{{ d.file_name }}</strong></a><br>
<span class="text-muted small">{{ d.get_doc_type_display }} · {{ d.uploaded_at|date:'d/m/Y' }}</span>
</div>
{% empty %}
<p class="text-muted mb-0">No documents available</p>
{% endfor %}
</div>
{% if subscription %}
<div class="stat-card">
<h6 class="mb-2">Subscription</h6>
<span class="badge {% if subscription.status == 'active' %}bg-success{% else %}bg-warning text-dark{% endif %}">{{ subscription.get_status_display }}</span>
<span class="text-muted ms-2">{{ subscription.get_plan_display }}</span>
</div>
{% endif %}
</div>
</div>
{% endblock %}