Add filters to members page

This commit is contained in:
William Bouzourène 2025-01-22 13:13:16 +01:00
parent 3d02804c3f
commit ff91f0ddca
2 changed files with 238 additions and 31 deletions

View file

@ -58,11 +58,62 @@ func Members(c *fiber.Ctx) error {
return err return err
} }
filterSection := c.Query("se")
filterArchive := c.Query("a")
filterSearch := c.Query("s")
sqlFilterSections := allowedSections
sqlFilterAppend := "IS NULL"
if filterArchive == "1" {
sqlFilterAppend = "IS NOT NULL"
sqlFilterSections = allowedSectionsArchived
}
var filterSectionUint uint
if len(filterSection) > 0 {
filterSectionUint64, err := strconv.ParseUint(filterSection, 10, 0)
if err == nil {
for _, s := range sqlFilterSections {
if s == uint(filterSectionUint64) {
filterSectionUint = uint(filterSectionUint64)
}
}
}
}
if filterSectionUint > 0 {
sqlFilterAppend = fmt.Sprintf(
"%s AND section_id = %d",
sqlFilterAppend,
filterSectionUint,
)
}
var sqlFilterSearch string
if len(filterSearch) > 0 {
sqlFilterSearch = fmt.Sprintf(
"%%%s%%", filterSearch,
)
}
var count int64 var count int64
if len(filterSearch) > 0 {
db.Model(&models.Person{}).Where( db.Model(&models.Person{}).Where(
"is_member = ? AND section_id IN ?", fmt.Sprintf(
"is_member = ? AND section_id IN ? AND (first_name LIKE ? OR last_name LIKE ?) AND deleted_at %s",
sqlFilterAppend,
),
true, allowedSections, sqlFilterSearch, sqlFilterSearch,
).Count(&count)
} else {
db.Model(&models.Person{}).Where(
fmt.Sprintf(
"is_member = ? AND section_id IN ? AND deleted_at %s",
sqlFilterAppend,
),
true, allowedSections, true, allowedSections,
).Count(&count) ).Count(&count)
}
pageQuery := c.Query("p") pageQuery := c.Query("p")
page, _ := strconv.Atoi(pageQuery) page, _ := strconv.Atoi(pageQuery)
@ -71,13 +122,18 @@ func Members(c *fiber.Ctx) error {
} }
pageSize := 50 pageSize := 50
offset := (page - 1) * pageSize
maxPages := 1 maxPages := 1
if count > int64(pageSize) { if count > int64(pageSize) {
maxPages = int(count) / pageSize maxPages = int(count) / pageSize
} }
if page > maxPages {
page = 1
}
offset := (page - 1) * pageSize
var pages []int var pages []int
for i := 1; i <= maxPages; i++ { for i := 1; i <= maxPages; i++ {
if i == page { if i == page {
@ -94,15 +150,44 @@ func Members(c *fiber.Ctx) error {
} }
var people []models.Person var people []models.Person
result := db.Offset(offset).Limit(pageSize).Order( if len(filterSearch) > 0 {
result := db.Unscoped().Offset(offset).Limit(pageSize).Order(
"last_name collate nocase asc, first_name collate nocase asc", "last_name collate nocase asc, first_name collate nocase asc",
).Preload("Section").Find( ).Preload("Section").Find(
&people, "is_member = ? AND section_id IN ?", true, allowedSections, &people,
fmt.Sprintf(
"is_member = ? AND section_id IN ? AND (first_name LIKE ? OR last_name LIKE ?) AND deleted_at %s",
sqlFilterAppend,
),
true, sqlFilterSections, sqlFilterSearch, sqlFilterSearch,
) )
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
return err return err
} }
} else {
result := db.Unscoped().Offset(offset).Limit(pageSize).Order(
"last_name collate nocase asc, first_name collate nocase asc",
).Preload("Section").Find(
&people,
fmt.Sprintf(
"is_member = ? AND section_id IN ? AND deleted_at %s",
sqlFilterAppend,
),
true, sqlFilterSections,
)
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
return err
}
}
var sections []models.Section
db.Order(
"name collate nocase asc",
).Find(
&sections, sqlFilterSections,
)
return c.Render("people", fiber.Map{ return c.Render("people", fiber.Map{
"PageTitle": "Membres", "PageTitle": "Membres",
@ -113,6 +198,10 @@ func Members(c *fiber.Ctx) error {
"MaxPages": maxPages, "MaxPages": maxPages,
"PermShow": permShow, "PermShow": permShow,
"PermShowArchived": permShowArchived, "PermShowArchived": permShowArchived,
"Sections": sections,
"FilterArchive": filterArchive,
"FilterSection": filterSectionUint,
"FilterSearch": filterSearch,
}) })
} }

View file

@ -18,13 +18,130 @@
<hr> <hr>
</div> </div>
<div class="my-3 text-end">
{% if MembersPage %}
<div class="btn-group">
<a class="btn btn-primary" href="/members/add">
<i class="bi-plus-lg"></i>
Ajouter
</a>
<a class="btn btn-primary" href="javascript:;">
<i class="bi-filetype-csv"></i>
Exporter
</a>
</div>
{% else %}
<div class="btn-group">
<a class="btn btn-primary" href="/contacts/add">
<i class="bi-plus-lg"></i>
Ajouter
</a>
<a class="btn btn-primary" href="javascript:;">
<i class="bi-filetype-csv"></i>
Exporter
</a>
</div>
{% endif %}
</div>
<form id="filters" method="get" class="my-3">
<div class="row">
<div class="col-6 col-lg-3 mb-2">
<label
for="archive"
class="form-label"
>
Section
</label>
<select
class="form-select"
id="section"
name="se"
>
<option value="0">Toutes</option>
{% for Section in Sections %}
<option
value="{{ Section.ID }}"
{% if Section.ID == FilterSection %}
selected
{% endif %}
>
{{ Section.Name }}
</option>
{% endfor %}
</select>
</div>
<div class="col-6 col-lg-3 mb-2">
<label
for="archive"
class="form-label"
>
Status
</label>
<select
class="form-select"
id="archive"
name="a"
>
{% if PermShow %}
<option value="0">
Actif
</option>
{% endif %}
{% if PermShowArchived %}
<option
value="1"
{% if FilterArchive == "1" %}
selected
{% endif %}
>
Archivé
</option>
{% endif %}
</select>
</div>
<div class="col-lg-6 mb-2">
<label
for="search"
class="form-label"
>
Recherche
</label>
<div class="input-group">
<input
type="text"
class="form-control"
id="search"
name="s"
value="{{ FilterSearch }}"
>
<button
class="btn btn-outline-success"
type="submit"
>
<i class="bi-search"></i>
</button>
</div>
</div>
</div>
</form>
<div class="table-responsive"> <div class="table-responsive">
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>Nom</th> <th class="w-25">Nom</th>
<th>Lieu</th> <th class="w-50 d-none d-sm-table-cell">Adresse</th>
<th>Section</th> <th class="w-25">Section</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -41,7 +158,11 @@
</a> </a>
{% endif %} {% endif %}
</td> </td>
<td> <td class="d-none d-sm-table-cell">
{{ Person.Address1 }}
{% if Person.Address1 and (Person.PostalCode or Person.City) %}
&ndash;
{% endif %}
{{ Person.PostalCode }} {{ Person.City }} {{ Person.PostalCode }} {{ Person.City }}
</td> </td>
<td> <td>
@ -55,7 +176,7 @@
</table> </table>
</div> </div>
<nav aria-label="Page navigation example"> <nav class="mt-3 mb-5">
<ul class="pagination justify-content-center"> <ul class="pagination justify-content-center">
{% if Page <= 1 %} {% if Page <= 1 %}
@ -124,18 +245,15 @@
</ul> </ul>
</nav> </nav>
<div class="mt-3">
{% if MembersPage %}
<a class="btn btn-md btn-primary" href="/members/add">
<i class="bi-plus-lg"></i>
Ajouter
</a>
{% else %}
<a class="btn btn-md btn-primary" href="/contacts/add">
<i class="bi-plus-lg"></i>
Ajouter
</a>
{% endif %}
</div>
</div> </div>
{% endblock %} {% endblock %}
{% block javascript %}
<script>
$(document).ready(function() {
$("#filters select").on("change", function() {
$("#filters").submit();
});
});
</script>
{% endblock %}