From 845933c33c720cb144c840d5c534fe043cd6f9ac Mon Sep 17 00:00:00 2001 From: kdeterme Date: Wed, 5 Aug 2026 15:30:06 +0200 Subject: [PATCH] feat: implement GPS navigation integration with modal selection and persistent provider preferences --- .../interventions/mobile/gps_navigation.js | 128 ++++++++++++++++++ .../_interventions_list_mobile.html | 22 ++- .../includes/_gps_navigation_modal.html | 62 +++++++++ .../intervention_detail_mobile.html | 35 +++-- .../interventions_index_mobile.html | 13 +- 5 files changed, 245 insertions(+), 15 deletions(-) create mode 100644 streetup/interventions/static/interventions/mobile/gps_navigation.js create mode 100644 streetup/interventions/templates/interventions/includes/_gps_navigation_modal.html diff --git a/streetup/interventions/static/interventions/mobile/gps_navigation.js b/streetup/interventions/static/interventions/mobile/gps_navigation.js new file mode 100644 index 0000000..c8e3f5c --- /dev/null +++ b/streetup/interventions/static/interventions/mobile/gps_navigation.js @@ -0,0 +1,128 @@ +/** + * Helper JS pour la gestion de la navigation GPS dans StreetUp Mobile. + */ +(function(window) { + 'use strict'; + + let activeGpsLat = null; + let activeGpsLon = null; + + /** + * Ouvre le modal de sélection GPS ou lance le GPS préféré s'il est enregistré. + * @param {number|string} lat Latitude + * @param {number|string} lon Longitude + * @param {string} [label] Libellé/Code de l'intervention + * @param {boolean} [forceModal=false] Forcer l'affichage du modal même si une préférence existe + * @param {Event} [event=null] Événement clic pour stopper la propagation + */ + function openGpsNavigation(lat, lon, label, forceModal, event) { + if (event) { + event.stopPropagation(); + event.preventDefault(); + } + + if (!lat || !lon || isNaN(parseFloat(lat)) || isNaN(parseFloat(lon))) { + if (window.toast || window.alert) { + alert("Aucune coordonnée GPS disponible pour cette intervention."); + } + return; + } + + activeGpsLat = parseFloat(lat); + activeGpsLon = parseFloat(lon); + + const preferredProvider = localStorage.getItem('streetup_preferred_gps'); + + if (preferredProvider && !forceModal) { + launchGpsProvider(preferredProvider); + return; + } + + const modalEl = document.getElementById('gpsNavigationModal'); + if (!modalEl) { + console.error("Modal #gpsNavigationModal introuvable."); + return; + } + + const destLabelEl = document.getElementById('gpsModalDestinationLabel'); + if (destLabelEl) { + if (label) { + destLabelEl.textContent = "Itinéraire vers : " + label; + } else { + destLabelEl.textContent = "Choisissez votre application de navigation :"; + } + } + + const rememberCheckbox = document.getElementById('gpsRememberChoice'); + if (rememberCheckbox) { + rememberCheckbox.checked = !!preferredProvider; + } + + const bsModal = bootstrap.Modal.getOrCreateInstance(modalEl); + bsModal.show(); + } + + /** + * Lance la navigation avec l'application choisie. + * @param {string} provider 'google', 'waze', 'apple', ou 'geo' + */ + function launchGpsProvider(provider) { + if (!activeGpsLat || !activeGpsLon) return; + + const rememberCheckbox = document.getElementById('gpsRememberChoice'); + if (rememberCheckbox && rememberCheckbox.checked) { + localStorage.setItem('streetup_preferred_gps', provider); + } else { + localStorage.removeItem('streetup_preferred_gps'); + } + + let url = ''; + const lat = activeGpsLat; + const lon = activeGpsLon; + + switch (provider) { + case 'google': + url = `https://www.google.com/maps/dir/?api=1&destination=${lat},${lon}`; + break; + case 'waze': + url = `https://waze.com/ul?ll=${lat},${lon}&navigate=yes`; + break; + case 'apple': + url = `https://maps.apple.com/?daddr=${lat},${lon}`; + break; + case 'geo': + url = `geo:${lat},${lon}?q=${lat},${lon}`; + break; + default: + url = `https://www.google.com/maps/dir/?api=1&destination=${lat},${lon}`; + } + + const modalEl = document.getElementById('gpsNavigationModal'); + if (modalEl) { + const bsModal = bootstrap.Modal.getInstance(modalEl); + if (bsModal) { + bsModal.hide(); + } + } + + // Pour les schémas personnalisés/intentions comme geo:, window.location.href fonctionne mieux + if (provider === 'geo' || provider === 'apple' || provider === 'waze') { + window.location.href = url; + } else { + window.open(url, '_blank', 'noopener,noreferrer'); + } + } + + /** + * Réinitialise la préférence de GPS sélectionnée. + */ + function resetGpsPreference() { + localStorage.removeItem('streetup_preferred_gps'); + } + + // Exposer les fonctions globalement + window.openGpsNavigation = openGpsNavigation; + window.launchGpsProvider = launchGpsProvider; + window.resetGpsPreference = resetGpsPreference; + +})(window); diff --git a/streetup/interventions/templates/interventions/_interventions_list_mobile.html b/streetup/interventions/templates/interventions/_interventions_list_mobile.html index 90dddf7..222353e 100644 --- a/streetup/interventions/templates/interventions/_interventions_list_mobile.html +++ b/streetup/interventions/templates/interventions/_interventions_list_mobile.html @@ -69,11 +69,23 @@ {% endif %} - {% if not intervention.assigned_member %} - - {% else %} - - {% endif %} +
+ {% if intervention.lat and intervention.lon %} + + {% endif %} + {% if not intervention.assigned_member %} + + {% else %} + + {% endif %} +
{% empty %} diff --git a/streetup/interventions/templates/interventions/includes/_gps_navigation_modal.html b/streetup/interventions/templates/interventions/includes/_gps_navigation_modal.html new file mode 100644 index 0000000..e4c08ab --- /dev/null +++ b/streetup/interventions/templates/interventions/includes/_gps_navigation_modal.html @@ -0,0 +1,62 @@ +{% load i18n %} + + + diff --git a/streetup/interventions/templates/interventions/intervention_detail_mobile.html b/streetup/interventions/templates/interventions/intervention_detail_mobile.html index 5dcbed7..7903c0d 100644 --- a/streetup/interventions/templates/interventions/intervention_detail_mobile.html +++ b/streetup/interventions/templates/interventions/intervention_detail_mobile.html @@ -506,13 +506,23 @@

{{ intervention.planned_begin_time|date:"d/m/Y H:i"|default:"/" }}

-

- {{ intervention.get_maintain_type_display }} +

+ + {{ intervention.get_maintain_type_display }} + + {% if intervention.lat and intervention.lon %} + + {% endif %}

{% include "interventions/includes/_operation_comment_modal.html" %} @@ -2331,10 +2341,19 @@ {% translate "Carte" %} - +
+ + +
+ +{% include "interventions/includes/_gps_navigation_modal.html" %} + {% endif %} diff --git a/streetup/interventions/templates/interventions/interventions_index_mobile.html b/streetup/interventions/templates/interventions/interventions_index_mobile.html index 467a91f..d2f3d7e 100644 --- a/streetup/interventions/templates/interventions/interventions_index_mobile.html +++ b/streetup/interventions/templates/interventions/interventions_index_mobile.html @@ -253,9 +253,13 @@
+ + + {% include "interventions/includes/_gps_navigation_modal.html" %} {% endblock content %} {% block extra_scripts %} +