Selaa lähdekoodia

add map filters

Olivier Massot 4 vuotta sitten
vanhempi
commit
520b02add4

+ 11 - 6
components/Ui/Map/Structures.vue

@@ -8,8 +8,7 @@
           :center="center"
           :bounds="bounds"
           :options="{scrollWheelZoom: false, zoomSnap: 0.25}"
-          @ready="$emit('ready', $event, field)"
-          @update="$emit('update', $event, field)"
+          @update:bounds="boundsUpdated"
         >
           <l-tile-layer
             url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
@@ -69,6 +68,7 @@ export default {
       center: defaultCenter,
       zoom: defaultZoom,
       bounds: defaultBounds,
+      isFirstRendering: true,
       shortcuts: [
         { src: '/images/metropole.png', alt: 'Metropole', bounds: { x1: 51.03, y1: -5.78, x2: 41.2, y2: 9.70 } },
         { src: '/images/guadeloupe.png', alt: 'Guadeloupe', bounds: { x1: 16.62, y1: -62.03, x2: 15.74, y2: -60.97 } },
@@ -81,11 +81,16 @@ export default {
   },
   methods: {
     setMapBounds (bounds) {
-      // const map = this.$el.querySelector('#map')
-      // console.log(map)
-      // map.$emit('boundsUpdated', [bounds.x1, bounds.y1, bounds.x2, bounds.y2])
-      // this.bounds = latLngBounds([bounds.x1, bounds.y1], [bounds.x2, bounds.y2])
+      this.center = [0, 0] // << without this, the new bounds won't be properly set if you're already inside these new bounds.
       this.bounds = [[bounds.x1, bounds.y1], [bounds.x2, bounds.y2]]
+    },
+    boundsUpdated (newBounds) {
+      // do not send and event on first automatic rendering
+      if (this.isFirstRendering) {
+        this.isFirstRendering = false
+        return
+      }
+      this.$emit('boundsUpdated', newBounds)
     }
   }
 }

+ 55 - 30
components/Ui/Search/Address.vue

@@ -1,36 +1,61 @@
 <template>
-  <v-text-field
-    type="text"
-    name="search-city"
-    class="search-bar"
-    outlined
-    :label="$t('where') + ' ?'"
-    autocomplete="off"
-    @change="$emit('change', $event)"
-  >
-    <button
-      class="search-bar-btn"
-      name="search-localize"
-    >
-      <i class="fas fa-crosshairs" />
-    </button>
-    <div class="city-search-dropdown" style="display: none;">
-      <div class="city-search-loading">
-        <nuxt-img
-          src="EXT:ot_templating/Resources/Public/media/gear.gif"
-          :alt="$t('please_wait')"
-        />
-      </div>
-      <div class="city-search-no-result">
-        {{ $t('no_result') }}
-      </div>
-      <div class="city-search-results" />
-    </div>
-    <input type="hidden" name="lat" value="{ot:request.getArgument(argument: 'lat')}">
-    <input type="hidden" name="long" value="{ot:request.getArgument(argument: 'long')}">
-  </v-text-field>
+  <div>
+    <v-text-field
+      v-model="text"
+      type="text"
+      name="search-city"
+      class="search-bar"
+      outlined
+      :label="$t('where') + ' ?'"
+      autocomplete="off"
+      append-icon="mdi-crosshairs-gps"
+      @change="$emit('change', $event)"
+      @click:append="geolocalizeUser"
+    />
+
+    <v-snackbar :value="errorMsg !== ''">
+      {{ errorMsg }}
+      <template #action="{ attrs }">
+        <v-btn text v-bind="attrs" @click="errorMsg=''">
+          {{ $t('close') }}
+        </v-btn>
+      </template>
+    </v-snackbar>
+  </div>
 </template>
 
+<script>
+export default {
+  data () {
+    return {
+      latitude: null,
+      longitude: null,
+      text: '',
+      errorMsg: ''
+    }
+  },
+  methods: {
+    geolocalizeUser () {
+      if (navigator.geolocation) {
+        navigator.geolocation.getCurrentPosition(
+          (position) => {
+            this.latitude = position.coords.latitude
+            this.latitude = position.coords.longitude
+            this.text = this.$t('my_position')
+          },
+          () => {
+            this.errorMsg = this.$t('geolocation_error')
+          }
+        )
+      } else {
+        this.errorMsg = this.$t('geolocation_not_supported')
+      }
+    }
+  }
+}
+</script>
+
+
 <style>
 .v-input__control {
   height: 56px;

+ 21 - 17
components/Ui/Search/Text.vue

@@ -1,23 +1,27 @@
 <template>
-  <div class="search-bar-wrapper">
-    <v-text-field
-      type="text"
-      class="search-bar"
-      name="search-query"
-      outlined
-      :label="$t('what') + ' ?'"
-      @input="$emit('change', $event)"
-    >
-      <button
-        class="search-bar-btn"
-        name="submit-search"
-      >
-        <i class="fas fa-search" />
-      </button>
-    </v-text-field>
-  </div>
+  <v-text-field
+    v-model="text"
+    type="text"
+    class="search-bar"
+    name="search-query"
+    outlined
+    append-icon="mdi-magnify"
+    :label="$t('what') + ' ?'"
+    @change="$emit('change', text)"
+    @click:append="$emit('change', text)"
+  />
 </template>
 
+<script>
+export default {
+  data () {
+    return {
+      text: ''
+    }
+  }
+}
+</script>
+
 <style>
 .v-input__control {
   height: 56px;

+ 5 - 0
lang/fr-FR.js

@@ -25,6 +25,11 @@ export default (_context, _locale) => {
     type: 'Type',
     reinitialize: 'Réinitialiser',
     search: 'Rechercher',
+    no_results: 'Aucun résultats',
+    my_position: 'Ma position',
+    close: 'Fermer',
+    geolocation_error: 'Une erreur s\'est produite lors de la géolocalisation',
+    geolocation_not_supported: 'La géolocalisation n\'est pas supportée par votre navigateur',
     BIG_BAND: 'Big band',
     BRASS_BAND: 'Brass band',
     ORCHESTRA_CLASS: "Classe d'orchestre",

+ 35 - 25
pages/structures_adherentes/index.vue

@@ -22,7 +22,10 @@
     <v-row>
       <!-- Map Column (hidden in 'list-view' mode)-->
       <v-col v-show="mapview" cols="6">
-        <UiMapStructures :structures="structures" />
+        <UiMapStructures
+          :structures="filteredStructures"
+          @boundsUpdated="mapBoundsFilterChanged"
+        />
       </v-col>
 
       <!-- Results column -->
@@ -112,25 +115,23 @@
 
         <!-- Results -->
         <v-data-iterator
-          :items="structures"
+          :items="filteredStructures"
           :page.sync="page"
           :items-per-page="itemsPerPage"
           sort-by="name"
           hide-default-footer
-          class="pt-4"
+          :no-data-text="$t('no_results')"
+          class="pt-4 mt-6"
         >
-          <!--          <span class="no-result" style="display: none">{{ $t("no_result") }}</span>-->
-          <!--          <span class="error-message" style="display: none">{{ $t("an_error_occured") }}</span>-->
-          <!--          <span class="results-count-message" style="display: none">-->
-          <!--            <i class="count" />&nbsp;<i>{{ $t("results") }}</i>-->
-          <!--          </span>-->
+          <template #header>
+            <i class="results-count">{{ totalRecords }} {{ $t('results') }}</i>
+          </template>
 
           <template #default="props">
-            <v-row justify="space-between" class="my-3">
+            <v-row justify="space-between" class="mt-1 mb-3">
               <v-col
                 v-for="structure in props.items"
                 :key="structure.name"
-                v-if="matchFilters(structure)"
                 cols="12"
                 sm="12"
                 :md="mapview ? 6 : 12"
@@ -1804,12 +1805,16 @@ export default {
       typeFilter: null,
       departmentFilter: null,
       federationFilter: null,
-      distanceFilter: null
+      distanceFilter: null,
+      mapBoundsFilter: null
     }
   },
   computed: {
+    filteredStructures () {
+      return this.structures.filter((s) => { return this.matchFilters(s) })
+    },
     totalRecords () {
-      return this.structures.length
+      return this.filteredStructures.length
     },
     pageCount () {
       return Math.floor(this.totalRecords / this.itemsPerPage) + 1
@@ -1840,6 +1845,9 @@ export default {
     distanceFilterChanged (newVal) {
       this.distanceFilter = newVal
     },
+    mapBoundsFilterChanged (newBounds) {
+      this.mapBoundsFilter = newBounds
+    },
     reinitializeFilters () {
       this.textFilter = null
       this.locationFilter = null
@@ -1847,6 +1855,7 @@ export default {
       this.departmentFilter = null
       this.federationFilter = null
       this.distanceFilter = null
+      this.mapBoundsFilter = null
     },
     matchFilters (structure) {
       // Filter by name
@@ -1886,19 +1895,15 @@ export default {
       }
 
       // filter by map bounds
-      // if (area !== null) {
-      //   if (structure.longitude < area[0] ||
-      //     structure.latitude < area[1] ||
-      //     structure.longitude > area[2] ||
-      //     structure.latitude > area[3]
-      //   ) {
-      //     if (structure.id == 498) {
-      //       console.log(structure.longitude, structure.latitude, area);
-      //       console.log(structure.longitude < area[0], structure.latitude < area[1], structure.longitude > area[2], structure.latitude > area[3])
-      //     }
-      //     return false;
-      //   }
-      // }
+      if (this.mapBoundsFilter !== null) {
+        if (structure.longitude < this.mapBoundsFilter.getSouthWest().lng ||
+          structure.latitude < this.mapBoundsFilter.getSouthWest().lat ||
+          structure.longitude > this.mapBoundsFilter.getNorthEast().lng ||
+          structure.latitude > this.mapBoundsFilter.getNorthEast().lat
+        ) {
+          return false
+        }
+      }
       return true
     }
   }
@@ -1931,4 +1936,9 @@ export default {
   .icon {
     color: $theme;
   }
+
+  .results-count {
+    font-size: .8em;
+    color: #666;
+  }
 </style>