Просмотр исходного кода

events - add location filter and date formatting

Olivier Massot 3 лет назад
Родитель
Сommit
0e579f82d0
8 измененных файлов с 68 добавлено и 23 удалено
  1. 6 0
      lang/fr-FR.js
  2. 6 1
      nuxt.config.js
  3. 2 1
      package.json
  4. 39 13
      pages/events/index.vue
  5. 2 2
      pages/structures/index.vue
  6. 7 3
      services/data/EventsProvider.ts
  7. 4 2
      services/utils/geo.ts
  8. 2 1
      tsconfig.json

+ 6 - 0
lang/fr-FR.js

@@ -85,5 +85,11 @@ export default (_context, _locale) => {
     apply: 'Appliquer',
     cancel: 'Annuler',
     reset: 'Réinitialiser',
+    from_hour: 'de',
+    to_hour: 'à',
+    on_hour: 'à',
+    on_day: 'Le',
+    from_day: 'Du',
+    to_day: 'au'
   })
 }

+ 6 - 1
nuxt.config.js

@@ -73,8 +73,13 @@ export default {
           }
         ]
       }
-    ]
+    ],
+    '@nuxtjs/date-fns'
   ],
+  dateFns: {
+    defaultLocale: 'fr-FR',
+    fallbackLocale: 'en-US'
+  },
 
   // Vuetify module configuration
   // @see https://vuetifyjs.com/en/features/theme/

+ 2 - 1
package.json

@@ -25,9 +25,10 @@
     "@fortawesome/free-solid-svg-icons": "^5.15.4",
     "@fortawesome/vue-fontawesome": "^2.0.2",
     "@nuxtjs/axios": "^5.13.6",
+    "@nuxtjs/date-fns": "^1.5.0",
     "@nuxtjs/i18n": "^7.0.3",
     "core-js": "^3.15.1",
-    "date-fns": "^2.29.0",
+    "date-fns": "^2.29.1",
     "iframe-resizer": "^4.3.2",
     "leaflet": "^1.7.1",
     "libphonenumber-js": "^1.9.38",

+ 39 - 13
pages/events/index.vue

@@ -141,10 +141,9 @@
                           <font-awesome-icon :icon="['fas', 'calendar']" class="icon mr-2" />
                         </td>
                         <td>
-                          <span v-if="event.datetimeStart && event.datetimeEnd">
-                            {{ new Date(event.datetimeStart).toLocaleString() }} ~ {{ new Date(event.datetimeEnd).toLocaleString() }}
+                          <span>
+                            {{ formatDateIntervalFor(new Date(event.datetimeStart), new Date(event.datetimeEnd)) }}
                           </span>
-                          <span v-else>{{ new Date(event.datetimeStart).toLocaleString() }}</span>
                         </td>
                       </tr>
 
@@ -193,8 +192,8 @@
 <script lang="ts">
 import Vue from 'vue'
 import EventsProvider from "~/services/data/EventsProvider"
-import {today, todayIso, formatIso, formatIsoDate} from '@/services/utils/date'
-import { reformatDate, addDays, nextSunday, addMonths } from "date-fns";
+import {today, todayIso, formatIso} from '@/services/utils/date'
+import locale from 'date-fns/locale/fr'
 
 const defaultDateRange: DateRange = { start: '', end: '' }
 
@@ -219,7 +218,7 @@ export default Vue.extend({
       null,
       this.dateRangeFilter.start,
       this.dateRangeFilter.end,
-      null,
+      this.locationFilter,
       this.page,
       this.itemsPerPage
     ).then(
@@ -246,20 +245,20 @@ export default Vue.extend({
       // Cette semaine
       const week_preset: DateRangePreset = {
         label: this.$t('next_week').toString(),
-        range: {start: todayIso(), end: formatIso(addDays(today(), 7))}
+        range: {start: todayIso(), end: formatIso(this.$dateFns.addDays(today(), 7))}
       }
 
       // Ce week-end
-      const sunday: Date = nextSunday(today())
+      const sunday: Date = this.$dateFns.nextSunday(today())
       const weekend_preset: DateRangePreset = {
         label: this.$t('next_weekend').toString(),
-        range: {start: formatIso(addDays(sunday, -2)), end: formatIso(sunday)}
+        range: {start: formatIso(this.$dateFns.addDays(sunday, -2)), end: formatIso(sunday)}
       }
 
       // Ce mois
       const month_preset: DateRangePreset = {
         label: this.$t('next_month').toString(),
-        range: {start: todayIso(), end: formatIso(addMonths(today(), 1))}
+        range: {start: todayIso(), end: formatIso(this.$dateFns.addMonths(today(), 1))}
       }
 
       return [today_preset, week_preset, weekend_preset, month_preset]
@@ -305,9 +304,36 @@ export default Vue.extend({
     enhancedAutocompleteFilter (_: any, queryText: string, itemText: string): boolean {
       return normalize(itemText).includes(normalize(queryText))
     },
-    formatDatetime(date: string): string {
-      console.log(date)
-      return reformatDate(date, 'yyyy-MM-DD[T]HH:mm:ssZZ', 'dd/MM/yyyy hh:mm')
+    formatDate(date: Date, short = true): string {
+      return short ? this.$dateFns.format(date, 'dd/MM/yyyy') : this.$dateFns.format(date, 'dd MMM yyyy', {locale: locale})
+    },
+    formatTime(date: Date): string {
+      return this.$dateFns.format(date, 'HH:mm')
+    },
+    formatDateTime(date: Date): string {
+      return this.formatDate(date) + ' ' + this.$t('on_hour') + ' ' + this.formatTime(date)
+    },
+    formatDateIntervalFor(dateStart: Date | null = null, dateEnd: Date | null = null): string {
+      if (dateStart === null && dateEnd !== null)
+      {
+        return this.formatDateTime(dateEnd)
+      }
+      else if (dateEnd === null && dateStart !== null) {
+        return this.formatDateTime(dateStart)
+      }
+      else if (dateStart !== null && dateEnd !== null) {
+        if (dateStart === dateEnd) {
+          return this.formatDateTime(dateStart)
+        }
+        else if (this.$dateFns.isSameDay(dateStart, dateEnd)) {
+          return this.$t('on_day') + ' ' + this.formatDate(dateStart, false) + ', ' +
+            this.$t('from_hour') + ' ' + this.formatTime(dateStart) + ' ' + this.$t('to_hour') + ' ' + this.formatTime(dateEnd)
+        }
+        else {
+          return this.$t('from_day') + ' ' + this.formatDateTime(dateStart) + ' ' + this.$t('to_day') + ' ' + this.formatDateTime(dateEnd)
+        }
+      }
+      return ""
     }
   }
 })

+ 2 - 2
pages/structures/index.vue

@@ -317,7 +317,7 @@ import Vue from 'vue'
 import { LatLngBounds } from 'leaflet'
 import departments from '@/enums/departments'
 import practices from '@/enums/practices'
-import sphericDistance from '@/services/utils/geo'
+import sphericalDistance from '@/services/utils/geo'
 import StructuresProvider from '~/services/data/StructuresProvider'
 
 const CMF_ID = 12097
@@ -489,7 +489,7 @@ export default Vue.extend({
 
       const radius = Number(this.distanceFilter) ?? 5
 
-      return sphericDistance(
+      return sphericalDistance(
         this.locationFilter.latitude,
         this.locationFilter.longitude,
         structure.mapAddress.latitude,

+ 7 - 3
services/data/EventsProvider.ts

@@ -2,6 +2,8 @@ import BaseProvider from '~/services/data/BaseProvider'
 import Address from "~/components/Ui/Search/Address.vue";
 import HydraParser from "~/services/data/HydraParser";
 
+const LOCATION_RADIUS = 20
+
 class PublicEventsProvider extends BaseProvider {
   protected normalize (e: any) : PublicEvent {
 
@@ -31,7 +33,7 @@ class PublicEventsProvider extends BaseProvider {
     organizationId: number | null = null,
     dateMin: string | null = null,
     dateMax: string | null = null,
-    city: string | null = null,
+    location: Coordinates | null = null,
     page: number = 1,
     itemsPerPage = 20
   ): Promise<HydraCollection<PublicEvent>> {
@@ -49,8 +51,8 @@ class PublicEventsProvider extends BaseProvider {
     if (dateMax !== null && dateMax !== '') {
       query.append('datetimeEnd[before]', dateMax)
     }
-    if (city !== null) {
-      query.append('city', city)
+    if (location !== null) {
+      query.append('withinDistance', [location.latitude, location.longitude, LOCATION_RADIUS].join(','))
     }
     if (page !== null) {
       query.append('page', `${page}`)
@@ -64,7 +66,9 @@ class PublicEventsProvider extends BaseProvider {
       url += `?${query}`
     }
 
+    console.log(url)
     return await this.get(url).then((res) => {
+      console.log(res)
       return HydraParser.parseCollection(res, this.normalize)
     })
   }

+ 4 - 2
services/utils/geo.ts

@@ -9,13 +9,15 @@ function toRad (val: number): number {
 
 /**
  * This function takes in latitude and longitude of two location and returns the distance between them as the crow flies (in km)
+ * Implementation of the Haversine formula
+ *
  * @param lat1
  * @param lon1
  * @param lat2
  * @param lon2
  * @returns {number}
  */
-function sphericDistance (lat1: number, lon1: number, lat2: number, lon2: number): number {
+function sphericalDistance (lat1: number, lon1: number, lat2: number, lon2: number): number {
   const R = 6371 // km
   const dLat = toRad(lat2 - lat1)
   const dLon = toRad(lon2 - lon1)
@@ -28,4 +30,4 @@ function sphericDistance (lat1: number, lon1: number, lat2: number, lon2: number
   return R * c
 }
 
-export default sphericDistance
+export default sphericalDistance

+ 2 - 1
tsconfig.json

@@ -30,7 +30,8 @@
       "@nuxtjs/i18n",
       "nuxt-leaflet",
       "@nuxtjs/axios",
-      "@types/node"
+      "@types/node",
+      "@nuxtjs/date-fns"
     ]
   },
   "exclude": [