ixg_platform/templates/ops/base_ops.html
ixgadmin f6aedc0002 Add the compliance registers to the ops portal
Facility, origin zone and collector group could only be registered in the
Django admin, which left the portal unable to onboard a new supply site,
zone or group. Add list/create/edit screens for all three, and create/edit
for mitigation actions, EUDR evidence and external-submission references
on a due-diligence case.

The origin-zone form keeps the map a view of the stored geometry, not a
check of it: the map wording is unchanged and geometry is only required to
be valid JSON. Verification is stamped from the acting user when the status
moves to verified/rejected, and cleared when it returns to unverified.

Nothing is removed from the admin; it stays as the superuser fallback.
Adds an nginx /tiles/ route on the ops host so the map imagery loads there
too (the tile view is root-mounted but ops remaps / to /ops/).
2026-09-25 16:26:59 +00:00

77 lines
6.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}IXG Operations{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<style>
body { font-size: .875rem; background: #f5f6fa; }
.sidebar { position: fixed; top: 0; bottom: 0; left: 0; z-index: 100; padding: 48px 0 0; width: 240px; background: #1e2a3a; }
.sidebar .nav-link { color: #a0aec0; padding: .65rem 1.25rem; font-size: .875rem; }
.sidebar .nav-link:hover, .sidebar .nav-link.active { color: #fff; background: rgba(255,255,255,.08); }
.sidebar .nav-link i { margin-right: .5rem; }
.sidebar .brand { padding: 1rem 1.25rem; font-size: 1.1rem; font-weight: 700; color: #fff; border-bottom: 1px solid rgba(255,255,255,.08); margin-bottom: .5rem; }
.main { margin-left: 240px; }
.topbar { background: #fff; border-bottom: 1px solid #e2e8f0; padding: .75rem 1.5rem; display: flex; justify-content: space-between; align-items: center; }
.content { padding: 1.5rem; }
.stat-card { background: #fff; border-radius: .5rem; padding: 1.25rem; border: 1px solid #e2e8f0; }
.stat-card .stat-value { font-size: 1.75rem; font-weight: 700; }
.stat-card .stat-label { font-size: .8rem; color: #718096; text-transform: uppercase; letter-spacing: .05em; }
.badge-status { font-size: .75rem; }
.page-header { margin-bottom: 1.5rem; }
.page-header h2 { font-weight: 600; }
.filter-bar { background: #fff; border-radius: .5rem; padding: 1rem; border: 1px solid #e2e8f0; margin-bottom: 1.5rem; }
.guide-content img { max-width: 100%; height: auto; border-radius: .375rem; }
.guide-content table { width: 100%; border-collapse: collapse; margin-bottom: 1rem; }
.guide-content th, .guide-content td { border: 1px solid #e2e8f0; padding: .5rem .75rem; }
.guide-content pre { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: .375rem; padding: .75rem; }
.guide-content blockquote { border-left: 4px solid #a7f3d0; padding-left: 1rem; color: #475569; }
</style>
{% block extra_head %}{% endblock %}
</head>
<body>
<div class="sidebar">
<div class="brand">IXG Platform</div>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link {% if request.resolver_match.url_name == 'dashboard' %}active{% endif %}" href="{% url 'ops:dashboard' %}"><i class="bi bi-speedometer2"></i> Dashboard</a></li>
<li class="nav-item"><a class="nav-link {% if 'intake' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:intake_list' %}"><i class="bi bi-basket"></i> Harvest Intakes</a></li>
<li class="nav-item"><a class="nav-link {% if 'facility' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:facility_list' %}"><i class="bi bi-building"></i> Facilities</a></li>
<li class="nav-item"><a class="nav-link {% if 'origin_zone' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:origin_zone_list' %}"><i class="bi bi-geo-alt"></i> Origin Zones</a></li>
<li class="nav-item"><a class="nav-link {% if 'collector' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:collector_group_list' %}"><i class="bi bi-people"></i> Collector Groups</a></li>
<li class="nav-item"><a class="nav-link {% if 'batch' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:batch_list' %}"><i class="bi bi-box-seam"></i> Batches</a></li>
<li class="nav-item"><a class="nav-link {% if 'qc' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:qc_list' %}"><i class="bi bi-clipboard-check"></i> QC Results</a></li>
<li class="nav-item"><a class="nav-link {% if 'verify' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:qc_verify_list' %}"><i class="bi bi-person-check"></i> QC Approvals</a></li>
<li class="nav-item"><a class="nav-link {% if 'coa' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:coa_review_list' %}"><i class="bi bi-file-earmark-medical"></i> CoA Reviews</a></li>
<li class="nav-item"><a class="nav-link {% if 'eudr' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:eudr_list' %}"><i class="bi bi-shield-check"></i> EUDR Compliance</a></li>
<li class="nav-item"><a class="nav-link {% if 'shipment' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:shipment_list' %}"><i class="bi bi-truck"></i> Shipments</a></li>
<li class="nav-item"><a class="nav-link {% if 'capa' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:capa_list' %}"><i class="bi bi-exclamation-triangle"></i> CAPA Records</a></li>
<li class="nav-item"><a class="nav-link {% if 'document' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:document_list' %}"><i class="bi bi-file-earmark-text"></i> Documents</a></li>
<li class="nav-item"><a class="nav-link {% if 'esg' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:esg_list' %}"><i class="bi bi-tree"></i> ESG Reports</a></li>
<li class="nav-item"><a class="nav-link {% if 'guide' in request.resolver_match.url_name %}active{% endif %}" href="{% url 'ops:guide_index' %}"><i class="bi bi-book"></i> Help</a></li>
</ul>
</div>
<div class="main">
<div class="topbar">
<span></span>
<div class="d-flex align-items-center gap-3">
<a href="/admin/" class="text-decoration-none text-secondary"><i class="bi bi-shield-lock"></i> Admin</a>
<span class="text-secondary">{{ request.user.full_name|default:request.user.email }}</span>
<form method="post" action="{% url 'oidc_logout' %}" class="m-0">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-outline-secondary">Logout</button>
</form>
</div>
</div>
<div class="content">
{% block content %}{% endblock %}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
{% block extra_js %}{% endblock %}
</body>
</html>