234 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			HTML
		
	
	
	
{{define "content"}}
 | 
						|
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
 | 
						|
    <h1 class="text-2xl font-semibold text-gray-900">Déplacements</h1>
 | 
						|
    <div class="sm:flex sm:items-center">
 | 
						|
        <div class="sm:flex-auto">
 | 
						|
          <p class="mt-2 text-sm text-gray-700"></p>
 | 
						|
        </div>
 | 
						|
        <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
 | 
						|
          <!--<a href="/app/journeys/groups_covoiturage">
 | 
						|
            <button type="button"
 | 
						|
              class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 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">
 | 
						|
              {{$.IconSet.Icon "hero:outline/plus-circle" "h-5 w-5 mr-3"}}
 | 
						|
              Gestion des groupes
 | 
						|
            </button>
 | 
						|
          </a>-->
 | 
						|
        </div>
 | 
						|
      </div>
 | 
						|
 | 
						|
    <div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-6 lg:max-w-7xl lg:grid-flow-col-dense lg:grid-cols-3">
 | 
						|
        <div class="space-y-6 lg:col-start-1 lg:col-span-1">
 | 
						|
            <div class="bg-white shadow sm:rounded-2xl">
 | 
						|
                <h2 id="timeline-title" class="text-lg font-medium text-gray-900 p-4 sm:px-6">Chercher une solution</h2>
 | 
						|
                <div class="border-t border-gray-200 px-4 py-5 sm:px-6">
 | 
						|
                    <form method="GET" action="{{if eq .ViewState.search_view "compact"}}/app/journeys/search{{else}}/app/journeys/{{end}}" x-data="journeySearch()">
 | 
						|
 | 
						|
                        <div class="py-4">
 | 
						|
                            <label for="beneficiary" class="block text-sm font-medium text-gray-700">Bénéficiaire (optionnel)</label>
 | 
						|
                            <div class="mt-1 relative" x-data="beneficiaryAutocomplete()">
 | 
						|
                                <input type="text"
 | 
						|
                                       x-model="input"
 | 
						|
                                       @input="onInput()"
 | 
						|
                                       @focus="showResults = true"
 | 
						|
                                       @blur="setTimeout(() => showResults = false, 200)"
 | 
						|
                                       class="p-2 shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-2xl">
 | 
						|
 | 
						|
                                <ul x-show="showResults && filteredBeneficiaries.length > 0"
 | 
						|
                                    class="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-xl py-1 text-base overflow-auto focus:outline-none sm:text-sm border border-gray-300"
 | 
						|
                                    tabindex="-1" role="listbox">
 | 
						|
                                    <template x-for="beneficiary in filteredBeneficiaries" :key="beneficiary.id">
 | 
						|
                                        <li class="text-gray-900 hover:bg-gray-200 cursor-default select-none relative py-2 pl-3 pr-9"
 | 
						|
                                            @click="selectBeneficiary(beneficiary)">
 | 
						|
                                            <span class="font-normal block truncate" x-text="beneficiary.name"></span>
 | 
						|
                                        </li>
 | 
						|
                                    </template>
 | 
						|
                                </ul>
 | 
						|
                            </div>
 | 
						|
                        </div>
 | 
						|
 | 
						|
                        {{ $departureField := "departure" }}
 | 
						|
                        {{ $departureLabel := "Départ" }}
 | 
						|
                        {{ $departure := .ViewState.departure }}
 | 
						|
                        {{ template "address_autocomplete" dict "FieldName" $departureField "FieldLabel" $departureLabel "Address" $departure }}
 | 
						|
 | 
						|
                        {{ $destinationField := "destination" }}
 | 
						|
                        {{ $destinationLabel := "Destination" }}
 | 
						|
                        {{ $destination := .ViewState.destination }}
 | 
						|
                        {{ template "address_autocomplete" dict "FieldName" $destinationField "FieldLabel" $destinationLabel "Address" $destination }}
 | 
						|
                        
 | 
						|
                        <input type="hidden" name="passengerid" value="{{.ViewState.passengerid}}" />
 | 
						|
 | 
						|
                        <div class="py-4 grid grid-cols-2">
 | 
						|
                            <div class="lg:col-span-1">
 | 
						|
                                <label for="departuredate" class="block text-sm font-medium text-gray-700">Date de départ</label>
 | 
						|
                                <div class="mt-1">
 | 
						|
                                    <input type="date" id="departuredate" name="departuredate" value="{{.ViewState.departuredate}}"
 | 
						|
                                        class="p-2 shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-l-2xl border-r-1">
 | 
						|
                                </div>
 | 
						|
                            </div>
 | 
						|
                            <div class="lg:col-span-1">
 | 
						|
                                <label for="departuretime" class="block text-sm font-medium text-gray-700">Heure de départ</label>
 | 
						|
                                <div class="mt-1">
 | 
						|
                                    <input type="time" id="departuretime" name="departuretime" value="{{.ViewState.departuretime}}"
 | 
						|
                                        class="p-2 shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-r-2xl border-l-0">
 | 
						|
                                </div>
 | 
						|
                            </div>
 | 
						|
                            
 | 
						|
                        </div>
 | 
						|
 | 
						|
                        <div class="flex gap-2 mt-8">
 | 
						|
                            <button type="submit"
 | 
						|
                                class="rounded-2xl border border-transparent bg-co-blue px-4 py-2 my-4 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">
 | 
						|
                                Chercher
 | 
						|
                            </button>
 | 
						|
                            {{if .ViewState.searched}}
 | 
						|
			    <a href="/app/journeys/save?departure={{json .ViewState.departure}}&destination={{ json .ViewState.destination }}&departuredate={{.ViewState.departuredate}}&departuretime={{.ViewState.departuretime}}&passengerid={{.ViewState.passengerid}}"
 | 
						|
                                class="rounded-2xl border border-gray-300 bg-white px-4 py-2 my-4 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 sm:w-auto inline-flex items-center">
 | 
						|
                                Enregistrer pour plus tard
 | 
						|
                            </a>
 | 
						|
                            {{end}}
 | 
						|
                        </div>
 | 
						|
                    </form>
 | 
						|
 | 
						|
                    <script>
 | 
						|
                    function journeySearch() {
 | 
						|
                        return {
 | 
						|
                            selectedBeneficiaryId: '{{.ViewState.passengerid}}',
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    function beneficiaryAutocomplete() {
 | 
						|
                        const beneficiaries = [
 | 
						|
                            {{range .ViewState.beneficiaries_list}}
 | 
						|
                            {
 | 
						|
                                id: '{{.ID}}',
 | 
						|
                                name: '{{.Data.first_name}} {{.Data.last_name}}',
 | 
						|
                                address: {{json .Data.address}}
 | 
						|
                            },
 | 
						|
                            {{end}}
 | 
						|
                        ];
 | 
						|
 | 
						|
                        return {
 | 
						|
                            input: '',
 | 
						|
                            showResults: false,
 | 
						|
                            filteredBeneficiaries: [],
 | 
						|
                            selectedBeneficiary: null,
 | 
						|
 | 
						|
                            init() {
 | 
						|
                                // Set initial value if passengerid is set
 | 
						|
                                const currentPassengerId = '{{.ViewState.passengerid}}';
 | 
						|
                                if (currentPassengerId) {
 | 
						|
                                    const beneficiary = beneficiaries.find(b => b.id === currentPassengerId);
 | 
						|
                                    if (beneficiary) {
 | 
						|
                                        this.input = beneficiary.name;
 | 
						|
                                        this.selectedBeneficiary = beneficiary;
 | 
						|
                                    }
 | 
						|
                                }
 | 
						|
                            },
 | 
						|
 | 
						|
                            onInput() {
 | 
						|
                                if (this.input.length === 0) {
 | 
						|
                                    this.filteredBeneficiaries = [];
 | 
						|
                                    this.selectedBeneficiary = null;
 | 
						|
                                    this.updatePassengerId('');
 | 
						|
                                    return;
 | 
						|
                                }
 | 
						|
 | 
						|
                                this.filteredBeneficiaries = beneficiaries.filter(beneficiary =>
 | 
						|
                                    beneficiary.name.toLowerCase().includes(this.input.toLowerCase())
 | 
						|
                                ).slice(0, 10); // Limit to 10 results
 | 
						|
                            },
 | 
						|
 | 
						|
                            selectBeneficiary(beneficiary) {
 | 
						|
                                this.input = beneficiary.name;
 | 
						|
                                this.selectedBeneficiary = beneficiary;
 | 
						|
                                this.showResults = false;
 | 
						|
                                this.updatePassengerId(beneficiary.id);
 | 
						|
                                this.setDepartureAddress(beneficiary.address);
 | 
						|
                            },
 | 
						|
 | 
						|
                            updatePassengerId(id) {
 | 
						|
                                const passengerInput = document.querySelector('input[name="passengerid"]');
 | 
						|
                                if (passengerInput) {
 | 
						|
                                    passengerInput.value = id;
 | 
						|
                                }
 | 
						|
                            },
 | 
						|
 | 
						|
                            setDepartureAddress(address) {
 | 
						|
                                if (address) {
 | 
						|
                                    // Find the departure address autocomplete container
 | 
						|
                                    const departureContainer = document.querySelector('input[name="departure"]').closest('[x-data]');
 | 
						|
                                    if (departureContainer && departureContainer._x_dataStack && departureContainer._x_dataStack[0]) {
 | 
						|
                                        const addressAutocomplete = departureContainer._x_dataStack[0];
 | 
						|
                                        // Update the address autocomplete component directly
 | 
						|
                                        addressAutocomplete.address = JSON.stringify(address);
 | 
						|
                                        addressAutocomplete.addressObject = address;
 | 
						|
                                        addressAutocomplete.input = address.properties.label;
 | 
						|
                                    }
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    </script>
 | 
						|
                </div>
 | 
						|
            </div>
 | 
						|
        </div>
 | 
						|
        <div class="lg:col-start-2 lg:col-span-2">
 | 
						|
            {{if .ViewState.searched}}
 | 
						|
            <section aria-labelledby="results-title" x-data="{
 | 
						|
                tab: 'all',
 | 
						|
                to(event) {
 | 
						|
                    this.tab = event.target.value
 | 
						|
                }
 | 
						|
            }">
 | 
						|
            <div class="bg-white shadow sm:rounded-lg sm:overflow-hidden">
 | 
						|
                <div class="divide-y divide-gray-200">
 | 
						|
                    <div>
 | 
						|
                        <div class="sm:hidden">
 | 
						|
                            <label for="tabs" class="sr-only">Select a tab</label>
 | 
						|
                            <select id="tabs" name="tabs" @change="to"
 | 
						|
                                class="block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
 | 
						|
                                {{range .ViewState.journey_tabs}}
 | 
						|
                                {{if or .enabled (and .module (moduleAvailable .module))}}
 | 
						|
                                <option value="{{.name}}">{{.title}}</option>
 | 
						|
                                {{end}}
 | 
						|
                                {{end}}
 | 
						|
                            </select>
 | 
						|
                        </div>
 | 
						|
                        <div class="hidden sm:block">
 | 
						|
                            <div class="border-b border-gray-200 pl-4 overflow-x-auto">
 | 
						|
                                <nav class="-mb-px flex space-x-8 min-w-max" aria-label="Tabs">
 | 
						|
                                    <!-- Current: "border-indigo-500 text-indigo-600", Default: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300" -->
 | 
						|
                                    {{range .ViewState.journey_tabs}}
 | 
						|
                                    {{if or .enabled (and .module (moduleAvailable .module))}}
 | 
						|
                                    <a href="#" @click="tab = '{{.name}}'"
 | 
						|
                                        class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
 | 
						|
                                        :class="tab == '{{.name}}' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
 | 
						|
                                        {{.title}} </a>
 | 
						|
                                    {{end}}
 | 
						|
                                    {{end}}
 | 
						|
                                </nav>
 | 
						|
                            </div>
 | 
						|
                        </div>
 | 
						|
                    </div>
 | 
						|
 | 
						|
                    <div x-show="tab == 'all'">{{template "journeys_all" .}}</div>
 | 
						|
                    <div x-show="tab == 'carpool'">{{template "journeys_carpool" .}}</div>
 | 
						|
                    <div x-show="tab == 'public-transit'">{{template "journeys_public_transit" .}}</div>
 | 
						|
                    <div x-show="tab == 'organized-carpool'">{{template "journeys_organized_carpool" .}}</div>
 | 
						|
                    <div x-show="tab == 'solidarity-transport'">{{template "journeys_solidarity_transport" .}}</div>
 | 
						|
                    <div x-show="tab == 'vehicles'">{{template "journeys_vehicles" .}}</div>
 | 
						|
                    <div x-show="tab == 'directory'">{{template "journeys_local_solutions" .}}</div>
 | 
						|
                    <div x-show="tab == 'others'">{{template "journeys_others" .}}</div>
 | 
						|
                </div>
 | 
						|
            </div>
 | 
						|
        </section>
 | 
						|
            {{else}}
 | 
						|
            {{template "saved_searches" .}}
 | 
						|
            {{end}}
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
 
 | 
						|
</div>
 | 
						|
{{end}}
 |