@@ -29,6 +29,8 @@ export default class MapLeafletLiveMapComponent extends Component {
2929 @service intl ;
3030 @service universe ;
3131 @service ( 'universe/menu-service' ) menuService ;
32+ @service geofenceEventBus ;
33+ @service currentUser ;
3234
3335 /** properties */
3436 id = guidFor ( this ) ;
@@ -57,6 +59,19 @@ export default class MapLeafletLiveMapComponent extends Component {
5759
5860 // Ensure we have valid coordinates on initialization
5961 this . #updateCoordinatesFromLocation( ) ;
62+
63+ if ( this . currentUser . companyId ) {
64+ this . geofenceEventBus . subscribe ( this . currentUser . companyId ) ;
65+ } else {
66+ this . _currentUserLoadedHandler = ( ) => this . geofenceEventBus . subscribe ( this . currentUser . companyId ) ;
67+ this . currentUser . on ( 'user.loaded' , this . _currentUserLoadedHandler ) ;
68+ }
69+
70+ // Subscribe to geofence events so the live map can react to boundary crossings
71+ this . _geofenceEnteredHandler = this . #handleGeofenceEntered. bind ( this ) ;
72+ this . _geofenceExitedHandler = this . #handleGeofenceExited. bind ( this ) ;
73+ this . universe . on ( 'fleet-ops.geofence.entered' , this . _geofenceEnteredHandler ) ;
74+ this . universe . on ( 'fleet-ops.geofence.exited' , this . _geofenceExitedHandler ) ;
6075 }
6176
6277 willDestroy ( ) {
@@ -67,6 +82,18 @@ export default class MapLeafletLiveMapComponent extends Component {
6782 this . universe . off ( 'user.located' , this . _locationUpdateHandler ) ;
6883 this . _locationUpdateHandler = null ;
6984 }
85+ if ( this . _currentUserLoadedHandler ) {
86+ this . currentUser . off ( 'user.loaded' , this . _currentUserLoadedHandler ) ;
87+ this . _currentUserLoadedHandler = null ;
88+ }
89+ if ( this . _geofenceEnteredHandler ) {
90+ this . universe . off ( 'fleet-ops.geofence.entered' , this . _geofenceEnteredHandler ) ;
91+ this . _geofenceEnteredHandler = null ;
92+ }
93+ if ( this . _geofenceExitedHandler ) {
94+ this . universe . off ( 'fleet-ops.geofence.exited' , this . _geofenceExitedHandler ) ;
95+ this . _geofenceExitedHandler = null ;
96+ }
7097 }
7198
7299 @action didLoad ( { target : map } ) {
@@ -259,6 +286,62 @@ export default class MapLeafletLiveMapComponent extends Component {
259286 return 14 ;
260287 }
261288
289+ /**
290+ * Handles a geofence.entered event from the GeofenceEventBus.
291+ * Briefly highlights the geofence layer on the map to provide visual feedback.
292+ *
293+ * @param {Object } event - Normalised geofence event object
294+ */
295+ #handleGeofenceEntered( event ) {
296+ debug ( `[LiveMap] geofence.entered — driver: ${ event . driverName } , geofence: ${ event . geofenceName } ` ) ;
297+ this . #flashGeofenceLayer( event . geofenceUuid , '#22c55e' ) ; // green
298+ }
299+
300+ /**
301+ * Handles a geofence.exited event from the GeofenceEventBus.
302+ * Briefly highlights the geofence layer on the map to provide visual feedback.
303+ *
304+ * @param {Object } event - Normalised geofence event object
305+ */
306+ #handleGeofenceExited( event ) {
307+ debug ( `[LiveMap] geofence.exited — driver: ${ event . driverName } , geofence: ${ event . geofenceName } ` ) ;
308+ this . #flashGeofenceLayer( event . geofenceUuid , '#ef4444' ) ; // red
309+ }
310+
311+ /**
312+ * Briefly changes the fill colour of a geofence polygon layer on the map
313+ * to provide visual feedback when a driver enters or exits.
314+ *
315+ * @param {string } geofenceUuid - UUID of the zone or service area
316+ * @param {string } flashColor - Hex colour to flash
317+ */
318+ #flashGeofenceLayer( geofenceUuid , flashColor ) {
319+ if ( ! geofenceUuid || ! this . map ) {
320+ return ;
321+ }
322+
323+ // Iterate over all Leaflet layers to find the matching geofence polygon
324+ this . map . eachLayer ( ( layer ) => {
325+ const model = layer . _model ;
326+ if ( model && model . uuid === geofenceUuid && typeof layer . setStyle === 'function' ) {
327+ const originalStyle = {
328+ color : layer . options . color ,
329+ fillColor : layer . options . fillColor ,
330+ weight : layer . options . weight ,
331+ } ;
332+
333+ // Flash to the event colour
334+ layer . setStyle ( { color : flashColor , fillColor : flashColor , weight : 3 } ) ;
335+
336+ // Restore original style after 2 seconds
337+ setTimeout ( ( ) => {
338+ if ( ! layer . _map ) return ; // layer may have been removed
339+ layer . setStyle ( originalStyle ) ;
340+ } , 2000 ) ;
341+ }
342+ } ) ;
343+ }
344+
262345 /**
263346 * Handles location updates from the location service
264347 * @param {Object } coordinates - The new coordinates
0 commit comments