atr/templates/committee-directory.html (90 lines of code) (raw):

{% extends "layouts/base.html" %} {% block title %} Committee directory ~ ATR {% endblock title %} {% block description %} List of all ASF committees and their associated projects. {% endblock description %} {% block content %} <h1>Committee directory</h1> <p>Current ASF committees and their projects:</p> <div class="mb-3"> <input type="text" id="project-filter" class="form-control d-inline-block w-auto" /> <button type="button" class="btn btn-primary" id="filter-button">Filter</button> </div> <div class="mb-3"> <p>Total count: {{ committees|length }}</p> </div> <div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4"> {% for committee in committees %} <div class="col"> <div class="card h-100 shadow-sm atr-cursor-pointer page-project-card" data-project-url="{{ as_url(routes.committees.view, name=committee.name) }}"> <div class="card-body"> <h3 class="card-title fs-4 mb-3">{{ committee.display_name }}</h3> <div class="row g-3"> <div class="col-4"> <div class="card h-100 bg-light border-0"> <div class="card-body p-2 d-flex flex-column justify-content-between text-center"> <small class="text-secondary">PMC members</small> <span class="fs-4 fw-medium mt-2">{{ committee.committee_members|length }}</span> </div> </div> </div> <div class="col-4"> <div class="card h-100 bg-light border-0"> <div class="card-body p-2 d-flex flex-column justify-content-between text-center"> <small class="text-secondary">Committers</small> <span class="fs-4 fw-medium mt-2">{{ committee.committers|length }}</span> </div> </div> </div> <div class="col-4"> <div class="card h-100 bg-light border-0"> <div class="card-body p-2 d-flex flex-column justify-content-between text-center"> <small class="text-secondary">Projects</small> <span class="fs-4 fw-medium mt-2">{{ committee.projects|length }}</span> </div> </div> </div> </div> </div> </div> </div> {% endfor %} </div> {% endblock content %} {% block javascripts %} {{ super() }} <script> function filter() { const projectFilter = document.getElementById("project-filter").value; const cards = document.querySelectorAll(".page-project-card"); for (let card of cards) { const nameElement = card.querySelector(".card-title"); const name = nameElement.innerHTML; if (!projectFilter) { card.parentElement.hidden = false; } else { card.parentElement.hidden = !name.match(new RegExp(projectFilter, 'i')); } } } // Add event listeners document.getElementById("filter-button").addEventListener("click", filter); document.getElementById("project-filter").addEventListener("keydown", function(event) { if (event.key === "Enter") { filter(); event.preventDefault(); } }); // Add click handlers for project cards document.querySelectorAll(".page-project-card").forEach(function(card) { card.addEventListener("click", function() { window.location.href = this.getAttribute("data-project-url"); }); }); </script> {% endblock javascripts %}