ixg_platform/templates/ops/intake_form.html
ixgadmin db05d6052a Quote the ops templates' HTML attributes so the classes apply
An unquoted attribute value ends at the first whitespace, so
``class=badge bg-danger`` is read by every browser as ``class="badge"`` plus two
meaningless attributes. Bootstrap was loading perfectly well; the markup simply
never asked for the styles. Across the ops portal that meant buttons rendered as
plain links, status badges were invisible (white text on a white background: a
failed result showed as nothing at all), the active sidebar item never
highlighted, and the flex utility classes did nothing. The buyer portal templates
quote their attributes, which is why only the ops portal looked unstyled.

346 attributes across 20 templates, rewritten mechanically with a conservative
transform that handles the three shapes in use — a Django tag as the value, a
multi-token class list, and a trailing simple conditional (the active-nav
highlight) — and leaves anything it does not recognise exactly as it was.
2026-09-17 13:57:53 +00:00

71 lines
2.9 KiB
HTML

{% extends 'ops/base_ops.html' %}
{% load static %}
{% block title %}{{ page_title }} - IXG Operations{% endblock %}
{% block content %}
<div class="page-header d-flex justify-content-between align-items-center">
<h2>{{ page_title }}</h2>
<a href="{% url 'ops:intake_list' %}" class="btn btn-sm btn-outline-secondary"><i class="bi bi-arrow-left"></i> Back</a>
</div>
<div class="row g-3">
<div class="col-md-7">
<div class="stat-card">
<form method="post novalidate" id="intake-form" data-group-zones="{{ group_zones }}">
{% csrf_token %}
{% if form.non_field_errors %}
{% for e in form.non_field_errors %}<div class="alert alert-danger py-2">{{ e }}</div>{% endfor %}
{% endif %}
{% for field in form %}
<div class="mb-3">
<label class="form-label" for="{{ field.id_for_label }}">
{{ field.label }}{% if field.field.required %} <span class="text-danger">*</span>{% endif %}
</label>
{{ field }}
{% if field.help_text %}<div class="form-text">{{ field.help_text }}</div>{% endif %}
{% for e in field.errors %}<div class="text-danger small">{{ e }}</div>{% endfor %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">{{ submit_label }}</button>
<a href="{% url 'ops:intake_list' %}" class="btn btn-outline-secondary">Cancel</a>
</form>
</div>
</div>
<div class="col-md-5">
<div class="stat-card mb-3">
<h6 class="mb-3"><i class="bi bi-info-circle"></i> Recording an intake</h6>
<p class="small mb-2">
An intake is the moment a collector group hands over shea at the processing
site. It is the record a finished batch is traced back to, so the fields
marked <span class="text-danger">*</span> are required: they are the ones the
platform's due-diligence checks read.
</p>
<p class="small mb-0">
If something is wrong on a saved intake, use <strong>Correct</strong> on the
list. Nothing is deleted — the record is amended, so the reference a buyer
or an auditor sees stays the same.
</p>
</div>
<div class="stat-card">
<h6 class="mb-3"><i class="bi bi-shield-check"></i> What these records feed</h6>
<ul class="small mb-0 ps-3">
<li><strong>Lineage</strong> — a batch needs at least one intake linked to it</li>
<li><strong>Intake data</strong> — a linked intake must have both a date and a weight</li>
<li><strong>Geolocation</strong> — every linked intake must point at a <em>verified</em> origin zone</li>
</ul>
<p class="small text-secondary mt-2 mb-0">
A missing date, weight or zone holds the batch's EUDR case back until it is
corrected here.
</p>
</div>
</div>
</div>
<script src="{% static 'js/ixg_intake_form.js' %}"></script>
{% endblock %}