evol: filters on beneficiaries

This commit is contained in:
Arnaud Delcasse
2026-02-25 10:33:52 +01:00
parent 29bc3a8bfa
commit 68ac6bb692
5 changed files with 34 additions and 12 deletions

View File

@@ -50,7 +50,7 @@ journey_tabs:
title: Transports title: Transports
enabled: true enabled: true
- name: directory - name: directory
title: Solutions locales title: Solutions complémentaires
module: directory module: directory
- name: carpool - name: carpool
title: Covoiturage title: Covoiturage

View File

@@ -7,14 +7,14 @@
<p class="mt-2 text-sm text-gray-700"></p> <p class="mt-2 text-sm text-gray-700"></p>
</div> </div>
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none"> <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
<a href="/api/cache/{{.ViewState.CacheId}}/export"> <a href="/exports/beneficiaries/beneficiaries.xlsx?{{if $.ViewState.archived}}archived=true&{{end}}{{if $.ViewState.filters.beneficiary_address_geo}}beneficiary_address_geo={{$.ViewState.filters.beneficiary_address_geo}}{{end}}">
<button type="button" <button type="button"
class="inline-flex items-center justify-center bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 flex items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue"> class="inline-flex items-center justify-center bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 flex items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">
{{$.IconSet.Icon "hero:outline/document-arrow-down" "h-5 w-5 mr-3"}} {{$.IconSet.Icon "hero:outline/document-arrow-down" "h-5 w-5 mr-3"}}
Exporter Exporter
</button> </button>
</a> </a>
{{if .ViewState.Archived}} {{if .ViewState.archived}}
<a href="/app/beneficiaries/"> <a href="/app/beneficiaries/">
<button type="button" <button type="button"
class="inline-flex items-center justify-center bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 flex items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue"> class="inline-flex items-center justify-center bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 flex items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">
@@ -40,9 +40,29 @@
</a> </a>
</div> </div>
</div> </div>
{{if $.ViewState.geography_filters_enabled}}
<div class="mt-4 flex justify-end">
<form class="flex flex-row items-center">
{{if $.ViewState.archived}}<input type="hidden" name="archived" value="true" />{{end}}
<label for="beneficiary_address_geo" class="mr-2 text-sm font-medium text-gray-700">Adresse bénéficiaire</label>
<div class="grid grid-cols-1">
<select id="beneficiary_address_geo" name="beneficiary_address_geo" class="col-start-1 row-start-1 w-48 appearance-none rounded-2xl bg-white border border-gray-300 py-2 pr-8 pl-3 text-sm text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue" onchange="this.form.submit()">
<option value="">Toutes les zones</option>
{{range $.ViewState.geography_filters_list}}
{{$geoValue := printf "%s:%s" .layer .code}}
<option value="{{$geoValue}}"{{if eq $.ViewState.filters.beneficiary_address_geo $geoValue}} selected{{end}}>{{.name}}</option>
{{end}}
</select>
<svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-gray-500 sm:size-4">
<path d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" fill-rule="evenodd" />
</svg>
</div>
</form>
</div>
{{end}}
</div> </div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8" x-data="{ <div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8" x-data="{
state: {{.ViewState.JSONWithLimits 0 10}}, state: {{.ViewState.list.JSONWithLimits 0 10}},
current: 0, current: 0,
nb_pages() { nb_pages() {
let nbEl = this.state.count let nbEl = this.state.count

View File

@@ -153,7 +153,7 @@
</label> </label>
<label class="inline-flex items-center cursor-pointer"> <label class="inline-flex items-center cursor-pointer">
<input type="checkbox" x-model="filters.kb" class="rounded border-gray-300 text-co-blue focus:ring-co-blue"> <input type="checkbox" x-model="filters.kb" class="rounded border-gray-300 text-co-blue focus:ring-co-blue">
<span class="ml-2 text-gray-600">Solutions locales</span> <span class="ml-2 text-gray-600">Solutions complémentaires</span>
</label> </label>
<label class="inline-flex items-center cursor-pointer"> <label class="inline-flex items-center cursor-pointer">
<input type="checkbox" x-model="filters.vehicles" class="rounded border-gray-300 text-co-blue focus:ring-co-blue"> <input type="checkbox" x-model="filters.vehicles" class="rounded border-gray-300 text-co-blue focus:ring-co-blue">

View File

@@ -20,6 +20,7 @@
dropLabel: '{{if .Journey}}{{ jsEscape .Journey.PassengerDrop.Properties.label }}{{end}}', dropLabel: '{{if .Journey}}{{ jsEscape .Journey.PassengerDrop.Properties.label }}{{end}}',
pickupDate: '{{if .Journey}}{{ timeFormat .Journey.PassengerPickupDate "02/01/2006 15:04" }}{{end}}', pickupDate: '{{if .Journey}}{{ timeFormat .Journey.PassengerPickupDate "02/01/2006 15:04" }}{{end}}',
status: '{{.Status}}', status: '{{.Status}}',
reason: {{ if .Data.reason }}'{{ jsEscape .Data.reason }}'{{ else }}''{{ end }},
price: '{{if .Journey}}{{ printf "%.2f" (round2 .Journey.Price.Amount) }}{{end}}', price: '{{if .Journey}}{{ printf "%.2f" (round2 .Journey.Price.Amount) }}{{end}}',
currency: '{{if .Journey}}{{.Journey.Price.Currency}}{{end}}', currency: '{{if .Journey}}{{.Journey.Price.Currency}}{{end}}',
motivation: {{ if .Data.motivation }}'{{ jsEscape .Data.motivation }}'{{ else }}''{{ end }}, motivation: {{ if .Data.motivation }}'{{ jsEscape .Data.motivation }}'{{ else }}''{{ end }},
@@ -45,10 +46,10 @@
goToPage(page) { goToPage(page) {
this.currentPage = page; this.currentPage = page;
}, },
getStatusBadge(status) { getStatusBadge(status, reason) {
if (status === 'WAITING_CONFIRMATION') return { class: 'p-1 text-xs bg-gray-300 rounded-xl', text: 'Attente confirmation' }; if (status === 'WAITING_CONFIRMATION') return { class: 'p-1 text-xs bg-gray-300 rounded-xl', text: 'Attente confirmation' };
if (status === 'VALIDATED') return { class: 'p-1 text-xs bg-co-green rounded-xl', text: 'Validé' }; if (status === 'VALIDATED') return { class: 'p-1 text-xs bg-co-green rounded-xl', text: 'Validé' };
if (status === 'CANCELLED') return { class: 'p-1 text-xs bg-co-red text-white rounded-xl', text: 'Annulé' }; if (status === 'CANCELLED') return { class: 'p-1 text-xs bg-co-red text-white rounded-xl', text: reason ? 'Annulé : ' + reason : 'Annulé' };
return { class: '', text: '' }; return { class: '', text: '' };
}, },
guaranteedMotivations: {{ json .ViewState.guaranteed_trip_motivations }}, guaranteedMotivations: {{ json .ViewState.guaranteed_trip_motivations }},
@@ -87,7 +88,7 @@
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.dropLabel"></td> <td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.dropLabel"></td>
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupDate"></td> <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupDate"></td>
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6"> <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
<span :class="getStatusBadge(booking.status).class" x-text="getStatusBadge(booking.status).text"></span> <span :class="getStatusBadge(booking.status, booking.reason).class" x-text="getStatusBadge(booking.status, booking.reason).text"></span>
<template x-if="booking.motivation && isGuaranteedTrip(booking.motivation)"> <template x-if="booking.motivation && isGuaranteedTrip(booking.motivation)">
<div class="mt-4"> <div class="mt-4">
<span class="text-xs p-2 bg-co-green text-white rounded-2xl" x-text="'Trajet garanti : ' + booking.motivation"></span> <span class="text-xs p-2 bg-co-green text-white rounded-2xl" x-text="'Trajet garanti : ' + booking.motivation"></span>

View File

@@ -21,6 +21,7 @@
dropLabel: '{{if .Journey}}{{ jsEscape .Journey.PassengerDrop.Properties.label }}{{end}}', dropLabel: '{{if .Journey}}{{ jsEscape .Journey.PassengerDrop.Properties.label }}{{end}}',
pickupDate: '{{if .Journey}}{{ timeFormat .Journey.PassengerPickupDate "02/01/2006 15:04" }}{{end}}', pickupDate: '{{if .Journey}}{{ timeFormat .Journey.PassengerPickupDate "02/01/2006 15:04" }}{{end}}',
status: '{{.Status}}', status: '{{.Status}}',
reason: {{ if .Data.reason }}'{{ jsEscape .Data.reason }}'{{ else }}''{{ end }},
motivation: {{ if .Data.motivation }}'{{ jsEscape .Data.motivation }}'{{ else }}''{{ end }} motivation: {{ if .Data.motivation }}'{{ jsEscape .Data.motivation }}'{{ else }}''{{ end }}
}{{end}} }{{end}}
], ],
@@ -43,10 +44,10 @@
goToPage(page) { goToPage(page) {
this.currentPage = page; this.currentPage = page;
}, },
getStatusBadge(status) { getStatusBadge(status, reason) {
if (status === 'WAITING_CONFIRMATION') return { class: 'p-1 text-xs bg-gray-300 rounded-xl', text: 'Attente confirmation' }; if (status === 'WAITING_CONFIRMATION') return { class: 'p-1 text-xs bg-gray-300 rounded-xl', text: 'Attente confirmation' };
if (status === 'VALIDATED') return { class: 'p-1 text-xs bg-co-green rounded-xl', text: 'Validé' }; if (status === 'VALIDATED') return { class: 'p-1 text-xs bg-co-green rounded-xl', text: 'Validé' };
if (status === 'CANCELLED') return { class: 'p-1 text-xs bg-co-red text-white rounded-xl', text: 'Annulé' }; if (status === 'CANCELLED') return { class: 'p-1 text-xs bg-co-red text-white rounded-xl', text: reason ? 'Annulé : ' + reason : 'Annulé' };
return { class: '', text: '' }; return { class: '', text: '' };
}, },
guaranteedMotivations: {{ json .ViewState.guaranteed_trip_motivations }}, guaranteedMotivations: {{ json .ViewState.guaranteed_trip_motivations }},
@@ -84,7 +85,7 @@
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.dropLabel"></td> <td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.dropLabel"></td>
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupDate"></td> <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupDate"></td>
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6"> <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
<span :class="getStatusBadge(booking.status).class" x-text="getStatusBadge(booking.status).text"></span> <span :class="getStatusBadge(booking.status, booking.reason).class" x-text="getStatusBadge(booking.status, booking.reason).text"></span>
<template x-if="booking.motivation && isGuaranteedTrip(booking.motivation)"> <template x-if="booking.motivation && isGuaranteedTrip(booking.motivation)">
<div class="mt-4"> <div class="mt-4">
<span class="text-xs p-2 bg-co-green text-white rounded-2xl" x-text="'Trajet garanti : ' + booking.motivation"></span> <span class="text-xs p-2 bg-co-green text-white rounded-2xl" x-text="'Trajet garanti : ' + booking.motivation"></span>