{% extends "admin/_base.html" %}
{% block content %}
<header class="rio-page-header">
<nav class="rio-breadcrumbs"><a href="/admin">Home</a> · <span>{{ display_name }}</span></nav>
<div class="rio-page-actions">
<h1>{{ display_name }}</h1>
<a class="rio-button rio-button--primary" href="/admin/{{ admin_name }}/new">{{ icon("plus", class="rio-icon") }} Add {{ singular_name }}</a>
</div>
</header>
<div class="rio-toolbar">
{# The search form carries hidden inputs for every active filter +
# the current sort, so submitting a query keeps the rest of the
# list-view state intact. Page intentionally resets to 1 — a new
# query against page N rarely makes sense. #}
<form method="get" action="/admin/{{ admin_name }}" class="rio-search-bar" role="search">
<span class="rio-search-input-wrap">
{{ icon("search", class="rio-search-icon") }}
<input type="search" name="q" value="{{ search_query }}" placeholder="Search…" class="rio-search-input" aria-label="Search">
</span>
{% for pair in active_filter_pairs %}
<input type="hidden" name="{{ pair[0] }}" value="{{ pair[1] }}">
{% endfor %}
{% if active_sort_field %}
<input type="hidden" name="sort" value="{{ active_sort_field }}">
<input type="hidden" name="dir" value="{{ active_sort_dir }}">
{% endif %}
{% if active_per_page_override %}
<input type="hidden" name="per_page" value="{{ active_per_page_override }}">
{% endif %}
<button type="submit" class="rio-button">Search</button>
</form>
{% if filters %}
<div class="rio-dropdown" data-rio-dropdown>
<button type="button" class="rio-dropdown-toggle" aria-haspopup="true" aria-expanded="false">
{{ icon("filter", class="rio-icon") }}
Filters
{% if active_filter_count > 0 %}
<span class="rio-dropdown-badge" aria-label="{{ active_filter_count }} active filter">{{ active_filter_count }}</span>
{% endif %}
{{ icon("chevron-down", class="rio-chev") }}
</button>
<div class="rio-dropdown-panel" role="dialog" aria-label="Filters">
{% for group in filters %}
<div class="rio-dropdown-section">
<span class="rio-dropdown-label">{{ group.label }}</span>
<div class="rio-dropdown-options">
<a href="{{ group.all_link }}" class="rio-dropdown-chip{% if not group.current %} is-active{% endif %}">All</a>
{% for opt in group.options %}
<a href="{{ opt.link }}" class="rio-dropdown-chip{% if opt.selected %} is-active{% endif %}">{{ opt.label }}</a>
{% endfor %}
</div>
</div>
{% endfor %}
{% if active_filter_count > 0 %}
<div class="rio-dropdown-footer">
<a href="{{ clear_all_filters_link }}" class="rio-button">Clear all</a>
</div>
{% endif %}
</div>
</div>
{% endif %}
{% if sort_options %}
<div class="rio-dropdown" data-rio-dropdown>
<button type="button" class="rio-dropdown-toggle" aria-haspopup="true" aria-expanded="false">
Sort: <strong style="font-weight: 600; color: var(--rio-text-strong);">{{ current_sort_label }}</strong>
{{ icon("chevron-down", class="rio-chev") }}
</button>
<div class="rio-dropdown-panel" role="dialog" aria-label="Sort">
<div class="rio-dropdown-menu">
{% for opt in sort_options %}
<a href="{{ opt.link }}" class="rio-dropdown-item{% if opt.is_active %} is-active{% endif %}">{{ opt.label }}</a>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% if per_page_options %}
<div class="rio-dropdown" data-rio-dropdown>
<button type="button" class="rio-dropdown-toggle" aria-haspopup="true" aria-expanded="false">
{{ current_per_page_label }}
{{ icon("chevron-down", class="rio-chev") }}
</button>
<div class="rio-dropdown-panel" role="dialog" aria-label="Rows per page">
<div class="rio-dropdown-menu">
{% for opt in per_page_options %}
<a href="{{ opt.link }}" class="rio-dropdown-item{% if opt.is_active %} is-active{% endif %}">{{ opt.label }}</a>
{% endfor %}
</div>
</div>
</div>
{% endif %}
</div>
{% if active_filter_pills %}
<div class="rio-active-filters" role="region" aria-label="Active filters">
<span class="rio-active-filters-label">Active</span>
{% for pill in active_filter_pills %}
<span class="rio-active-pill">
<span class="rio-active-pill-key">{{ pill.label }}:</span>
{{ pill.value_label }}
<a href="{{ pill.remove_link }}" class="rio-active-pill-x" aria-label="Remove {{ pill.label }} filter">×</a>
</span>
{% endfor %}
<a href="{{ clear_all_filters_link }}" class="rio-active-filters-clear">Clear all</a>
</div>
{% endif %}
{# Bulk-select form wraps the entire table so checked rows submit as
# a single comma-separated `_ids` field built by admin.js. The form
# POSTs to `/admin/{name}/bulk_delete`; the server's two-step flow
# (confirm → commit) takes over from there. JS toggles `.is-active`
# on the form when ≥1 checkbox is checked, which reveals the bulk
# bar. Without JS, the bulk bar stays hidden and users fall back to
# per-row Delete actions. #}
<form method="post" action="/admin/{{ admin_name }}/bulk_delete" class="rio-bulk-form" data-rio-bulk>
<input type="hidden" name="_csrf" value="{{ csrf_token }}">
<input type="hidden" name="_ids" value="" data-rio-bulk-ids>
<div class="rio-bulk-bar" role="region" aria-live="polite" aria-label="Bulk actions">
<span class="rio-bulk-bar-count"><strong data-rio-bulk-count>0</strong> selected</span>
{# Built-in Delete uses the form's default action (/bulk_delete).
# Project-defined actions override via `formaction`, so the
# same form + same selected ids dispatch to different routes. #}
<button type="submit" class="rio-button rio-button--danger">{{ icon("trash", class="rio-icon") }} Delete selected</button>
{% for btn in bulk_action_buttons %}
<button type="submit" formaction="{{ btn.form_action }}" class="rio-button{% if btn.destructive %} rio-button--danger{% endif %}">{{ btn.label }}</button>
{% endfor %}
<button type="button" class="rio-bulk-bar-clear" data-rio-bulk-clear>Clear selection</button>
</div>
<section class="rio-card rio-list">
{% if rows %}
<table class="rio-table rio-table--striped">
<thead>
<tr>
<th class="rio-th rio-th--checkbox">
<input type="checkbox" class="rio-row-checkbox-all" data-rio-bulk-all aria-label="Select all rows">
</th>
{% for f in fields %}
<th class="rio-th rio-th--{{ f.kind }}{% if f.sort_active %} rio-th--sort-{{ f.sort_active }}{% endif %}">
<a href="{{ f.sort_link }}" class="rio-th-sort">
{{ f.label }}{% if f.sort_active == "asc" %} ▲{% elif f.sort_active == "desc" %} ▼{% endif %}
</a>
</th>
{% endfor %}
<th class="rio-th rio-th--actions">Actions</th>
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
<td class="rio-td rio-td--checkbox">
<input type="checkbox" class="rio-row-checkbox" data-rio-bulk-row value="{{ row.id }}" aria-label="Select row {{ row.id }}">
</td>
{% for f in fields %}
<td class="rio-td rio-td--{{ f.kind }}"{% if f.kind == "text" %} title="{{ row[f.name]|default(value='') }}"{% endif %}>
{% if f.name == "id" %}
<a href="/admin/{{ admin_name }}/{{ row.id }}/edit">{{ row.id }}</a>
{% elif f.kind == "checkbox" %}
{% if row[f.name] %}Yes{% else %}No{% endif %}
{% else %}
{{ row[f.name]|default(value='') }}
{% endif %}
</td>
{% endfor %}
<td class="rio-td rio-td--actions">
<a class="rio-button rio-button--ghost rio-button--sm" href="/admin/{{ admin_name }}/{{ row.id }}/edit">{{ icon("pencil", class="rio-icon") }} Edit</a>
<a class="rio-button rio-button--danger-ghost rio-button--sm" href="/admin/{{ admin_name }}/{{ row.id }}/delete">{{ icon("trash", class="rio-icon") }} Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="rio-empty">No {{ display_name|lower }} yet. <a href="/admin/{{ admin_name }}/new">Add the first one.</a></p>
{% endif %}
</section>
</form>
{% if total_pages > 1 %}
<nav class="rio-pagination" aria-label="Pagination">
<span class="rio-meta">{{ total_rows }} total · page {{ page }} of {{ total_pages }}</span>
{% if prev_page_link %}<a class="rio-pagination-link" href="{{ prev_page_link }}">← Previous</a>{% endif %}
{% for item in page_items %}
{% if item.kind == "ellipsis" %}
<span class="rio-pagination-ellipsis" aria-hidden="true">…</span>
{% elif item.is_active %}
<span class="rio-pagination-num is-active" aria-current="page">{{ item.number }}</span>
{% else %}
<a class="rio-pagination-num" href="{{ item.link }}">{{ item.number }}</a>
{% endif %}
{% endfor %}
{% if next_page_link %}<a class="rio-pagination-link" href="{{ next_page_link }}">Next →</a>{% endif %}
</nav>
{% endif %}
{% endblock %}