{% extends 'base.html' %} {% load static format_tags %} {% block title %}Absences | FoxFitt{% endblock %} {% block content %} {% comment %} === ABSENCES LIST PAGE === Filtered, paginated table of absences. Each row links to edit and has an inline delete form. CSV export button only shows for admin. {% endcomment %}
{# === Page header — title + log/export action buttons === #}

Absences

{{ page.paginator.count }} record{{ page.paginator.count|pluralize }}
Log Absence {% if is_admin %} CSV {% endif %}
{# === Flash messages (e.g. "Absence deleted") === #} {% if messages %} {% for m in messages %}
{{ m }}
{% endfor %} {% endif %} {# === Filter bar — 7 fields stacked on mobile, wrapped on desktop === #}
{# === Reason filter — multi-checkbox dropdown (Fix A2, May 2026) === #} {# All checkboxes share name="reason" so Django gets multiple values #} {# in request.GET.getlist('reason') when the form submits. The wrapping #} {#
    keeps the dropdown open while #} {# the user is picking multiple boxes; submitting via the Apply button #} {# closes it normally. #}
Clear
{# === Table of absences === #}
{% for a in page %} {% empty %} {% endfor %}
Date Worker Reason Paid? Logged by Notes
{{ a.date|date:"d M Y" }} {{ a.worker.name }} {{ a.get_reason_display }} {% if a.is_paid %} {% if a.payroll_adjustment %}({{ a.payroll_adjustment.amount|money }}){% endif %} {% else %} {% endif %} {{ a.logged_by.username|default:"—" }} {{ a.notes|truncatechars:60 }}
{% csrf_token %}
No absences match the filters.
{# === Pagination — only shown when there's more than one page === #} {% if page.has_other_pages %} {% endif %}
{% comment %} === Reason badge colours === Reuses the existing semantic badge palette from custom.css so dark/ light theme switching works out of the box. Green-ish for "valid" leave (sick/family/annual), neutral for unpaid/other, amber for IOD, purple-ish (deduction) for the disciplinary reasons (suspension, absconded). {% endcomment %} {% endblock %}