Skip to content

Commit

Permalink
Merge branch 'staging' into analytics-data-download
Browse files Browse the repository at this point in the history
  • Loading branch information
OchiengPaul442 committed Mar 8, 2025
2 parents 0080ab7 + 7c88999 commit 2a07057
Show file tree
Hide file tree
Showing 30 changed files with 1,030 additions and 732 deletions.
2 changes: 1 addition & 1 deletion k8s/platform/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ replicaCount: 1
image:
repository: eu.gcr.io/airqo-250220/airqo-next-platform
pullPolicy: Always
tag: prod-6a098ecd-1740727843
tag: prod-e85de0ae-1741457587
imagePullSecrets: []
nameOverride: ''
fullnameOverride: ''
Expand Down
2 changes: 1 addition & 1 deletion k8s/platform/values-stage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ replicaCount: 1
image:
repository: eu.gcr.io/airqo-250220/airqo-stage-next-platform
pullPolicy: Always
tag: stage-93a63a9e-1740727732
tag: stage-ad93b232-1741457506
imagePullSecrets: []
nameOverride: ''
fullnameOverride: ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,39 @@ const OrganizationDropdown = () => {

// Initialize active group if missing
useEffect(() => {
// If we're still fetching, do nothing yet
if (isFetchingActiveGroup) return;

const storedGroup = localStorage.getItem('activeGroup');
if (storedGroup) {
const defaultGroup = JSON.parse(storedGroup);
dispatch(setOrganizationName(defaultGroup.grp_title));
try {
// Attempt to parse the stored group
const defaultGroup = JSON.parse(storedGroup);

// Check if defaultGroup and its properties exist
if (defaultGroup && defaultGroup.grp_title) {
dispatch(setOrganizationName(defaultGroup.grp_title));
} else {
// If the stored data is missing expected fields, remove it
localStorage.removeItem('activeGroup');
console.warn(
'activeGroup in localStorage is missing grp_title, removing it...',
);
}
} catch (error) {
// If JSON parsing fails, remove the invalid item
console.error('Error parsing activeGroup from localStorage:', error);
localStorage.removeItem('activeGroup');
}
} else if (!activeGroupId && activeGroups.length > 0) {
// No activeGroup in localStorage, so pick the first available group
const defaultGroup = activeGroups[0];
localStorage.setItem('activeGroup', JSON.stringify(defaultGroup));
dispatch(setOrganizationName(defaultGroup.grp_title));
if (defaultGroup && defaultGroup.grp_title) {
dispatch(setOrganizationName(defaultGroup.grp_title));
}
}
}, [activeGroupId, activeGroups, dispatch]);
}, [isFetchingActiveGroup, activeGroupId, activeGroups, dispatch]);

const handleUpdatePreferences = useCallback(
async (group) => {
Expand Down
107 changes: 59 additions & 48 deletions src/platform/src/common/components/Map/AirQoMap.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// AirQoMap.jsx
import React, { useEffect, useRef, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import mapboxgl from 'mapbox-gl';
Expand Down Expand Up @@ -47,16 +48,20 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
'mapbox://styles/mapbox/streets-v11',
);

// Parse and Validate URL Parameters
// Parse and validate URL parameters
let latParam, lngParam, zmParam;
let hasValidParams = false;

if (typeof window !== 'undefined') {
const urlParams = new URLSearchParams(window.location.search);
latParam = parseFloat(urlParams.get('lat'));
lngParam = parseFloat(urlParams.get('lng'));
zmParam = parseFloat(urlParams.get('zm'));
hasValidParams = !isNaN(latParam) && !isNaN(lngParam) && !isNaN(zmParam);
try {
const urlParams = new URLSearchParams(window.location.search);
latParam = parseFloat(urlParams.get('lat'));
lngParam = parseFloat(urlParams.get('lng'));
zmParam = parseFloat(urlParams.get('zm'));
hasValidParams = !isNaN(latParam) && !isNaN(lngParam) && !isNaN(zmParam);
} catch (error) {
console.error('Error parsing URL parameters:', error);
hasValidParams = false;
}
}

// Redux Selectors
Expand All @@ -79,14 +84,14 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
);
const shareLocation = useShareLocation(setToastMessage, mapRef);

// Clear Data on Unmount
// Clear data on unmount
useEffect(() => {
return () => {
dispatch(clearData());
};
}, [dispatch]);

// Set Center and Zoom Based on URL Params or Reset Map
// Set center and zoom based on URL parameters or reset map
useEffect(() => {
if (hasValidParams) {
dispatch(setCenter({ latitude: latParam, longitude: lngParam }));
Expand All @@ -96,18 +101,17 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
}
}, [hasValidParams, latParam, lngParam, zmParam, dispatch]);

// Initialize Map
// Initialize the map
useEffect(() => {
const initializeMap = async () => {
try {
mapboxgl.accessToken = mapboxApiAccessToken;

const initialCenter = hasValidParams
? [lngParam, latParam]
: [mapData.center.longitude, mapData.center.latitude];
const initialZoom = hasValidParams ? zmParam : mapData.zoom;

if (!mapContainerRef.current) return; // Ensure container exists
if (!mapContainerRef.current) return;

const map = new mapboxgl.Map({
container: mapContainerRef.current,
Expand All @@ -119,21 +123,25 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
mapRef.current = map;

map.on('load', () => {
map.resize();

// Add controls conditionally
if (!(width < 1024 && selectedNode)) {
map.addControl(new CustomZoomControl(dispatch), 'bottom-right');
map.addControl(
new CustomGeolocateControl(setToastMessage),
'bottom-right',
);
try {
map.resize();

// Conditionally add controls
if (!(width < 1024 && selectedNode)) {
map.addControl(new CustomZoomControl(), 'bottom-right');
map.addControl(
new CustomGeolocateControl(setToastMessage),
'bottom-right',
);
}

// Fetch data after the map is loaded
fetchAndProcessData();
setLoading(false);
dispatch(setMapLoading(false));
} catch (err) {
console.error('Error during map load event:', err);
}

// Fetch data once map is loaded
fetchAndProcessData();
setLoading(false);
dispatch(setMapLoading(false));
});

map.on('error', (e) => {
Expand All @@ -153,15 +161,18 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
if (!mapRef.current) {
initializeMap();
} else {
// Update the map's style, center, and zoom
mapRef.current.setStyle(mapStyle);
mapRef.current.flyTo({
center: hasValidParams
? [lngParam, latParam]
: [mapData.center.longitude, mapData.center.latitude],
zoom: hasValidParams ? zmParam : mapData.zoom,
essential: true,
});
try {
mapRef.current.setStyle(mapStyle);
mapRef.current.flyTo({
center: hasValidParams
? [lngParam, latParam]
: [mapData.center.longitude, mapData.center.latitude],
zoom: hasValidParams ? zmParam : mapData.zoom,
essential: true,
});
} catch (error) {
console.error('Error updating map style:', error);
}
}

return () => {
Expand All @@ -172,39 +183,37 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
};
}, [mapStyle, NodeType, mapboxApiAccessToken, width]);

// Manage Loading State Timeout
// Manage loading state timeout
useEffect(() => {
if (loading) {
const loaderTimer = setTimeout(() => {
if (!mapRef.current || mapRef.current.isStyleLoaded()) {
setLoading(false);
}
}, 10000);

return () => clearTimeout(loaderTimer);
}
}, [loading]);

// Handle Node Selection Loading
// Handle node selection loading
useEffect(() => {
if (selectedNode) {
const skeletonTimer = setTimeout(() => {
dispatch(setMapLoading(false));
setLoading(false);
}, 2000);

return () => clearTimeout(skeletonTimer);
}
}, [dispatch, selectedNode]);

// Handle Location Boundaries
// Handle location boundaries with improved error handling in the hook
useLocationBoundaries({
mapRef,
mapData,
setLoading,
});

// Fly to New Center and Zoom When Map Data Changes
// Fly to new center and zoom when map data changes
useEffect(() => {
if (mapRef.current && mapData.center && mapData.zoom) {
const { latitude, longitude } = mapData.center;
Expand All @@ -225,7 +234,7 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
zmParam,
]);

// Update Clusters When Data Changes
// Update clusters when data changes
useEffect(() => {
if (mapRef.current) {
try {
Expand All @@ -236,20 +245,22 @@ const AirQoMap = ({ customStyle, mapboxApiAccessToken, pollutant }) => {
}
}, [clusterUpdate]);

// Handle Window Resize
// Handle window resize events
useEffect(() => {
const handleResize = () => {
if (mapRef.current && mapRef.current.isStyleLoaded()) {
mapRef.current.resize();
try {
if (mapRef.current && mapRef.current.isStyleLoaded()) {
mapRef.current.resize();
}
} catch (error) {
console.error('Error handling window resize:', error);
}
};

window.addEventListener('resize', handleResize);
handleResize();

return () => {
window.removeEventListener('resize', handleResize);
};
return () => window.removeEventListener('resize', handleResize);
}, [selectedNode]);

return (
Expand Down
Loading

0 comments on commit 2a07057

Please sign in to comment.