Compare commits
2 Commits
e2e4286858
...
ed726b610f
Author | SHA1 | Date |
---|---|---|
|
ed726b610f | |
|
73d99e7ad7 |
|
@ -99,6 +99,7 @@ views:
|
||||||
- web/layouts/beneficiaries/_partials/beneficiary-organizations.html
|
- web/layouts/beneficiaries/_partials/beneficiary-organizations.html
|
||||||
- web/layouts/beneficiaries/_partials/beneficiary-wallet.html
|
- web/layouts/beneficiaries/_partials/beneficiary-wallet.html
|
||||||
- web/layouts/beneficiaries/_partials/beneficiary-solidarity-transport.html
|
- web/layouts/beneficiaries/_partials/beneficiary-solidarity-transport.html
|
||||||
|
- web/layouts/beneficiaries/_partials/beneficiary-organized-carpool.html
|
||||||
- web/layouts/beneficiaries/display.html
|
- web/layouts/beneficiaries/display.html
|
||||||
update:
|
update:
|
||||||
files:
|
files:
|
||||||
|
@ -345,6 +346,8 @@ views:
|
||||||
- web/layouts/_partials/address_autocomplete.html
|
- web/layouts/_partials/address_autocomplete.html
|
||||||
- web/layouts/organized_carpool/_partials/driver_availabilities.html
|
- web/layouts/organized_carpool/_partials/driver_availabilities.html
|
||||||
- web/layouts/organized_carpool/_partials/driver_documents.html
|
- web/layouts/organized_carpool/_partials/driver_documents.html
|
||||||
|
- web/layouts/organized_carpool/_partials/driver_wallet.html
|
||||||
|
- web/layouts/organized_carpool/_partials/driver_history.html
|
||||||
- web/layouts/organized_carpool/driver_display.html
|
- web/layouts/organized_carpool/driver_display.html
|
||||||
journey:
|
journey:
|
||||||
files:
|
files:
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
{{define "beneficiary_organized_carpool"}}
|
||||||
|
<div class="py-6">
|
||||||
|
{{if .ViewState.organized_carpool_stats}}
|
||||||
|
<div class="py-5 text-center">
|
||||||
|
<p class="text-lg">Trajets réalisés : {{ .ViewState.organized_carpool_stats.count }}</p>
|
||||||
|
<p class="text-lg">Kilomètres réalisés : {{ .ViewState.organized_carpool_stats.km}} km</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<div class="text-center py-5">
|
||||||
|
<a href="/app/journeys/?passengerid={{.ViewState.beneficiary.ID}}" class="inline-flex">
|
||||||
|
<button type="button" class="px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Chercher un trajet</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{if .ViewState.organized_carpool_bookings}}
|
||||||
|
<div class="py-5">
|
||||||
|
<h4 class="text-lg font-medium text-gray-900 mb-4 text-center">Historique des covoiturages solidaires</h4>
|
||||||
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Date</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Conducteur</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Départ</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Arrivée</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Statut</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
|
{{range .ViewState.organized_carpool_bookings}}
|
||||||
|
{{if or (eq .Status.String "CONFIRMED") (eq .Status.String "WAITING_DRIVER_CONFIRMATION")}}
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{timeFormat .PassengerPickupDate.AsTime "02/01/2006 15:04"}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Driver}}
|
||||||
|
<a class="text-co-blue" href="/app/organized-carpool/drivers/{{.Driver.Id}}">
|
||||||
|
{{ (index $.ViewState.organized_carpool_drivers_map .Driver.Id).Data.first_name }}
|
||||||
|
{{ (index $.ViewState.organized_carpool_drivers_map .Driver.Id).Data.last_name }}
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{.PassengerPickupAddress}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{.PassengerDropAddress}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if eq .Status.String "CONFIRMED"}}
|
||||||
|
<span class="p-1 px-2 text-xs bg-co-green rounded-2xl">Confirmé</span>
|
||||||
|
{{else if eq .Status.String "WAITING_DRIVER_CONFIRMATION"}}
|
||||||
|
<span class="p-1 px-2 text-xs bg-gray-300 rounded-2xl">Attente confirmation</span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
<a class="text-co-blue" href="/app/organized-carpool/bookings/{{.Id}}">Voir</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="py-5">
|
||||||
|
<p class="text-sm text-gray-500 text-center">Aucun covoiturage solidaire enregistré</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
|
@ -1,10 +1,75 @@
|
||||||
{{define "beneficiary_solidarity_transport"}}
|
{{define "beneficiary_solidarity_transport"}}
|
||||||
<div class="px-4 py-6 sm:px-6 text-center">
|
<div class="py-6">
|
||||||
<p class="text-center text-lg">Trajets réalisés : {{ .ViewState.solidarity_transport_stats.count }}</p>
|
{{if .ViewState.solidarity_transport_stats}}
|
||||||
<p class="text-center text-lg">Kilomètres réalisés : {{ .ViewState.solidarity_transport_stats.km}} km</p>
|
<div class="py-5 text-center">
|
||||||
|
<p class="text-lg">Trajets réalisés : {{ .ViewState.solidarity_transport_stats.count }}</p>
|
||||||
|
<p class="text-lg">Kilomètres réalisés : {{ .ViewState.solidarity_transport_stats.km}} km</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<a href="/app/journeys/?passengerid={{.ViewState.beneficiary.ID}}" class="inline-flex">
|
<div class="text-center py-5">
|
||||||
<button type="button" class="m-10 w-full px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Chercher un trajet</button>
|
<a href="/app/journeys/?passengerid={{.ViewState.beneficiary.ID}}" class="inline-flex">
|
||||||
</a>
|
<button type="button" class="px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Chercher un trajet</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{if .ViewState.solidarity_transport_bookings}}
|
||||||
|
<div class="py-5">
|
||||||
|
<h4 class="text-lg font-medium text-gray-900 mb-4 text-center">Historique des transports solidaires</h4>
|
||||||
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Date</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Conducteur</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Départ</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Arrivée</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Statut</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
|
{{range .ViewState.solidarity_transport_bookings}}
|
||||||
|
{{if or (eq .Status "VALIDATED") (eq .Status "WAITING_CONFIRMATION")}}
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Journey}}
|
||||||
|
{{timeFormat .Journey.PassengerPickupDate "02/01/2006 15:04"}}
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .DriverId}}
|
||||||
|
<a class="text-co-blue" href="/app/solidarity-transport/drivers/{{.DriverId}}">
|
||||||
|
{{ (index $.ViewState.solidarity_transport_drivers_map .DriverId).Data.first_name }}
|
||||||
|
{{ (index $.ViewState.solidarity_transport_drivers_map .DriverId).Data.last_name }}
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Journey}}{{if .Journey.PassengerPickup}}{{.Journey.PassengerPickup.Properties.label}}{{end}}{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Journey}}{{if .Journey.PassengerDrop}}{{.Journey.PassengerDrop.Properties.label}}{{end}}{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if eq .Status "VALIDATED"}}
|
||||||
|
<span class="p-1 px-2 text-xs bg-co-green rounded-2xl">Validé</span>
|
||||||
|
{{else if eq .Status "WAITING_CONFIRMATION"}}
|
||||||
|
<span class="p-1 px-2 text-xs bg-gray-300 rounded-2xl">Attente confirmation</span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
<a class="text-co-blue" href="/app/solidarity-transport/bookings/{{.Id}}">Voir</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="py-5">
|
||||||
|
<p class="text-sm text-gray-500 text-center">Aucun transport solidaire enregistré</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -189,6 +189,12 @@
|
||||||
Transport solidaire </a>
|
Transport solidaire </a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{if moduleAvailable "organized_carpool"}}
|
||||||
|
<a href="#" @click="tab = 'organized_carpool'"
|
||||||
|
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||||
|
:class="tab == 'organized_carpool' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||||
|
Covoiturage solidaire </a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<a href="#" @click="tab = 'organizations'"
|
<a href="#" @click="tab = 'organizations'"
|
||||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||||
|
@ -208,6 +214,7 @@
|
||||||
<div x-show="tab == 'notes'">{{template "beneficiary_notes" .}}</div>
|
<div x-show="tab == 'notes'">{{template "beneficiary_notes" .}}</div>
|
||||||
<div x-show="tab == 'wallet'">{{template "beneficiary_wallet" .}}</div>
|
<div x-show="tab == 'wallet'">{{template "beneficiary_wallet" .}}</div>
|
||||||
{{if moduleAvailable "solidarity_transport"}}<div x-show="tab == 'solidarity_transport'">{{template "beneficiary_solidarity_transport" .}}</div>{{end}}
|
{{if moduleAvailable "solidarity_transport"}}<div x-show="tab == 'solidarity_transport'">{{template "beneficiary_solidarity_transport" .}}</div>{{end}}
|
||||||
|
{{if moduleAvailable "organized_carpool"}}<div x-show="tab == 'organized_carpool'">{{template "beneficiary_organized_carpool" .}}</div>{{end}}
|
||||||
<div x-show="tab == 'organizations'">{{template "beneficiary_organizations" .}}</div>
|
<div x-show="tab == 'organizations'">{{template "beneficiary_organizations" .}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,11 +22,9 @@
|
||||||
<div class="mt-2 grid grid-cols-1">
|
<div class="mt-2 grid grid-cols-1">
|
||||||
<select id="{{$tab}}_status" name="status" class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white py-1.5 pr-8 pl-3 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-indigo-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:*:bg-gray-800 dark:focus-visible:outline-co-blue" onchange="this.form.submit()">
|
<select id="{{$tab}}_status" name="status" class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white py-1.5 pr-8 pl-3 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-indigo-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:*:bg-gray-800 dark:focus-visible:outline-co-blue" onchange="this.form.submit()">
|
||||||
<option></option>
|
<option></option>
|
||||||
<option value="VALIDATED"{{if eq .filters.status "VALIDATED"}} selected{{end}}>Validé</option>
|
<option value="WAITING_DRIVER_CONFIRMATION"{{if eq .filters.status "WAITING_DRIVER_CONFIRMATION"}} selected{{end}}>Attente confirmation conducteur</option>
|
||||||
<option value="CONFIRMED"{{if eq .filters.status "CONFIRMED"}} selected{{end}}>Confirmé</option>
|
<option value="CONFIRMED"{{if eq .filters.status "CONFIRMED"}} selected{{end}}>Confirmé</option>
|
||||||
<option value="CANCELLED"{{if eq .filters.status "CANCELLED"}} selected{{end}}>Annulé</option>
|
<option value="CANCELLED"{{if eq .filters.status "CANCELLED"}} selected{{end}}>Annulé</option>
|
||||||
<option value="WAITING_CONFIRMATION"{{if eq .filters.status "WAITING_CONFIRMATION"}} selected{{end}}>Attente confirmation</option>
|
|
||||||
<option value="WAITING_DRIVER_CONFIRMATION"{{if eq .filters.status "WAITING_DRIVER_CONFIRMATION"}} selected{{end}}>Attente confirmation conducteur</option>
|
|
||||||
</select>
|
</select>
|
||||||
<svg viewBox="0 0 16 16" fill="currentColor" data-slot="icon" 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 dark:text-gray-400">
|
<svg viewBox="0 0 16 16" fill="currentColor" data-slot="icon" 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 dark:text-gray-400">
|
||||||
<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" />
|
<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" />
|
||||||
|
|
|
@ -4,6 +4,52 @@
|
||||||
{{if eq (len .ViewState.bookings_history) 0}}
|
{{if eq (len .ViewState.bookings_history) 0}}
|
||||||
<div class="m-10 text-center text-gray-600">Aucun trajet dans le passé</div>
|
<div class="m-10 text-center text-gray-600">Aucun trajet dans le passé</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
<div x-data="{
|
||||||
|
bookings: [
|
||||||
|
{{range $index, $booking := .ViewState.bookings_history}}{{if $index}},{{end}}{
|
||||||
|
id: '{{$booking.Id}}',
|
||||||
|
driverId: '{{$booking.Driver.Id}}',
|
||||||
|
driverFirstName: '{{ (index $.ViewState.drivers_map $booking.Driver.Id).Data.first_name }}',
|
||||||
|
driverLastName: '{{ (index $.ViewState.drivers_map $booking.Driver.Id).Data.last_name }}',
|
||||||
|
passengerId: '{{$booking.Passenger.Id}}',
|
||||||
|
passengerFirstName: '{{ (index $.ViewState.passengers_map $booking.Passenger.Id).Data.first_name }}',
|
||||||
|
passengerLastName: '{{ (index $.ViewState.passengers_map $booking.Passenger.Id).Data.last_name }}',
|
||||||
|
pickupAddress: '{{$booking.PassengerPickupAddress}}',
|
||||||
|
dropAddress: '{{$booking.PassengerDropAddress}}',
|
||||||
|
pickupDate: '{{ timeFormat $booking.PassengerPickupDate.AsTime "02/01/2006 15:04" }}',
|
||||||
|
status: '{{$booking.Status.String}}',
|
||||||
|
price: '{{if $booking.Price}}{{ printf "%.2f" (round2 $booking.Price.Amount) }}{{else}}N/A{{end}}',
|
||||||
|
currency: '{{if $booking.Price}}{{$booking.Price.Currency}}{{end}}'
|
||||||
|
}{{end}}
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
itemsPerPage: {{ if .ViewState.trips_items_per_page }}{{ .ViewState.trips_items_per_page }}{{ else }}10{{ end }},
|
||||||
|
get totalPages() {
|
||||||
|
return Math.ceil(this.bookings.length / this.itemsPerPage);
|
||||||
|
},
|
||||||
|
get paginatedBookings() {
|
||||||
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
|
const end = start + this.itemsPerPage;
|
||||||
|
return this.bookings.slice(start, end);
|
||||||
|
},
|
||||||
|
nextPage() {
|
||||||
|
if (this.currentPage < this.totalPages) this.currentPage++;
|
||||||
|
},
|
||||||
|
prevPage() {
|
||||||
|
if (this.currentPage > 1) this.currentPage--;
|
||||||
|
},
|
||||||
|
goToPage(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
},
|
||||||
|
getStatusBadge(status) {
|
||||||
|
if (status === 'WAITING_DRIVER_CONFIRMATION') return { class: 'p-1 text-xs bg-gray-300 rounded-xl', text: 'Attente confirmation' };
|
||||||
|
if (status === 'CONFIRMED') return { class: 'p-1 text-xs bg-co-green rounded-xl', text: 'Confirmé' };
|
||||||
|
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é' };
|
||||||
|
return { class: '', text: '' };
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
|
||||||
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -42,55 +88,86 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200 bg-white">
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
{{range .ViewState.bookings_history}}
|
<template x-for="booking in paginatedBookings" :key="booking.id">
|
||||||
<tr>
|
<tr>
|
||||||
<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">
|
||||||
<a class="text-co-blue" href="/app/organized-carpool/drivers/{{.Driver.Id}}">
|
<a class="text-co-blue" :href="'/app/organized-carpool/drivers/' + booking.driverId">
|
||||||
{{ (index $.ViewState.drivers_map .Driver.Id).Data.first_name }}
|
<span x-text="booking.driverFirstName + ' ' + booking.driverLastName"></span>
|
||||||
{{ (index $.ViewState.drivers_map .Driver.Id).Data.last_name }}
|
</a>
|
||||||
</a>
|
</td>
|
||||||
</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">
|
<a class="text-co-blue" :href="'/app/beneficiaries/' + booking.passengerId">
|
||||||
<a class="text-co-blue" href="/app/beneficiaries/{{.Passenger.Id}}">
|
<span x-text="booking.passengerFirstName + ' ' + booking.passengerLastName"></span>
|
||||||
{{ (index $.ViewState.passengers_map .Passenger.Id).Data.first_name }}
|
</a>
|
||||||
{{ (index $.ViewState.passengers_map .Passenger.Id).Data.last_name }}
|
</td>
|
||||||
</a>
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupAddress"></td>
|
||||||
</td>
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.dropAddress"></td>
|
||||||
<td class="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" x-text="booking.pickupDate"></td>
|
||||||
{{ .PassengerPickupAddress }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<span :class="getStatusBadge(booking.status).class" x-text="getStatusBadge(booking.status).text"></span>
|
||||||
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ .PassengerDropAddress }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<span x-text="booking.price !== 'N/A' ? booking.price + ' ' + booking.currency : 'N/A'"></span>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ timeFormat .PassengerPickupDate.AsTime "02/01/2006 15:04" }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<a class="text-co-blue" :href="'/app/organized-carpool/bookings/' + booking.id">Voir</a>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ if eq .Status.String "WAITING_DRIVER_CONFIRMATION"}}
|
</tr>
|
||||||
<span class="p-1 text-xs bg-gray-300 rounded-xl">Attente confirmation</span>
|
</template>
|
||||||
{{ else if eq .Status.String "CONFIRMED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-green rounded-xl">Confirmé</span>
|
|
||||||
{{ else if eq .Status.String "VALIDATED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-green rounded-xl">Validé</span>
|
|
||||||
{{ else if eq .Status.String "CANCELLED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-red text-white rounded-xl">Annulé</span>
|
|
||||||
{{ end }}
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
|
||||||
{{ if .Price }}
|
|
||||||
{{ printf "%.2f" (round2 .Price.Amount) }} {{ .Price.Currency }}
|
|
||||||
{{ else }}
|
|
||||||
N/A
|
|
||||||
{{ end }}
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
|
||||||
<a class="text-co-blue" href="/app/organized-carpool/bookings/{{.Id}}">
|
|
||||||
Voir
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- Pagination -->
|
||||||
|
<div class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
|
||||||
|
<div class="flex flex-1 justify-between sm:hidden">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Précédent
|
||||||
|
</button>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Suivant
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-700">
|
||||||
|
Affichage de
|
||||||
|
<span class="font-medium" x-text="(currentPage - 1) * itemsPerPage + 1"></span>
|
||||||
|
Ă
|
||||||
|
<span class="font-medium" x-text="Math.min(currentPage * itemsPerPage, bookings.length)"></span>
|
||||||
|
sur
|
||||||
|
<span class="font-medium" x-text="bookings.length"></span>
|
||||||
|
résultats
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Précédent</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<template x-for="page in totalPages" :key="page">
|
||||||
|
<button @click="goToPage(page)"
|
||||||
|
:class="page === currentPage ? 'z-10 bg-co-blue text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-co-blue' : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:outline-offset-0'"
|
||||||
|
class="relative inline-flex items-center px-4 py-2 text-sm font-semibold focus:z-20"
|
||||||
|
x-text="page"></button>
|
||||||
|
</template>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Suivant</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -4,6 +4,53 @@
|
||||||
{{if eq (len .ViewState.bookings) 0}}
|
{{if eq (len .ViewState.bookings) 0}}
|
||||||
<div class="m-10 text-center text-gray-600">Aucun trajet déclaré</div>
|
<div class="m-10 text-center text-gray-600">Aucun trajet déclaré</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
<div x-data="{
|
||||||
|
bookings: [
|
||||||
|
{{range $index, $booking := .ViewState.bookings}}{{if $index}},{{end}}{
|
||||||
|
id: '{{$booking.Id}}',
|
||||||
|
driverId: '{{$booking.Driver.Id}}',
|
||||||
|
driverFirstName: '{{ (index $.ViewState.drivers_map $booking.Driver.Id).Data.first_name }}',
|
||||||
|
driverLastName: '{{ (index $.ViewState.drivers_map $booking.Driver.Id).Data.last_name }}',
|
||||||
|
passengerId: '{{$booking.Passenger.Id}}',
|
||||||
|
passengerFirstName: '{{ (index $.ViewState.passengers_map $booking.Passenger.Id).Data.first_name }}',
|
||||||
|
passengerLastName: '{{ (index $.ViewState.passengers_map $booking.Passenger.Id).Data.last_name }}',
|
||||||
|
pickupAddress: '{{$booking.PassengerPickupAddress}}',
|
||||||
|
dropAddress: '{{$booking.PassengerDropAddress}}',
|
||||||
|
pickupDate: '{{ timeFormat $booking.PassengerPickupDate.AsTime "02/01/2006 15:04" }}',
|
||||||
|
status: '{{$booking.Status.String}}',
|
||||||
|
price: '{{if $booking.Price}}{{ printf "%.2f" (round2 $booking.Price.Amount) }}{{else}}N/A{{end}}',
|
||||||
|
currency: '{{if $booking.Price}}{{$booking.Price.Currency}}{{end}}'
|
||||||
|
}{{end}}
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
itemsPerPage: {{ if .ViewState.trips_items_per_page }}{{ .ViewState.trips_items_per_page }}{{ else }}10{{ end }},
|
||||||
|
get totalPages() {
|
||||||
|
return Math.ceil(this.bookings.length / this.itemsPerPage);
|
||||||
|
},
|
||||||
|
get paginatedBookings() {
|
||||||
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
|
const end = start + this.itemsPerPage;
|
||||||
|
return this.bookings.slice(start, end);
|
||||||
|
},
|
||||||
|
nextPage() {
|
||||||
|
if (this.currentPage < this.totalPages) this.currentPage++;
|
||||||
|
},
|
||||||
|
prevPage() {
|
||||||
|
if (this.currentPage > 1) this.currentPage--;
|
||||||
|
},
|
||||||
|
goToPage(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
},
|
||||||
|
getStatusBadge(status) {
|
||||||
|
if (status === 'WAITING_DRIVER_CONFIRMATION') return { class: 'p-1 text-xs bg-gray-300 rounded-xl', text: 'Attente confirmation' };
|
||||||
|
if (status === 'WAITING_PASSENGER_CONFIRMATION') return { class: 'p-1 text-xs bg-gray-300 rounded-xl', text: 'Attente confirmation passager' };
|
||||||
|
if (status === 'CONFIRMED') return { class: 'p-1 text-xs bg-co-green rounded-xl', text: 'Confirmé' };
|
||||||
|
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é' };
|
||||||
|
return { class: '', text: '' };
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
|
||||||
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -42,57 +89,86 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200 bg-white">
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
{{range .ViewState.bookings}}
|
<template x-for="booking in paginatedBookings" :key="booking.id">
|
||||||
<tr>
|
<tr>
|
||||||
<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">
|
||||||
<a class="text-co-blue" href="/app/organized-carpool/drivers/{{.Driver.Id}}">
|
<a class="text-co-blue" :href="'/app/organized-carpool/drivers/' + booking.driverId">
|
||||||
{{ (index $.ViewState.drivers_map .Driver.Id).Data.first_name }}
|
<span x-text="booking.driverFirstName + ' ' + booking.driverLastName"></span>
|
||||||
{{ (index $.ViewState.drivers_map .Driver.Id).Data.last_name }}
|
</a>
|
||||||
</a>
|
</td>
|
||||||
</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">
|
<a class="text-co-blue" :href="'/app/beneficiaries/' + booking.passengerId">
|
||||||
<a class="text-co-blue" href="/app/beneficiaries/{{.Passenger.Id}}">
|
<span x-text="booking.passengerFirstName + ' ' + booking.passengerLastName"></span>
|
||||||
{{ (index $.ViewState.passengers_map .Passenger.Id).Data.first_name }}
|
</a>
|
||||||
{{ (index $.ViewState.passengers_map .Passenger.Id).Data.last_name }}
|
</td>
|
||||||
</a>
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupAddress"></td>
|
||||||
</td>
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.dropAddress"></td>
|
||||||
<td class="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" x-text="booking.pickupDate"></td>
|
||||||
{{ .PassengerPickupAddress }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<span :class="getStatusBadge(booking.status).class" x-text="getStatusBadge(booking.status).text"></span>
|
||||||
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ .PassengerDropAddress }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<span x-text="booking.price !== 'N/A' ? booking.price + ' ' + booking.currency : 'N/A'"></span>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ timeFormat .PassengerPickupDate.AsTime "02/01/2006 15:04" }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<a class="text-co-blue" :href="'/app/organized-carpool/bookings/' + booking.id">Voir</a>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ if eq .Status.String "WAITING_DRIVER_CONFIRMATION"}}
|
</tr>
|
||||||
<span class="p-1 text-xs bg-gray-300 rounded-xl">Attente confirmation</span>
|
</template>
|
||||||
{{ else if eq .Status.String "WAITING_PASSENGER_CONFIRMATION"}}
|
|
||||||
<span class="p-1 text-xs bg-gray-300 rounded-xl">Attente confirmation passager</span>
|
|
||||||
{{ else if eq .Status.String "CONFIRMED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-green rounded-xl">Confirmé</span>
|
|
||||||
{{ else if eq .Status.String "VALIDATED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-green rounded-xl">Validé</span>
|
|
||||||
{{ else if eq .Status.String "CANCELLED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-red text-white rounded-xl">Annulé</span>
|
|
||||||
{{ end }}
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
|
||||||
{{ if .Price }}
|
|
||||||
{{ printf "%.2f" (round2 .Price.Amount) }} {{ .Price.Currency }}
|
|
||||||
{{ else }}
|
|
||||||
N/A
|
|
||||||
{{ end }}
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
|
||||||
<a class="text-co-blue" href="/app/organized-carpool/bookings/{{.Id}}">
|
|
||||||
Voir
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- Pagination -->
|
||||||
|
<div class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
|
||||||
|
<div class="flex flex-1 justify-between sm:hidden">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Précédent
|
||||||
|
</button>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Suivant
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-700">
|
||||||
|
Affichage de
|
||||||
|
<span class="font-medium" x-text="(currentPage - 1) * itemsPerPage + 1"></span>
|
||||||
|
Ă
|
||||||
|
<span class="font-medium" x-text="Math.min(currentPage * itemsPerPage, bookings.length)"></span>
|
||||||
|
sur
|
||||||
|
<span class="font-medium" x-text="bookings.length"></span>
|
||||||
|
résultats
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Précédent</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<template x-for="page in totalPages" :key="page">
|
||||||
|
<button @click="goToPage(page)"
|
||||||
|
:class="page === currentPage ? 'z-10 bg-co-blue text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-co-blue' : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:outline-offset-0'"
|
||||||
|
class="relative inline-flex items-center px-4 py-2 text-sm font-semibold focus:z-20"
|
||||||
|
x-text="page"></button>
|
||||||
|
</template>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Suivant</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
{{define "organized_carpool_driver_history"}}
|
||||||
|
<div class="py-6">
|
||||||
|
{{if .ViewState.stats}}
|
||||||
|
<div class="py-5 text-center">
|
||||||
|
<p class="text-lg">Covoiturages réalisés : {{ .ViewState.stats.bookings.confirmed }}</p>
|
||||||
|
<p class="text-lg">Kilomètres parcourus : {{ .ViewState.stats.bookings.km }} km</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .ViewState.bookings}}
|
||||||
|
<div class="py-5">
|
||||||
|
<h4 class="text-lg font-medium text-gray-900 mb-4 text-center">Historique des covoiturages</h4>
|
||||||
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Date</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Passager</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Départ</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Arrivée</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
|
{{range .ViewState.bookings}}
|
||||||
|
{{if eq .Status.String "CONFIRMED"}}
|
||||||
|
<tr>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .PassengerPickupDate}}
|
||||||
|
{{timeFormat .PassengerPickupDate.AsTime "02/01/2006 15:04"}}
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Passenger}}
|
||||||
|
<a class="text-co-blue" href="/app/beneficiaries/{{.Passenger.Id}}">
|
||||||
|
{{ (index $.ViewState.beneficiaries_map .Passenger.Id).Data.first_name }}
|
||||||
|
{{ (index $.ViewState.beneficiaries_map .Passenger.Id).Data.last_name }}
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{.PassengerPickupAddress}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{.PassengerDropAddress}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
<a class="text-co-blue" href="/app/organized-carpool/bookings/{{.Id}}">Voir</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="py-5">
|
||||||
|
<p class="text-sm text-gray-500 text-center">Aucun covoiturage enregistré</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
|
@ -0,0 +1,113 @@
|
||||||
|
{{define "organized_carpool_driver_wallet"}}
|
||||||
|
<div class="py-6"
|
||||||
|
x-data="{
|
||||||
|
walletdialog: false
|
||||||
|
}">
|
||||||
|
<div class="py-5 text-center">
|
||||||
|
<p class="text-lg">Solde : {{ printf "%.2f" .ViewState.wallet_balance }} €</p>
|
||||||
|
<button @click="walletdialog = !walletdialog"
|
||||||
|
class="rounded-2xl border border-transparent bg-co-blue px-4 py-2 my-4 mt-8 w-full text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 sm:w-auto">
|
||||||
|
Créditer le compte
|
||||||
|
</button>
|
||||||
|
<div class="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true"
|
||||||
|
x-show="walletdialog">
|
||||||
|
<div class="fixed inset-0 bg-gray-900 opacity-30 transition-opacity"></div>
|
||||||
|
|
||||||
|
<div class="fixed inset-0 z-10 overflow-y-auto">
|
||||||
|
<div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||||
|
<div class="relative transform overflow-hidden rounded-lg bg-white px-4 pt-5 pb-4 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-sm sm:p-6">
|
||||||
|
<div>
|
||||||
|
<div class="mt-3 text-center sm:mt-5">
|
||||||
|
<h3 class="text-lg font-medium leading-6 text-gray-900" id="modal-title">Créditer le compte</h3>
|
||||||
|
<div class="mt-2">
|
||||||
|
<p class="text-sm text-gray-500">Créditer le compte mobilité du conducteur</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form method="POST" action="/app/wallets/{{.ViewState.driver.ID}}/credit" class="my-4">
|
||||||
|
<div class="my-8">
|
||||||
|
<input type="number" step="0.01" id="amount" name="amount" value="0"
|
||||||
|
class="w-full shadow-sm focus:ring-co-blue focus:border-co-blue px-2 p-1 sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
</div>
|
||||||
|
<div class="mt-5 sm:mt-6">
|
||||||
|
<button type="submit" class="inline-flex w-full justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 sm:text-sm">Ajouter</button>
|
||||||
|
</div>
|
||||||
|
<div class="mt-5 sm:mt-6">
|
||||||
|
<button @click="walletdialog=false" type="button" class="inline-flex w-full justify-center max-w-xs bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Annuler</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Wallet Operations History -->
|
||||||
|
{{if .ViewState.driver.Data.wallet_history}}
|
||||||
|
<div class="py-5">
|
||||||
|
<h4 class="text-lg font-medium text-gray-900 mb-4 text-center">Historique des opérations</h4>
|
||||||
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Date</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Crédit</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Débit</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Moyen de paiement</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
|
<!-- Initial Balance Row -->
|
||||||
|
<tr class="bg-gray-50">
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-500 italic sm:pl-6">
|
||||||
|
Solde initial
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">
|
||||||
|
{{if .ViewState.driver.Data.wallet}}{{ printf "%.2f" .ViewState.driver.Data.wallet }} €{{else}}0.00 €{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm text-gray-500 sm:pl-6">
|
||||||
|
-
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm text-gray-500 sm:pl-6">
|
||||||
|
-
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm text-gray-500 sm:pl-6">
|
||||||
|
-
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{range $index, $operation := .ViewState.driver.Data.wallet_history}}
|
||||||
|
<tr>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if $operation.timestamp}}{{timeFormat $operation.timestamp "02/01/2006 15:04"}}{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-green-600 sm:pl-6">
|
||||||
|
{{if $operation.amount}}
|
||||||
|
{{if or (eq $operation.operation_type "credit") (not $operation.operation_type)}}
|
||||||
|
{{ printf "%.2f" $operation.amount }} €
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-red-600 sm:pl-6">
|
||||||
|
{{if eq $operation.operation_type "debit"}}
|
||||||
|
{{ printf "%.2f" $operation.amount }} €
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{$operation.payment_method}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{$operation.description}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="py-5">
|
||||||
|
<p class="text-sm text-gray-500 text-center">Aucune opération enregistrée</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{end}}
|
|
@ -28,6 +28,39 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div x-data="{
|
||||||
|
drivers: [
|
||||||
|
{{range $index, $driver := .ViewState.drivers}}{{if $index}},{{end}}{
|
||||||
|
id: '{{$driver.ID}}',
|
||||||
|
firstName: '{{$driver.Data.first_name}}',
|
||||||
|
lastName: '{{$driver.Data.last_name}}',
|
||||||
|
address: '{{if $driver.Data.address}}{{$driver.Data.address.properties.label}}{{end}}',
|
||||||
|
addressDestination: '{{if $driver.Data.address_destination}}{{$driver.Data.address_destination.properties.label}}{{end}}',
|
||||||
|
phoneNumber: '{{$driver.Data.phone_number}}',
|
||||||
|
validated: {{if carpoolDriverValidatedProfile $driver (carpoolDocuments $driver.ID)}}true{{else}}false{{end}}
|
||||||
|
}{{end}}
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
itemsPerPage: {{ if .ViewState.drivers_items_per_page }}{{ .ViewState.drivers_items_per_page }}{{ else }}10{{ end }},
|
||||||
|
get totalPages() {
|
||||||
|
return Math.ceil(this.drivers.length / this.itemsPerPage);
|
||||||
|
},
|
||||||
|
get paginatedDrivers() {
|
||||||
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
|
const end = start + this.itemsPerPage;
|
||||||
|
return this.drivers.slice(start, end);
|
||||||
|
},
|
||||||
|
nextPage() {
|
||||||
|
if (this.currentPage < this.totalPages) this.currentPage++;
|
||||||
|
},
|
||||||
|
prevPage() {
|
||||||
|
if (this.currentPage > 1) this.currentPage--;
|
||||||
|
},
|
||||||
|
goToPage(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
|
||||||
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -58,27 +91,76 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200 bg-white">
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
{{ range .ViewState.drivers }}
|
<template x-for="driver in paginatedDrivers" :key="driver.id">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">{{ .Data.first_name }} {{ .Data.last_name }}</td>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="driver.firstName + ' ' + driver.lastName"></td>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">{{if .Data.address}}{{.Data.address.properties.label}}{{end}}</td>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="driver.address"></td>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">{{if .Data.address_destination}}{{.Data.address_destination.properties.label}}{{end}}</td>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="driver.addressDestination"></td>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">{{ .Data.phone_number }}</td>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="driver.phoneNumber"></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">
|
||||||
{{if carpoolDriverValidatedProfile . (carpoolDocuments .ID) }}
|
<span x-show="driver.validated" class="p-1 px-2 text-xs bg-co-green rounded-2xl">Oui</span>
|
||||||
<span class="p-1 px-2 text-xs bg-co-green rounded-2xl">Oui</span>
|
<span x-show="!driver.validated" class="p-1 px-2 text-xs bg-co-red text-white rounded-2xl">Non</span>
|
||||||
{{else}}
|
</td>
|
||||||
<span class="p-1 px-2 text-xs bg-co-red text-white rounded-2xl">Non</span>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
{{end}}
|
<a class="text-co-blue hover:text-co-blue" :href="'/app/organized-carpool/drivers/' + driver.id">
|
||||||
</td>
|
Voir
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</a>
|
||||||
<a class="text-co-blue hover:text-co-blue"
|
</td>
|
||||||
href="/app/organized-carpool/drivers/{{.ID}}">
|
</tr>
|
||||||
Voir
|
</template>
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- Pagination -->
|
||||||
|
<div class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
|
||||||
|
<div class="flex flex-1 justify-between sm:hidden">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Précédent
|
||||||
|
</button>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Suivant
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-700">
|
||||||
|
Affichage de
|
||||||
|
<span class="font-medium" x-text="(currentPage - 1) * itemsPerPage + 1"></span>
|
||||||
|
Ă
|
||||||
|
<span class="font-medium" x-text="Math.min(currentPage * itemsPerPage, drivers.length)"></span>
|
||||||
|
sur
|
||||||
|
<span class="font-medium" x-text="drivers.length"></span>
|
||||||
|
résultats
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Précédent</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<template x-for="page in totalPages" :key="page">
|
||||||
|
<button @click="goToPage(page)"
|
||||||
|
:class="page === currentPage ? 'z-10 bg-co-blue text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-co-blue' : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:outline-offset-0'"
|
||||||
|
class="relative inline-flex items-center px-4 py-2 text-sm font-semibold focus:z-20"
|
||||||
|
x-text="page"></button>
|
||||||
|
</template>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Suivant</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -134,6 +134,14 @@
|
||||||
{{ timeFormat .ViewState.booking.PassengerPickupDate.AsTime "02/01/2006 15:04" }}
|
{{ timeFormat .ViewState.booking.PassengerPickupDate.AsTime "02/01/2006 15:04" }}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
{{if .ViewState.booking.Distance}}
|
||||||
|
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||||
|
<dt class="text-sm font-medium text-gray-500">Distance</dt>
|
||||||
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||||
|
{{ .ViewState.booking.Distance }} km
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||||
<dt class="text-sm font-medium text-gray-500">Prix (passager)</dt>
|
<dt class="text-sm font-medium text-gray-500">Prix (passager)</dt>
|
||||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section aria-labelledby="functionalities-title" x-data="{
|
<section aria-labelledby="functionalities-title" x-data="{
|
||||||
tab: 'documents',
|
tab: '{{ if .ViewState.tab }}{{ .ViewState.tab }}{{ else }}documents{{ end }}',
|
||||||
to(event) {
|
to(event) {
|
||||||
this.tab = event.target.value
|
this.tab = event.target.value
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,10 @@
|
||||||
<option value="events">Dispositifs</option> -->
|
<option value="events">Dispositifs</option> -->
|
||||||
|
|
||||||
<option value="documents">Documents</option>
|
<option value="documents">Documents</option>
|
||||||
|
|
||||||
|
<option value="wallet">Compte mobilité</option>
|
||||||
|
|
||||||
|
<option value="history">Covoiturage solidaire</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden sm:block">
|
<div class="hidden sm:block">
|
||||||
|
@ -134,12 +138,24 @@
|
||||||
:class="tab == 'documents' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
:class="tab == 'documents' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||||
Documents </a>
|
Documents </a>
|
||||||
|
|
||||||
|
<a href="#" @click="tab = 'wallet'"
|
||||||
|
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||||
|
:class="tab == 'wallet' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||||
|
Compte mobilité </a>
|
||||||
|
|
||||||
|
<a href="#" @click="tab = 'history'"
|
||||||
|
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||||
|
:class="tab == 'history' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||||
|
Covoiturage solidaire </a>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div x-show="tab == 'documents'">{{template "driver_files" .}}</div>
|
<div x-show="tab == 'documents'">{{template "driver_files" .}}</div>
|
||||||
|
<div x-show="tab == 'wallet'">{{template "organized_carpool_driver_wallet" .}}</div>
|
||||||
|
<div x-show="tab == 'history'">{{template "organized_carpool_driver_history" .}}</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,87 +4,145 @@
|
||||||
{{if eq (len .ViewState.bookings_history) 0}}
|
{{if eq (len .ViewState.bookings_history) 0}}
|
||||||
<div class="m-10 text-center text-gray-600">Aucun trajet dans le passé</div>
|
<div class="m-10 text-center text-gray-600">Aucun trajet dans le passé</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
<div x-data="{
|
||||||
|
bookings: [
|
||||||
|
{{range $index, $booking := .ViewState.bookings_history}}{{if $index}},{{end}}{
|
||||||
|
id: '{{$booking.Id}}',
|
||||||
|
driverId: '{{$booking.DriverId}}',
|
||||||
|
driverFirstName: '{{ (index $.ViewState.drivers_map $booking.DriverId).Data.first_name }}',
|
||||||
|
driverLastName: '{{ (index $.ViewState.drivers_map $booking.DriverId).Data.last_name }}',
|
||||||
|
passengerId: '{{$booking.PassengerId}}',
|
||||||
|
passengerFirstName: '{{ (index $.ViewState.passengers_map $booking.PassengerId).Data.first_name }}',
|
||||||
|
passengerLastName: '{{ (index $.ViewState.passengers_map $booking.PassengerId).Data.last_name }}',
|
||||||
|
pickupLabel: '{{$booking.Journey.PassengerPickup.Properties.label}}',
|
||||||
|
dropLabel: '{{$booking.Journey.PassengerDrop.Properties.label}}',
|
||||||
|
pickupDate: '{{ $booking.Journey.PassengerPickupDate.Format "02/01/2006 15:04" }}',
|
||||||
|
status: '{{$booking.Status}}',
|
||||||
|
price: '{{ printf "%.2f" (round2 $booking.Journey.Price.Amount) }}',
|
||||||
|
currency: '{{$booking.Journey.Price.Currency}}'
|
||||||
|
}{{end}}
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
itemsPerPage: {{ if .ViewState.trips_items_per_page }}{{ .ViewState.trips_items_per_page }}{{ else }}10{{ end }},
|
||||||
|
get totalPages() {
|
||||||
|
return Math.ceil(this.bookings.length / this.itemsPerPage);
|
||||||
|
},
|
||||||
|
get paginatedBookings() {
|
||||||
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
|
const end = start + this.itemsPerPage;
|
||||||
|
return this.bookings.slice(start, end);
|
||||||
|
},
|
||||||
|
nextPage() {
|
||||||
|
if (this.currentPage < this.totalPages) this.currentPage++;
|
||||||
|
},
|
||||||
|
prevPage() {
|
||||||
|
if (this.currentPage > 1) this.currentPage--;
|
||||||
|
},
|
||||||
|
goToPage(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
},
|
||||||
|
getStatusBadge(status) {
|
||||||
|
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 === 'CANCELLED') return { class: 'p-1 text-xs bg-co-red text-white rounded-xl', text: 'Annulé' };
|
||||||
|
return { class: '', text: '' };
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
|
||||||
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col"
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Conducteur</th>
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Passager</th>
|
||||||
Conducteur
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Départ</th>
|
||||||
</th>
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Destination</th>
|
||||||
<th scope="col"
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Date</th>
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Statut</th>
|
||||||
Passager
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Prix</th>
|
||||||
</th>
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"> </th>
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Départ
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Destination
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Date
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Statut
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Prix
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
|
|
||||||
</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200 bg-white">
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
{{range .ViewState.bookings_history}}
|
<template x-for="booking in paginatedBookings" :key="booking.id">
|
||||||
<tr>
|
<tr>
|
||||||
<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">
|
||||||
<a class="text-co-blue" href="/app/solidarity-transport/drivers/{{.DriverId}}">
|
<a class="text-co-blue" :href="'/app/solidarity-transport/drivers/' + booking.driverId">
|
||||||
{{ (index $.ViewState.drivers_map .DriverId).Data.first_name }}
|
<span x-text="booking.driverFirstName + ' ' + booking.driverLastName"></span>
|
||||||
{{ (index $.ViewState.drivers_map .DriverId).Data.last_name }}
|
</a>
|
||||||
</a>
|
</td>
|
||||||
</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">
|
<a class="text-co-blue" :href="'/app/beneficiaries/' + booking.passengerId">
|
||||||
<a class="text-co-blue" href="/app/beneficiaries/{{.PassengerId}}">
|
<span x-text="booking.passengerFirstName + ' ' + booking.passengerLastName"></span>
|
||||||
{{ (index $.ViewState.passengers_map .PassengerId).Data.first_name }}
|
</a>
|
||||||
{{ (index $.ViewState.passengers_map .PassengerId).Data.last_name }}
|
</td>
|
||||||
</a>
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupLabel"></td>
|
||||||
</td>
|
<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">
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupDate"></td>
|
||||||
{{ .Journey.PassengerPickup.Properties.label }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<span :class="getStatusBadge(booking.status).class" x-text="getStatusBadge(booking.status).text"></span>
|
||||||
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ .Journey.PassengerDrop.Properties.label }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<span x-text="booking.price + ' ' + booking.currency"></span>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ .Journey.PassengerPickupDate.Format "02/01/2006 15:04" }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<a class="text-co-blue" :href="'/app/solidarity-transport/bookings/' + booking.id">Voir</a>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</td>
|
||||||
{{ if eq .Status "WAITING_CONFIRMATION"}}
|
</tr>
|
||||||
<span class="p-1 text-xs bg-gray-300 rounded-xl">Attente confirmation</span>
|
</template>
|
||||||
{{ else if eq .Status "VALIDATED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-green rounded-xl">Validé</span>
|
|
||||||
{{ else if eq .Status "CANCELLED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-red text-white rounded-xl">Annulé</span>
|
|
||||||
{{ end }}
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
|
||||||
{{ printf "%.2f" (round2 .Journey.Price.Amount) }} {{ .Journey.Price.Currency }}
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
|
||||||
<a class="text-co-blue" href="/app/solidarity-transport/bookings/{{.Id}}">
|
|
||||||
Voir
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- Pagination -->
|
||||||
|
<div class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
|
||||||
|
<div class="flex flex-1 justify-between sm:hidden">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Précédent
|
||||||
|
</button>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Suivant
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-700">
|
||||||
|
Affichage de
|
||||||
|
<span class="font-medium" x-text="(currentPage - 1) * itemsPerPage + 1"></span>
|
||||||
|
Ă
|
||||||
|
<span class="font-medium" x-text="Math.min(currentPage * itemsPerPage, bookings.length)"></span>
|
||||||
|
sur
|
||||||
|
<span class="font-medium" x-text="bookings.length"></span>
|
||||||
|
résultats
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Précédent</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<template x-for="page in totalPages" :key="page">
|
||||||
|
<button @click="goToPage(page)"
|
||||||
|
:class="page === currentPage ? 'z-10 bg-co-blue text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-co-blue' : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:outline-offset-0'"
|
||||||
|
class="relative inline-flex items-center px-4 py-2 text-sm font-semibold focus:z-20"
|
||||||
|
x-text="page"></button>
|
||||||
|
</template>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Suivant</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -5,81 +5,148 @@
|
||||||
{{if eq (len .ViewState.bookings) 0}}
|
{{if eq (len .ViewState.bookings) 0}}
|
||||||
<div class="m-10 text-center text-gray-600">Aucun trajet déclaré</div>
|
<div class="m-10 text-center text-gray-600">Aucun trajet déclaré</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
<div x-data="{
|
||||||
|
bookings: [
|
||||||
|
{{range $index, $booking := .ViewState.bookings}}{{if $index}},{{end}}{
|
||||||
|
id: '{{$booking.Id}}',
|
||||||
|
driverId: '{{$booking.DriverId}}',
|
||||||
|
driverFirstName: '{{ (index $.ViewState.drivers_map $booking.DriverId).Data.first_name }}',
|
||||||
|
driverLastName: '{{ (index $.ViewState.drivers_map $booking.DriverId).Data.last_name }}',
|
||||||
|
passengerId: '{{$booking.PassengerId}}',
|
||||||
|
passengerFirstName: '{{ (index $.ViewState.passengers_map $booking.PassengerId).Data.first_name }}',
|
||||||
|
passengerLastName: '{{ (index $.ViewState.passengers_map $booking.PassengerId).Data.last_name }}',
|
||||||
|
pickupLabel: '{{$booking.Journey.PassengerPickup.Properties.label}}',
|
||||||
|
dropLabel: '{{$booking.Journey.PassengerDrop.Properties.label}}',
|
||||||
|
pickupDate: '{{ timeFormat $booking.Journey.PassengerPickupDate "02/01/2006 15:04" }}',
|
||||||
|
status: '{{$booking.Status}}',
|
||||||
|
motivation: '{{if $booking.Data.motivation}}{{$booking.Data.motivation}}{{end}}'
|
||||||
|
}{{end}}
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
itemsPerPage: {{ if .ViewState.trips_items_per_page }}{{ .ViewState.trips_items_per_page }}{{ else }}10{{ end }},
|
||||||
|
get totalPages() {
|
||||||
|
return Math.ceil(this.bookings.length / this.itemsPerPage);
|
||||||
|
},
|
||||||
|
get paginatedBookings() {
|
||||||
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
|
const end = start + this.itemsPerPage;
|
||||||
|
return this.bookings.slice(start, end);
|
||||||
|
},
|
||||||
|
nextPage() {
|
||||||
|
if (this.currentPage < this.totalPages) this.currentPage++;
|
||||||
|
},
|
||||||
|
prevPage() {
|
||||||
|
if (this.currentPage > 1) this.currentPage--;
|
||||||
|
},
|
||||||
|
goToPage(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
},
|
||||||
|
getStatusBadge(status) {
|
||||||
|
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 === 'CANCELLED') return { class: 'p-1 text-xs bg-co-red text-white rounded-xl', text: 'Annulé' };
|
||||||
|
return { class: '', text: '' };
|
||||||
|
},
|
||||||
|
isGuaranteedTrip(motivation) {
|
||||||
|
return motivation === 'Santé' || motivation === 'Insertion' || motivation === 'Administratif';
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
|
||||||
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col"
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Conducteur</th>
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Passager</th>
|
||||||
Conducteur
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Départ</th>
|
||||||
</th>
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Destination</th>
|
||||||
<th scope="col"
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Date</th>
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Statut</th>
|
||||||
Passager
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"> </th>
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Départ
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Destination
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Date
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
Statut
|
|
||||||
</th>
|
|
||||||
<th scope="col"
|
|
||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
|
||||||
|
|
||||||
</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200 bg-white">
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
{{range .ViewState.bookings}}
|
<template x-for="booking in paginatedBookings" :key="booking.id">
|
||||||
<tr>
|
<tr>
|
||||||
<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">
|
||||||
<a class="text-co-blue" href="/app/solidarity-transport/drivers/{{.DriverId}}">
|
<a class="text-co-blue" :href="'/app/solidarity-transport/drivers/' + booking.driverId">
|
||||||
{{ (index $.ViewState.drivers_map .DriverId).Data.first_name }}
|
<span x-text="booking.driverFirstName + ' ' + booking.driverLastName"></span>
|
||||||
{{ (index $.ViewState.drivers_map .DriverId).Data.last_name }}
|
</a>
|
||||||
</a>
|
</td>
|
||||||
</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">
|
<a class="text-co-blue" :href="'/app/beneficiaries/' + booking.passengerId">
|
||||||
<a class="text-co-blue" href="/app/beneficiaries/{{.PassengerId}}">
|
<span x-text="booking.passengerFirstName + ' ' + booking.passengerLastName"></span>
|
||||||
{{ (index $.ViewState.passengers_map .PassengerId).Data.first_name }}
|
</a>
|
||||||
{{ (index $.ViewState.passengers_map .PassengerId).Data.last_name }}
|
</td>
|
||||||
</a>
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupLabel"></td>
|
||||||
</td>
|
<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">
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="booking.pickupDate"></td>
|
||||||
{{ .Journey.PassengerPickup.Properties.label }}
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
</td>
|
<span :class="getStatusBadge(booking.status).class" x-text="getStatusBadge(booking.status).text"></span>
|
||||||
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
<template x-if="booking.motivation && isGuaranteedTrip(booking.motivation)">
|
||||||
{{ .Journey.PassengerDrop.Properties.label }}
|
<div class="mt-4">
|
||||||
</td>
|
<span class="text-xs p-2 bg-co-green text-white rounded-2xl" x-text="'Trajet garanti : ' + booking.motivation"></span>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</div>
|
||||||
{{ timeFormat .Journey.PassengerPickupDate "02/01/2006 15:04" }}
|
</template>
|
||||||
</td>
|
</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">
|
||||||
{{ if eq .Status "WAITING_CONFIRMATION"}}
|
<a class="text-co-blue" :href="'/app/solidarity-transport/bookings/' + booking.id">Voir</a>
|
||||||
<span class="p-1 text-xs bg-gray-300 rounded-xl">Attente confirmation</span>
|
</td>
|
||||||
{{ else if eq .Status "VALIDATED"}}
|
</tr>
|
||||||
<span class="p-1 text-xs bg-co-green rounded-xl">Validé</span>
|
</template>
|
||||||
{{ else if eq .Status "CANCELLED"}}
|
|
||||||
<span class="p-1 text-xs bg-co-red text-white rounded-xl">Annulé</span>
|
|
||||||
{{ end }}
|
|
||||||
{{if and .Data.motivation (or (or (eq .Data.motivation "Santé") (eq .Data.motivation "Insertion")) (eq .Data.motivation "Administratif"))}}<div class="mt-4"><span class="text-xs p-2 bg-co-green text-white rounded-2xl">Trajet garanti : {{.Data.motivation}}</span></div>{{end}}
|
|
||||||
</td>
|
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
|
||||||
<a class="text-co-blue" href="/app/solidarity-transport/bookings/{{.Id}}">
|
|
||||||
Voir
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- Pagination -->
|
||||||
|
<div class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
|
||||||
|
<div class="flex flex-1 justify-between sm:hidden">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Précédent
|
||||||
|
</button>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Suivant
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-700">
|
||||||
|
Affichage de
|
||||||
|
<span class="font-medium" x-text="(currentPage - 1) * itemsPerPage + 1"></span>
|
||||||
|
Ă
|
||||||
|
<span class="font-medium" x-text="Math.min(currentPage * itemsPerPage, bookings.length)"></span>
|
||||||
|
sur
|
||||||
|
<span class="font-medium" x-text="bookings.length"></span>
|
||||||
|
résultats
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Précédent</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<template x-for="page in totalPages" :key="page">
|
||||||
|
<button @click="goToPage(page)"
|
||||||
|
:class="page === currentPage ? 'z-10 bg-co-blue text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-co-blue' : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:outline-offset-0'"
|
||||||
|
class="relative inline-flex items-center px-4 py-2 text-sm font-semibold focus:z-20"
|
||||||
|
x-text="page"></button>
|
||||||
|
</template>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Suivant</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -1,7 +1,69 @@
|
||||||
{{define "driver_history"}}
|
{{define "driver_history"}}
|
||||||
<div class="px-4 py-6 sm:px-6 text-center">
|
<div class="py-6">
|
||||||
<p class="text-center text-lg">Trajets réalisés : {{ .ViewState.stats.bookings.count }}</p>
|
{{if .ViewState.stats}}
|
||||||
<p class="text-center text-lg">Kilomètres réalisés : {{ .ViewState.stats.bookings.km}} km</p>
|
<div class="py-5 text-center">
|
||||||
|
<p class="text-lg">Trajets réalisés : {{ .ViewState.stats.bookings.count }}</p>
|
||||||
|
<p class="text-lg">Kilomètres réalisés : {{ .ViewState.stats.bookings.km}} km</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .ViewState.bookings}}
|
||||||
|
<div class="py-5">
|
||||||
|
<h4 class="text-lg font-medium text-gray-900 mb-4 text-center">Historique des transports solidaires</h4>
|
||||||
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
|
<thead class="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Date</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Passager</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Départ</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Arrivée</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Statut</th>
|
||||||
|
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
|
{{range .ViewState.bookings}}
|
||||||
|
{{if or (eq .Status "VALIDATED") (eq .Status "WAITING_CONFIRMATION")}}
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Journey}}
|
||||||
|
{{timeFormat .Journey.PassengerPickupDate "02/01/2006 15:04"}}
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .PassengerId}}
|
||||||
|
<a class="text-co-blue" href="/app/beneficiaries/{{.PassengerId}}">
|
||||||
|
{{ (index $.ViewState.beneficiaries_map .PassengerId).Data.first_name }}
|
||||||
|
{{ (index $.ViewState.beneficiaries_map .PassengerId).Data.last_name }}
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Journey}}{{if .Journey.PassengerPickup}}{{.Journey.PassengerPickup.Properties.label}}{{end}}{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if .Journey}}{{if .Journey.PassengerDrop}}{{.Journey.PassengerDrop.Properties.label}}{{end}}{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
{{if eq .Status "VALIDATED"}}
|
||||||
|
<span class="p-1 px-2 text-xs bg-co-green rounded-2xl">Validé</span>
|
||||||
|
{{else if eq .Status "WAITING_CONFIRMATION"}}
|
||||||
|
<span class="p-1 px-2 text-xs bg-gray-300 rounded-2xl">Attente confirmation</span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
|
<a class="text-co-blue" href="/app/solidarity-transport/bookings/{{.Id}}">Voir</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="py-5">
|
||||||
|
<p class="text-sm text-gray-500 text-center">Aucun transport solidaire enregistré</p>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -27,6 +27,38 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div x-data="{
|
||||||
|
drivers: [
|
||||||
|
{{range $index, $driver := .ViewState.drivers}}{{if $index}},{{end}}{
|
||||||
|
id: '{{$driver.ID}}',
|
||||||
|
firstName: '{{$driver.Data.first_name}}',
|
||||||
|
lastName: '{{$driver.Data.last_name}}',
|
||||||
|
address: '{{if $driver.Data.address}}{{$driver.Data.address.properties.label}}{{end}}',
|
||||||
|
phoneNumber: '{{$driver.Data.phone_number}}',
|
||||||
|
validated: {{if solidarityDriverValidatedProfile $driver (solidarityDocuments $driver.ID)}}true{{else}}false{{end}}
|
||||||
|
}{{end}}
|
||||||
|
],
|
||||||
|
currentPage: 1,
|
||||||
|
itemsPerPage: {{ if .ViewState.drivers_items_per_page }}{{ .ViewState.drivers_items_per_page }}{{ else }}10{{ end }},
|
||||||
|
get totalPages() {
|
||||||
|
return Math.ceil(this.drivers.length / this.itemsPerPage);
|
||||||
|
},
|
||||||
|
get paginatedDrivers() {
|
||||||
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
|
const end = start + this.itemsPerPage;
|
||||||
|
return this.drivers.slice(start, end);
|
||||||
|
},
|
||||||
|
nextPage() {
|
||||||
|
if (this.currentPage < this.totalPages) this.currentPage++;
|
||||||
|
},
|
||||||
|
prevPage() {
|
||||||
|
if (this.currentPage > 1) this.currentPage--;
|
||||||
|
},
|
||||||
|
goToPage(page) {
|
||||||
|
this.currentPage = page;
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
|
||||||
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
<table class="min-w-full divide-y divide-gray-300 border-gray-300 border-t-1">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -53,26 +85,75 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200 bg-white">
|
<tbody class="divide-y divide-gray-200 bg-white">
|
||||||
{{ range .ViewState.drivers }}
|
<template x-for="driver in paginatedDrivers" :key="driver.id">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">{{ .Data.first_name }} {{ .Data.last_name }}</td>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="driver.firstName + ' ' + driver.lastName"></td>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">{{if .Data.address}}{{.Data.address.properties.label}}{{end}}</td>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="driver.address"></td>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">{{ .Data.phone_number }}</td>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6" x-text="driver.phoneNumber"></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">
|
||||||
{{if solidarityDriverValidatedProfile . (solidarityDocuments .ID) }}
|
<span x-show="driver.validated" class="p-1 px-2 text-xs bg-co-green rounded-2xl">Oui</span>
|
||||||
<span class="p-1 px-2 text-xs bg-co-green rounded-2xl">Oui</span>
|
<span x-show="!driver.validated" class="p-1 px-2 text-xs bg-co-red text-white rounded-2xl">Non</span>
|
||||||
{{else}}
|
</td>
|
||||||
<span class="p-1 px-2 text-xs bg-co-red text-white rounded-2xl">Non</span>
|
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||||
{{end}}
|
<a class="text-co-blue hover:text-co-blue" :href="'/app/solidarity-transport/drivers/' + driver.id">
|
||||||
</td>
|
Voir
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
</a>
|
||||||
<a class="text-co-blue hover:text-co-blue"
|
</td>
|
||||||
href="/app/solidarity-transport/drivers/{{.ID}}">
|
</tr>
|
||||||
Voir
|
</template>
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- Pagination -->
|
||||||
|
<div class="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
|
||||||
|
<div class="flex flex-1 justify-between sm:hidden">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Précédent
|
||||||
|
</button>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
Suivant
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-700">
|
||||||
|
Affichage de
|
||||||
|
<span class="font-medium" x-text="(currentPage - 1) * itemsPerPage + 1"></span>
|
||||||
|
Ă
|
||||||
|
<span class="font-medium" x-text="Math.min(currentPage * itemsPerPage, drivers.length)"></span>
|
||||||
|
sur
|
||||||
|
<span class="font-medium" x-text="drivers.length"></span>
|
||||||
|
résultats
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
|
<button @click="prevPage()" :disabled="currentPage === 1"
|
||||||
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Précédent</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<template x-for="page in totalPages" :key="page">
|
||||||
|
<button @click="goToPage(page)"
|
||||||
|
:class="page === currentPage ? 'z-10 bg-co-blue text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-co-blue' : 'text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:outline-offset-0'"
|
||||||
|
class="relative inline-flex items-center px-4 py-2 text-sm font-semibold focus:z-20"
|
||||||
|
x-text="page"></button>
|
||||||
|
</template>
|
||||||
|
<button @click="nextPage()" :disabled="currentPage === totalPages"
|
||||||
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
<span class="sr-only">Suivant</span>
|
||||||
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section aria-labelledby="functionalities-title" x-data="{
|
<section aria-labelledby="functionalities-title" x-data="{
|
||||||
tab: 'documents',
|
tab: '{{ if .ViewState.tab }}{{ .ViewState.tab }}{{ else }}documents{{ end }}',
|
||||||
to(event) {
|
to(event) {
|
||||||
this.tab = event.target.value
|
this.tab = event.target.value
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@
|
||||||
|
|
||||||
<option value="wallet">Compte mobilité</option>
|
<option value="wallet">Compte mobilité</option>
|
||||||
|
|
||||||
<option value="history">Historique</option>
|
<option value="history">Transports solidaires</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden sm:block">
|
<div class="hidden sm:block">
|
||||||
|
@ -197,7 +197,7 @@
|
||||||
<a href="#" @click="tab = 'history'"
|
<a href="#" @click="tab = 'history'"
|
||||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||||
:class="tab == 'history' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
:class="tab == 'history' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||||
Transport solidaires </a>
|
Transports solidaires </a>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<div class="max-w-7xl m-auto px-4 sm:px-6 md:px-8 flex flex-col justify-items-center">
|
<div class="max-w-7xl m-auto px-4 sm:px-6 md:px-8 flex flex-col justify-items-center">
|
||||||
{{if .ViewState.passenger}}
|
{{if .ViewState.passenger}}
|
||||||
{{if lt .ViewState.passenger_wallet_balance .ViewState.pricing_result.passenger.Amount}}
|
{{if lt .ViewState.passenger_wallet_balance .ViewState.pricing_result.passenger.Amount}}
|
||||||
<p class="text-xl text-co-red text-center p-4">Le solde du compte mobilité est insuffisant.</p>
|
<p class="text-xl text-co-red text-center p-4">Le solde du compte mobilité est insuffisant. <a href="/app/beneficiaries/{{.ViewState.passenger.ID}}?tab=wallet" class="underline text-co-blue">Créditer le compte</a></p>
|
||||||
{{end}}
|
{{end}}
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{{if not .ViewState.driver_journey.Noreturn}}
|
{{if not .ViewState.driver_journey.Noreturn}}
|
||||||
|
|
|
@ -138,6 +138,48 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{if .ViewState.vehicle_optional_fields}}
|
||||||
|
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||||
|
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||||
|
<div class="md:col-span-1">
|
||||||
|
<h3 class="text-lg font-medium leading-6 text-gray-900">Autres propriétés</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-500">Informations complémentaires sur le véhicule</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||||
|
<div class="grid grid-cols-6 gap-6">
|
||||||
|
{{range .ViewState.vehicle_optional_fields}}
|
||||||
|
<div class="col-span-6 sm:col-span-3">
|
||||||
|
<label for="{{.name}}" class="block text-sm font-medium text-gray-700">{{.label}}</label>
|
||||||
|
{{if eq .type "select"}}
|
||||||
|
<div class="sm:mt-0 sm:col-span-2">
|
||||||
|
<select id="{{.name}}" name="{{.name}}"
|
||||||
|
class="p-2 max-w-lg mt-1 block focus:ring-co-blue focus:border-co-blue w-full shadow-sm sm:max-w-xs sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{range .options}}
|
||||||
|
<option value="{{.value}}">{{.label}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{else if eq .type "textarea"}}
|
||||||
|
<textarea id="{{.name}}" name="{{.name}}" rows="3"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl"></textarea>
|
||||||
|
{{else if eq .type "date"}}
|
||||||
|
<input type="date" id="{{.name}}" name="{{.name}}"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{else if eq .type "number"}}
|
||||||
|
<input type="number" id="{{.name}}" name="{{.name}}"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{else}}
|
||||||
|
<input type="text" id="{{.name}}" name="{{.name}}"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
||||||
<a href="/app/vehicles-management/">
|
<a href="/app/vehicles-management/">
|
||||||
|
|
|
@ -170,26 +170,37 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<section aria-labelledby="timeline-title" class="lg:col-start-3 lg:col-span-1">
|
{{if .ViewState.vehicle_optional_fields}}
|
||||||
<div class="bg-white px-4 py-5 shadow sm:rounded-lg sm:px-6">
|
<section aria-labelledby="vehicle-other-properties-title" class="lg:col-start-3 lg:col-span-1">
|
||||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900">Réservations à venir</h2>
|
<div class="bg-white shadow sm:rounded-lg">
|
||||||
{{if eq (len .ViewState.vehicle.Bookings) 0}}
|
<div class="px-4 py-5 sm:px-6">
|
||||||
<p class="p-12 text-gray-500 text-center text-md">Aucune réservation à venir</p>
|
<h2 id="vehicle-other-properties-title" class="text-lg leading-6 font-medium text-gray-900">Autres propriétés</h2>
|
||||||
{{end}}
|
<p class="mt-1 max-w-2xl text-sm text-gray-500">Informations complémentaires sur le véhicule</p>
|
||||||
<ul role="list" class="divide-y divide-gray-200">
|
</div>
|
||||||
{{range .ViewState.vehicle.Bookings}}
|
<div class="border-t border-gray-200 px-4 py-5 sm:px-6">
|
||||||
<li class="py-4 flex">
|
<dl class="space-y-4">
|
||||||
<div class="ml-3">
|
{{range .ViewState.vehicle_optional_fields}}
|
||||||
<a href="/app/vehicles-management/bookings/{{.ID}}" class="hover:bg-gray-200">
|
{{if index $.ViewState.vehicle.Data .name}}
|
||||||
<p class="text-sm font-medium text-gray-900">Du {{(timeFrom .Startdate).Format "02/01/2006"}} au {{(timeFrom .Enddate).Format "02/01/2006"}}</p>
|
<div>
|
||||||
<p class="text-sm text-gray-500"></p>
|
<dt class="text-sm font-medium text-gray-500">{{.label}}</dt>
|
||||||
</a>
|
<dd class="mt-1 text-sm text-gray-900">
|
||||||
|
{{if eq .type "select"}}
|
||||||
|
{{$fieldValue := index $.ViewState.vehicle.Data .name}}
|
||||||
|
{{range .options}}
|
||||||
|
{{if eq .value $fieldValue}}{{.label}}{{end}}
|
||||||
|
{{end}}
|
||||||
|
{{else}}
|
||||||
|
{{index $.ViewState.vehicle.Data .name}}
|
||||||
|
{{end}}
|
||||||
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
{{end}}
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
fields: {
|
fields: {
|
||||||
licence_plate: '{{ .ViewState.vehicle.Data.licence_plate }}',
|
licence_plate: '{{ .ViewState.vehicle.Data.licence_plate }}',
|
||||||
name: '{{ .ViewState.vehicle.Data.name }}',
|
name: '{{ .ViewState.vehicle.Data.name }}',
|
||||||
|
type: '{{ .ViewState.vehicle.Type }}',
|
||||||
kilometers: '{{ .ViewState.vehicle.Data.kilometers }}',
|
kilometers: '{{ .ViewState.vehicle.Data.kilometers }}',
|
||||||
informations: '{{ .ViewState.vahicle.Data.informations}}',
|
informations: '{{ .ViewState.vehicle.Data.informations}}',
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
licence_plate: ['required', 'regexMatch:^[A-Z]{1,2}-[0-9]{1,3}-[A-Z]{1,2}$'],
|
licence_plate: ['required', 'regexMatch:^[A-Z]{1,2}-[0-9]{1,3}-[A-Z]{1,2}$'],
|
||||||
|
@ -86,7 +87,7 @@
|
||||||
<legend class="sr-only">Automatique</legend>
|
<legend class="sr-only">Automatique</legend>
|
||||||
<div class="relative flex items-start">
|
<div class="relative flex items-start">
|
||||||
<div class="flex h-5 items-center">
|
<div class="flex h-5 items-center">
|
||||||
<input id="automatic" aria-describedby="automatic-description" name="automatic" type="checkbox" class="h-4 w-4 rounded border-gray-300 text-co-blue focus:ring-co-blue">
|
<input id="automatic" aria-describedby="automatic-description" name="automatic" type="checkbox" {{if .ViewState.vehicle.Data.automatic}}checked{{end}} class="h-4 w-4 rounded border-gray-300 text-co-blue focus:ring-co-blue">
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3 text-sm">
|
<div class="ml-3 text-sm">
|
||||||
<label for="automatic" class="font-medium text-gray-700">Automatique</label>
|
<label for="automatic" class="font-medium text-gray-700">Automatique</label>
|
||||||
|
@ -126,8 +127,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||||
{{ $fieldName := "address" }}
|
{{ $fieldName := "address" }}
|
||||||
{{if .ViewState.Data.address}}
|
{{if .ViewState.vehicle.Data.address}}
|
||||||
{{$default := .ViewState.Data.address}}
|
{{$default := .ViewState.vehicle.Data.address}}
|
||||||
{{ template "address" dict "FieldName" $fieldName "Default" $default}}
|
{{ template "address" dict "FieldName" $fieldName "Default" $default}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{ template "address_autocomplete" dict "FieldName" $fieldName}}
|
{{ template "address_autocomplete" dict "FieldName" $fieldName}}
|
||||||
|
@ -144,6 +145,48 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{if .ViewState.vehicle_optional_fields}}
|
||||||
|
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||||
|
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||||
|
<div class="md:col-span-1">
|
||||||
|
<h3 class="text-lg font-medium leading-6 text-gray-900">Autres propriétés</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-500">Informations complémentaires sur le véhicule</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||||
|
<div class="grid grid-cols-6 gap-6">
|
||||||
|
{{range .ViewState.vehicle_optional_fields}}
|
||||||
|
<div class="col-span-6 sm:col-span-3">
|
||||||
|
<label for="{{.name}}" class="block text-sm font-medium text-gray-700">{{.label}}</label>
|
||||||
|
{{if eq .type "select"}}
|
||||||
|
<div class="sm:mt-0 sm:col-span-2">
|
||||||
|
<select id="{{.name}}" name="{{.name}}"
|
||||||
|
class="p-2 max-w-lg mt-1 block focus:ring-co-blue focus:border-co-blue w-full shadow-sm sm:max-w-xs sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{range .options}}
|
||||||
|
<option value="{{.value}}" {{if eq .value (index $.ViewState.vehicle.Data .name)}}selected{{end}}>{{.label}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{else if eq .type "textarea"}}
|
||||||
|
<textarea id="{{.name}}" name="{{.name}}" rows="3"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl">{{index $.ViewState.vehicle.Data .name}}</textarea>
|
||||||
|
{{else if eq .type "date"}}
|
||||||
|
<input type="date" id="{{.name}}" name="{{.name}}" value="{{index $.ViewState.vehicle.Data .name}}"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{else if eq .type "number"}}
|
||||||
|
<input type="number" id="{{.name}}" name="{{.name}}" value="{{index $.ViewState.vehicle.Data .name}}"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{else}}
|
||||||
|
<input type="text" id="{{.name}}" name="{{.name}}" value="{{index $.ViewState.vehicle.Data .name}}"
|
||||||
|
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl">
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
||||||
<a href="/app/vehicles-management/fleet/{{.ViewState.vehicle.ID}}">
|
<a href="/app/vehicles-management/fleet/{{.ViewState.vehicle.ID}}">
|
||||||
|
|
|
@ -6,9 +6,13 @@
|
||||||
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
||||||
"Courier New", monospace;
|
"Courier New", monospace;
|
||||||
|
--color-red-100: oklch(0.936 0.032 17.717);
|
||||||
--color-red-500: oklch(0.637 0.237 25.331);
|
--color-red-500: oklch(0.637 0.237 25.331);
|
||||||
--color-red-600: oklch(0.577 0.245 27.325);
|
--color-red-600: oklch(0.577 0.245 27.325);
|
||||||
|
--color-red-800: oklch(0.444 0.177 26.899);
|
||||||
--color-red-900: oklch(0.396 0.141 25.723);
|
--color-red-900: oklch(0.396 0.141 25.723);
|
||||||
|
--color-yellow-100: oklch(0.973 0.071 103.193);
|
||||||
|
--color-yellow-800: oklch(0.476 0.114 61.907);
|
||||||
--color-green-100: oklch(0.962 0.044 156.743);
|
--color-green-100: oklch(0.962 0.044 156.743);
|
||||||
--color-green-600: oklch(0.627 0.194 149.214);
|
--color-green-600: oklch(0.627 0.194 149.214);
|
||||||
--color-green-800: oklch(0.448 0.119 151.328);
|
--color-green-800: oklch(0.448 0.119 151.328);
|
||||||
|
@ -472,6 +476,9 @@
|
||||||
.mx-auto {
|
.mx-auto {
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
}
|
}
|
||||||
|
.-my-1 {
|
||||||
|
margin-block: calc(var(--spacing) * -1);
|
||||||
|
}
|
||||||
.-my-1\.5 {
|
.-my-1\.5 {
|
||||||
margin-block: calc(var(--spacing) * -1.5);
|
margin-block: calc(var(--spacing) * -1.5);
|
||||||
}
|
}
|
||||||
|
@ -520,6 +527,9 @@
|
||||||
.mt-10 {
|
.mt-10 {
|
||||||
margin-top: calc(var(--spacing) * 10);
|
margin-top: calc(var(--spacing) * 10);
|
||||||
}
|
}
|
||||||
|
.-mr-1 {
|
||||||
|
margin-right: calc(var(--spacing) * -1);
|
||||||
|
}
|
||||||
.-mr-1\.5 {
|
.-mr-1\.5 {
|
||||||
margin-right: calc(var(--spacing) * -1.5);
|
margin-right: calc(var(--spacing) * -1.5);
|
||||||
}
|
}
|
||||||
|
@ -550,6 +560,9 @@
|
||||||
.mb-4 {
|
.mb-4 {
|
||||||
margin-bottom: calc(var(--spacing) * 4);
|
margin-bottom: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
|
.mb-6 {
|
||||||
|
margin-bottom: calc(var(--spacing) * 6);
|
||||||
|
}
|
||||||
.mb-10 {
|
.mb-10 {
|
||||||
margin-bottom: calc(var(--spacing) * 10);
|
margin-bottom: calc(var(--spacing) * 10);
|
||||||
}
|
}
|
||||||
|
@ -728,9 +741,15 @@
|
||||||
.min-h-screen {
|
.min-h-screen {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
.w-0 {
|
||||||
|
width: calc(var(--spacing) * 0);
|
||||||
|
}
|
||||||
.w-0\.5 {
|
.w-0\.5 {
|
||||||
width: calc(var(--spacing) * 0.5);
|
width: calc(var(--spacing) * 0.5);
|
||||||
}
|
}
|
||||||
|
.w-1 {
|
||||||
|
width: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.w-1\/2 {
|
.w-1\/2 {
|
||||||
width: calc(1/2 * 100%);
|
width: calc(1/2 * 100%);
|
||||||
}
|
}
|
||||||
|
@ -1744,6 +1763,9 @@
|
||||||
.bg-indigo-600 {
|
.bg-indigo-600 {
|
||||||
background-color: var(--color-indigo-600);
|
background-color: var(--color-indigo-600);
|
||||||
}
|
}
|
||||||
|
.bg-red-100 {
|
||||||
|
background-color: var(--color-red-100);
|
||||||
|
}
|
||||||
.bg-red-500 {
|
.bg-red-500 {
|
||||||
background-color: var(--color-red-500);
|
background-color: var(--color-red-500);
|
||||||
}
|
}
|
||||||
|
@ -1756,6 +1778,9 @@
|
||||||
.bg-white {
|
.bg-white {
|
||||||
background-color: var(--color-white);
|
background-color: var(--color-white);
|
||||||
}
|
}
|
||||||
|
.bg-yellow-100 {
|
||||||
|
background-color: var(--color-yellow-100);
|
||||||
|
}
|
||||||
.-bg-conic {
|
.-bg-conic {
|
||||||
--tw-gradient-position: in oklab;
|
--tw-gradient-position: in oklab;
|
||||||
background-image: conic-gradient(var(--tw-gradient-stops));
|
background-image: conic-gradient(var(--tw-gradient-stops));
|
||||||
|
@ -1967,6 +1992,9 @@
|
||||||
.px-6 {
|
.px-6 {
|
||||||
padding-inline: calc(var(--spacing) * 6);
|
padding-inline: calc(var(--spacing) * 6);
|
||||||
}
|
}
|
||||||
|
.py-0 {
|
||||||
|
padding-block: calc(var(--spacing) * 0);
|
||||||
|
}
|
||||||
.py-0\.5 {
|
.py-0\.5 {
|
||||||
padding-block: calc(var(--spacing) * 0.5);
|
padding-block: calc(var(--spacing) * 0.5);
|
||||||
}
|
}
|
||||||
|
@ -2003,6 +2031,9 @@
|
||||||
.py-12 {
|
.py-12 {
|
||||||
padding-block: calc(var(--spacing) * 12);
|
padding-block: calc(var(--spacing) * 12);
|
||||||
}
|
}
|
||||||
|
.pt-1 {
|
||||||
|
padding-top: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.pt-1\.5 {
|
.pt-1\.5 {
|
||||||
padding-top: calc(var(--spacing) * 1.5);
|
padding-top: calc(var(--spacing) * 1.5);
|
||||||
}
|
}
|
||||||
|
@ -2302,9 +2333,15 @@
|
||||||
.text-red-600 {
|
.text-red-600 {
|
||||||
color: var(--color-red-600);
|
color: var(--color-red-600);
|
||||||
}
|
}
|
||||||
|
.text-red-800 {
|
||||||
|
color: var(--color-red-800);
|
||||||
|
}
|
||||||
.text-white {
|
.text-white {
|
||||||
color: var(--color-white);
|
color: var(--color-white);
|
||||||
}
|
}
|
||||||
|
.text-yellow-800 {
|
||||||
|
color: var(--color-yellow-800);
|
||||||
|
}
|
||||||
.capitalize {
|
.capitalize {
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
@ -2990,6 +3027,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.focus\:z-20 {
|
||||||
|
&:focus {
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
.focus\:border-blue-500 {
|
.focus\:border-blue-500 {
|
||||||
&:focus {
|
&:focus {
|
||||||
border-color: var(--color-blue-500);
|
border-color: var(--color-blue-500);
|
||||||
|
@ -3082,6 +3124,11 @@
|
||||||
outline-offset: calc(2px * -1);
|
outline-offset: calc(2px * -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.focus\:outline-offset-0 {
|
||||||
|
&:focus {
|
||||||
|
outline-offset: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.focus\:outline-indigo-600 {
|
.focus\:outline-indigo-600 {
|
||||||
&:focus {
|
&:focus {
|
||||||
outline-color: var(--color-indigo-600);
|
outline-color: var(--color-indigo-600);
|
||||||
|
@ -3098,6 +3145,12 @@
|
||||||
--tw-ring-inset: inset;
|
--tw-ring-inset: inset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.focus-visible\:outline {
|
||||||
|
&:focus-visible {
|
||||||
|
outline-style: var(--tw-outline-style);
|
||||||
|
outline-width: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.focus-visible\:outline-2 {
|
.focus-visible\:outline-2 {
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
outline-style: var(--tw-outline-style);
|
outline-style: var(--tw-outline-style);
|
||||||
|
@ -3109,6 +3162,16 @@
|
||||||
outline-offset: calc(2px * -1);
|
outline-offset: calc(2px * -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.focus-visible\:outline-offset-2 {
|
||||||
|
&:focus-visible {
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.focus-visible\:outline-co-blue {
|
||||||
|
&:focus-visible {
|
||||||
|
outline-color: var(--color-co-blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
.focus-visible\:outline-indigo-600 {
|
.focus-visible\:outline-indigo-600 {
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
outline-color: var(--color-indigo-600);
|
outline-color: var(--color-indigo-600);
|
||||||
|
@ -3124,6 +3187,11 @@
|
||||||
opacity: 30%;
|
opacity: 30%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.disabled\:opacity-50 {
|
||||||
|
&:disabled {
|
||||||
|
opacity: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
.sm\:col-span-1 {
|
.sm\:col-span-1 {
|
||||||
@media (width >= 40rem) {
|
@media (width >= 40rem) {
|
||||||
grid-column: span 1 / span 1;
|
grid-column: span 1 / span 1;
|
||||||
|
|
Loading…
Reference in New Issue