datastake-daf 0.6.272 → 0.6.273

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,85 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ import mapboxgl from 'mapbox-gl';
3
+ import 'mapbox-gl/dist/mapbox-gl.css';
4
+
5
+ const SimpleGlobeDebug = ({ projects = [] }) => {
6
+ const mapContainer = useRef(null);
7
+ const map = useRef(null);
8
+
9
+ useEffect(() => {
10
+ if (map.current) return; // Initialize map only once
11
+
12
+ // Set Mapbox access token
13
+ mapboxgl.accessToken = 'pk.eyJ1IjoicmVkaXM5OTkiLCJhIjoiY2x4YWV5MzA5MmtuZzJpcXM5Y201Z2E2YiJ9.m5bwPg-Tj4Akesl1yQUa3w';
14
+
15
+ console.log('🗺️ [DEBUG] Creating map...');
16
+
17
+ // Create map
18
+ map.current = new mapboxgl.Map({
19
+ container: mapContainer.current,
20
+ style: 'mapbox://styles/mapbox/satellite-v9',
21
+ center: [0, 0],
22
+ zoom: 3,
23
+ projection: 'globe'
24
+ });
25
+
26
+ // Add markers when map loads
27
+ map.current.on('load', () => {
28
+ console.log('🗺️ [DEBUG] Map loaded, adding markers...');
29
+
30
+ projects.forEach((project, index) => {
31
+ console.log(`📍 [DEBUG] Adding marker ${index}:`, project);
32
+
33
+ // Create marker element
34
+ const el = document.createElement('div');
35
+ el.className = 'mapboxgl-marker';
36
+ el.style.width = '20px';
37
+ el.style.height = '20px';
38
+ el.style.backgroundColor = '#00809E';
39
+ el.style.borderRadius = '50%';
40
+ el.style.border = '2px solid white';
41
+ el.style.cursor = 'pointer';
42
+ el.style.boxShadow = '0px 3.45px 3.45px 0px #00000029';
43
+ el.style.display = 'flex';
44
+ el.style.alignItems = 'center';
45
+ el.style.justifyContent = 'center';
46
+ el.style.color = 'white';
47
+ el.style.fontWeight = 'bold';
48
+ el.innerHTML = `<span>${project.percentageCompletion || 0}</span>`;
49
+
50
+ // Create popup
51
+ const popup = new mapboxgl.Popup({ offset: 25 })
52
+ .setHTML(`
53
+ <div>
54
+ <h3>${project.name}</h3>
55
+ <p>${project.projectDescription || 'No description'}</p>
56
+ <p>Completion: ${project.percentageCompletion || 0}%</p>
57
+ </div>
58
+ `);
59
+
60
+ // Add marker to map
61
+ new mapboxgl.Marker(el)
62
+ .setLngLat([project.longitude, project.latitude])
63
+ .setPopup(popup)
64
+ .addTo(map.current);
65
+
66
+ console.log(`✅ [DEBUG] Marker ${index} added at:`, [project.longitude, project.latitude]);
67
+ });
68
+ });
69
+
70
+ return () => {
71
+ if (map.current) {
72
+ map.current.remove();
73
+ map.current = null;
74
+ }
75
+ };
76
+ }, []);
77
+
78
+ return (
79
+ <div style={{ width: '100%', height: '600px', border: '2px solid #ccc' }}>
80
+ <div ref={mapContainer} style={{ width: '100%', height: '100%' }} />
81
+ </div>
82
+ );
83
+ };
84
+
85
+ export default SimpleGlobeDebug;
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import SimpleGlobe from './SimpleGlobe';
3
+
4
+ // Your sample project data
5
+ const SAMPLE_PROJECTS = [
6
+ {
7
+ _id: "sample-1",
8
+ name: "Dakar Solar Initiative",
9
+ country: "SN",
10
+ datastakeId: "PRJ-SAMPLE-001",
11
+ sectoralScope: "energy",
12
+ percentageCompletion: 75,
13
+ projectDescription: "Large-scale solar energy project in Dakar region",
14
+ latitude: 14.7167,
15
+ longitude: -17.4677,
16
+ author: { name: "Dakar Energy Co." }
17
+ },
18
+ {
19
+ _id: "sample-2",
20
+ name: "Saint-Louis Wind Farm",
21
+ country: "SN",
22
+ datastakeId: "PRJ-SAMPLE-002",
23
+ sectoralScope: "energy",
24
+ percentageCompletion: 45,
25
+ projectDescription: "Wind energy project in Saint-Louis region",
26
+ latitude: 16.0167,
27
+ longitude: -16.4833,
28
+ author: { name: "Wind Power Solutions" }
29
+ },
30
+ {
31
+ _id: "sample-3",
32
+ name: "Casamance Reforestation",
33
+ country: "SN",
34
+ datastakeId: "PRJ-SAMPLE-003",
35
+ sectoralScope: "agricultureForestryAndOtherLandUse",
36
+ percentageCompletion: 60,
37
+ projectDescription: "Forest restoration project in Casamance region",
38
+ latitude: 12.5833,
39
+ longitude: -16.2667,
40
+ author: { name: "Green Casamance" }
41
+ }
42
+ ];
43
+
44
+ /**
45
+ * SimpleGlobeExample - Example usage of the SimpleGlobe component
46
+ *
47
+ * This shows how easy it is to display your project data as pins on a 3D globe.
48
+ * Just pass your project array to the SimpleGlobe component!
49
+ */
50
+ const SimpleGlobeExample = () => {
51
+ const handleProjectClick = (projectData) => {
52
+ console.log('Project clicked:', projectData);
53
+ // You can add your custom logic here, like:
54
+ // - Navigate to project details page
55
+ // - Show project information in a modal
56
+ // - Update application state
57
+ alert(`Clicked on: ${projectData.name}\nCompletion: ${projectData.percentageCompletion}%`);
58
+ };
59
+
60
+ return (
61
+ <div style={{ width: '100%', height: '600px' }}>
62
+ <SimpleGlobe
63
+ projects={SAMPLE_PROJECTS}
64
+ showSider={true}
65
+ onProjectClick={handleProjectClick}
66
+ mapConfig={{
67
+ maxZoom: 8,
68
+ minZoom: 2
69
+ }}
70
+ />
71
+ </div>
72
+ );
73
+ };
74
+
75
+ export default SimpleGlobeExample;
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import SimpleGlobe from './SimpleGlobe';
3
+
4
+ // Test with a simple, known working dataset
5
+ const TEST_PROJECTS = [
6
+ {
7
+ _id: "test-1",
8
+ name: "Test Project 1",
9
+ latitude: 14.7167,
10
+ longitude: -17.4677,
11
+ percentageCompletion: 75,
12
+ projectDescription: "Test project in Dakar"
13
+ },
14
+ {
15
+ _id: "test-2",
16
+ name: "Test Project 2",
17
+ latitude: 16.0167,
18
+ longitude: -16.4833,
19
+ percentageCompletion: 45,
20
+ projectDescription: "Test project in Saint-Louis"
21
+ }
22
+ ];
23
+
24
+ const SimpleGlobeTest = () => {
25
+ console.log('🧪 [SIMPLE GLOBE TEST] Test projects:', TEST_PROJECTS);
26
+
27
+ const handleProjectClick = (projectData) => {
28
+ console.log('🧪 [SIMPLE GLOBE TEST] Project clicked:', projectData);
29
+ alert(`Clicked: ${projectData.name} at ${projectData.gps?.latitude}, ${projectData.gps?.longitude}`);
30
+ };
31
+
32
+ return (
33
+ <div style={{ width: '100%', height: '600px', border: '2px solid #ccc' }}>
34
+ <h3>SimpleGlobe Test</h3>
35
+ <SimpleGlobe
36
+ projects={TEST_PROJECTS}
37
+ showSider={true}
38
+ onProjectClick={handleProjectClick}
39
+ mapConfig={{
40
+ maxZoom: 8,
41
+ minZoom: 2
42
+ }}
43
+ />
44
+ </div>
45
+ );
46
+ };
47
+
48
+ export default SimpleGlobeTest;
@@ -48,15 +48,30 @@ export const useGlobe = ({
48
48
  const isMounted = useRef(true);
49
49
 
50
50
  const addAllDataToMap = useCallback(() => {
51
-
52
- if (!data || !mapRef || !mapRef.isStyleLoaded()) {
51
+ console.log('🚀 [GLOBE HOOK] addAllDataToMap called');
52
+ console.log('🚀 [GLOBE HOOK] data:', data);
53
+ console.log('🚀 [GLOBE HOOK] mapRef exists:', !!mapRef);
54
+ console.log('🚀 [GLOBE HOOK] style loaded:', mapRef?.isStyleLoaded());
55
+
56
+ if (!data || !mapRef) {
57
+ console.log('❌ [GLOBE HOOK] addAllDataToMap early return - missing data or mapRef');
58
+ return;
59
+ }
60
+
61
+ if (!mapRef.isStyleLoaded()) {
62
+ console.log('⏳ [GLOBE HOOK] Style not loaded yet, retrying in 100ms...');
63
+ setTimeout(() => {
64
+ addAllDataToMap();
65
+ }, 100);
53
66
  return;
54
67
  }
55
68
 
56
- // Prevent multiple calls with empty data
57
69
  if (data.length === 0) {
70
+ console.log('❌ [GLOBE HOOK] addAllDataToMap early return - no data');
58
71
  return;
59
72
  }
73
+
74
+ console.log('✅ [GLOBE HOOK] Starting to add markers to map...');
60
75
 
61
76
  // Clear existing markers using functional update to avoid dependency issues
62
77
  setMapMarkers(currentMarkers => {
@@ -108,8 +123,14 @@ export const useGlobe = ({
108
123
  const newMarkers = [];
109
124
  const maxTotal = Math.max(...(data || []).map((d) => d.total || 0));
110
125
 
126
+ console.log('🎯 [GLOBE HOOK] Processing data items:', data.length);
111
127
  data.forEach((d, i) => {
128
+ console.log(`🎯 [GLOBE HOOK] Processing item ${i}:`, d);
129
+ console.log(`🎯 [GLOBE HOOK] Item ${i} marker:`, d?.marker);
130
+ console.log(`🎯 [GLOBE HOOK] Item ${i} lat/lng:`, d?.marker?.lat, d?.marker?.lng);
131
+
112
132
  if (d?.marker?.lat && d?.marker?.lng) {
133
+ console.log(`✅ [GLOBE HOOK] Item ${i} has valid coordinates, creating marker...`);
113
134
  let marker;
114
135
  let iconClassName = "";
115
136
  let innerHtml = "";
@@ -212,6 +233,8 @@ export const useGlobe = ({
212
233
  .setLngLat([d.marker.lng, d.marker.lat])
213
234
  .setPopup(new mapboxgl.Popup().setDOMContent(div))
214
235
  .addTo(mapRef);
236
+
237
+ console.log(`🎉 [GLOBE HOOK] Marker ${i} added to map at:`, [d.marker.lng, d.marker.lat]);
215
238
 
216
239
  } else if (type === "territory") {
217
240
  // Handle territory polygons
@@ -297,6 +320,8 @@ export const useGlobe = ({
297
320
  .setLngLat([d.marker.lng, d.marker.lat])
298
321
  .setPopup(new mapboxgl.Popup().setDOMContent(div))
299
322
  .addTo(mapRef);
323
+
324
+ console.log(`🎉 [GLOBE HOOK] Default marker ${i} added to map at:`, [d.marker.lng, d.marker.lat]);
300
325
  }
301
326
 
302
327
  // Add click handler
@@ -330,6 +355,7 @@ export const useGlobe = ({
330
355
  mapboxgl.accessToken = MAP_TOKEN;
331
356
 
332
357
  // Create the map with Mapbox GL JS - 3D globe
358
+ console.log('🗺️ [GLOBE HOOK] Creating map with style:', STYLE_URL);
333
359
  const map = new mapboxgl.Map({
334
360
  container: container.current,
335
361
  style: STYLE_URL,
@@ -348,9 +374,13 @@ export const useGlobe = ({
348
374
 
349
375
  // Configure the map when style loads
350
376
  map.on('style.load', () => {
377
+ console.log('🎨 [GLOBE HOOK] Style loaded event triggered');
378
+ console.log('🎨 [GLOBE HOOK] Map style loaded:', map.isStyleLoaded());
351
379
 
352
380
  // Wait a bit for the style to fully load
353
381
  setTimeout(() => {
382
+ console.log('🎨 [GLOBE HOOK] After timeout - Map style loaded:', map.isStyleLoaded());
383
+
354
384
  // Set fog for the space background effect with stars - simplified to avoid errors
355
385
  try {
356
386
  map.setFog({
@@ -445,9 +475,10 @@ export const useGlobe = ({
445
475
  // Add navigation controls
446
476
  map.addControl(new mapboxgl.NavigationControl(), 'top-right');
447
477
 
478
+ console.log('🗺️ [GLOBE HOOK] Map created successfully');
448
479
  return map;
449
480
  } catch (error) {
450
- console.error('Error creating Mapbox GL JS globe:', error);
481
+ console.error('❌ [GLOBE HOOK] Error creating Mapbox GL JS globe:', error);
451
482
  return null;
452
483
  }
453
484
  }, []);
@@ -460,10 +491,13 @@ export const useGlobe = ({
460
491
  // }, [initialMarkerSetIsDone]);
461
492
 
462
493
  useEffect(() => {
494
+ console.log('🔄 [GLOBE HOOK] useEffect for map creation - mapRef:', !!mapRef);
463
495
 
464
496
  if (!mapRef) {
497
+ console.log('🔄 [GLOBE HOOK] Creating map instance...');
465
498
  const instance = createInstance();
466
499
  if (instance) {
500
+ console.log('🔄 [GLOBE HOOK] Map instance created, setting mapRef');
467
501
  setMapRef(instance);
468
502
 
469
503
  // Add comprehensive resize detection for Mapbox GL JS responsiveness
@@ -552,15 +586,24 @@ export const useGlobe = ({
552
586
  }, [polygon, mapRef]);
553
587
 
554
588
  useEffect(() => {
555
-
589
+ console.log('📥 [GLOBE HOOK] allData received:', allData);
590
+ console.log('📥 [GLOBE HOOK] allData length:', allData?.length);
591
+
556
592
  if (allData) {
557
593
  if (allData.length === 0) {
594
+ console.log('⚠️ [GLOBE HOOK] Empty data array');
558
595
  setEmptyStateIsVisible(true);
559
596
  } else if (emptyStateIsVisible) {
560
597
  setEmptyStateIsVisible(false);
561
598
  }
562
- setData(filterValidGPS(allData));
599
+
600
+ console.log('🔍 [GLOBE HOOK] Filtering data with filterValidGPS...');
601
+ const filteredData = filterValidGPS(allData);
602
+ console.log('🔍 [GLOBE HOOK] filtered data result:', filteredData);
603
+ console.log('🔍 [GLOBE HOOK] filtered data length:', filteredData.length);
604
+ setData(filteredData);
563
605
  } else {
606
+ console.log('❌ [GLOBE HOOK] No allData provided');
564
607
  setData(null);
565
608
  }
566
609
  }, [allData, emptyStateIsVisible]);
@@ -591,7 +634,20 @@ export const useGlobe = ({
591
634
  }, [user, mapRef, allData]);
592
635
 
593
636
  useEffect(() => {
594
- if (mapRef && data && !initialMarkerSetIsDone && mapRef.isStyleLoaded()) {
637
+ console.log('🔄 [GLOBE HOOK] useEffect triggered:', {
638
+ mapRef: !!mapRef,
639
+ data: !!data,
640
+ dataLength: data?.length,
641
+ initialMarkerSetIsDone,
642
+ styleLoaded: mapRef?.isStyleLoaded()
643
+ });
644
+
645
+ if (mapRef && data && !initialMarkerSetIsDone) {
646
+ console.log('🚀 [GLOBE HOOK] Attempting to add markers...');
647
+ console.log('🚀 [GLOBE HOOK] Style loaded check:', mapRef.isStyleLoaded());
648
+
649
+ // Try to add markers immediately, and if style isn't loaded,
650
+ // the addAllDataToMap function will handle it
595
651
  setInitialMarkerSetIsDone(true);
596
652
  addAllDataToMap();
597
653
  }
@@ -111,7 +111,7 @@ function Globe({
111
111
  renderSider = null,
112
112
  renderMarker = null,
113
113
  type = "default",
114
- showSider = true,
114
+ showSider = false,
115
115
  filtersConfig,
116
116
  onFilterChange = () => { },
117
117
  isSatellite = false,
@@ -122,11 +122,29 @@ function Globe({
122
122
  }) {
123
123
  // Map data to include marker coordinates
124
124
  const mappedData = useMemo(
125
- () =>
126
- data.map((d) => ({
127
- ...d,
128
- marker: { lat: d?.gps?.latitude, lng: d?.gps?.longitude },
129
- })),
125
+ () => {
126
+ console.log('📊 [GLOBE COMPONENT] Original data received:', data);
127
+ console.log('📊 [GLOBE COMPONENT] Data length:', data?.length);
128
+
129
+ if (!data || data.length === 0) {
130
+ console.log('❌ [GLOBE COMPONENT] No data to map');
131
+ return [];
132
+ }
133
+
134
+ const mapped = data.map((d, i) => {
135
+ console.log(`📊 [GLOBE COMPONENT] Mapping item ${i}:`, d);
136
+ console.log(`📊 [GLOBE COMPONENT] Item ${i} GPS:`, d?.gps);
137
+ const result = {
138
+ ...d,
139
+ marker: { lat: d?.gps?.latitude, lng: d?.gps?.longitude },
140
+ };
141
+ console.log(`📊 [GLOBE COMPONENT] Item ${i} mapped result:`, result);
142
+ return result;
143
+ });
144
+
145
+ console.log('📊 [GLOBE COMPONENT] Final mapped data:', mapped);
146
+ return mapped;
147
+ },
130
148
  [data],
131
149
  );
132
150
 
@@ -0,0 +1,243 @@
1
+ import { storyConfig as EventConfig } from "./storyConfig1.js";
2
+ // Create default configs since the other files were deleted
3
+ const DefaultGlobeConfig = {
4
+ data: [
5
+ {
6
+ gps: { latitude: 40.7128, longitude: -74.0060 },
7
+ name: "New York City",
8
+ description: "Major metropolitan area in the United States",
9
+ total: 15,
10
+ sources: 3,
11
+ },
12
+ {
13
+ gps: { latitude: 51.5074, longitude: -0.1278 },
14
+ name: "London",
15
+ description: "Capital of the United Kingdom",
16
+ total: 12,
17
+ sources: 2,
18
+ },
19
+ {
20
+ gps: { latitude: 35.6762, longitude: 139.6503 },
21
+ name: "Tokyo",
22
+ description: "Capital of Japan",
23
+ total: 8,
24
+ sources: 1,
25
+ },
26
+ {
27
+ gps: { latitude: -33.8688, longitude: 151.2093 },
28
+ name: "Sydney",
29
+ description: "Major city in Australia",
30
+ total: 6,
31
+ sources: 2,
32
+ },
33
+ {
34
+ gps: { latitude: -22.9068, longitude: -43.1729 },
35
+ name: "Rio de Janeiro",
36
+ description: "Major city in Brazil",
37
+ total: 10,
38
+ sources: 1,
39
+ },
40
+ ],
41
+ renderTooltip: (data) => [
42
+ { label: "City", value: data.name || "-" },
43
+ { label: "Total Events", value: data.total || 0 },
44
+ { label: "Sources", value: data.sources || 0 },
45
+ { label: "Description", value: data.description || "-" },
46
+ ],
47
+ primaryLink: true,
48
+ showSider: false,
49
+ };
50
+
51
+ const TerritoryGlobeConfig = {
52
+ data: [
53
+ {
54
+ gps: { latitude: 39.9042, longitude: 116.4074 },
55
+ name: "Beijing Territory",
56
+ description: "Administrative region in China",
57
+ total: 25,
58
+ sources: 4,
59
+ },
60
+ {
61
+ gps: { latitude: 55.7558, longitude: 37.6176 },
62
+ name: "Moscow Region",
63
+ description: "Federal subject of Russia",
64
+ total: 18,
65
+ sources: 3,
66
+ },
67
+ {
68
+ gps: { latitude: -26.2041, longitude: 28.0473 },
69
+ name: "Gauteng Province",
70
+ description: "Province in South Africa",
71
+ total: 14,
72
+ sources: 2,
73
+ },
74
+ {
75
+ gps: { latitude: 19.4326, longitude: -99.1332 },
76
+ name: "Mexico City Territory",
77
+ description: "Federal district in Mexico",
78
+ total: 20,
79
+ sources: 3,
80
+ },
81
+ ],
82
+ renderTooltip: (data) => [
83
+ { label: "Territory", value: data.name || "-" },
84
+ { label: "Total Events", value: data.total || 0 },
85
+ { label: "Sources", value: data.sources || 0 },
86
+ { label: "Description", value: data.description || "-" },
87
+ ],
88
+ primaryLink: true,
89
+ showSider: false,
90
+ };
91
+
92
+ const StakeholderGlobeConfig = {
93
+ data: [
94
+ {
95
+ gps: { latitude: 48.8566, longitude: 2.3522 },
96
+ name: "Paris NGO",
97
+ description: "Environmental NGO in France",
98
+ total: 12,
99
+ sources: 2,
100
+ },
101
+ {
102
+ gps: { latitude: 37.7749, longitude: -122.4194 },
103
+ name: "San Francisco Tech",
104
+ description: "Technology company in California",
105
+ total: 8,
106
+ sources: 1,
107
+ },
108
+ {
109
+ gps: { latitude: 1.3521, longitude: 103.8198 },
110
+ name: "Singapore Corp",
111
+ description: "Multinational corporation",
112
+ total: 15,
113
+ sources: 3,
114
+ },
115
+ {
116
+ gps: { latitude: 52.5200, longitude: 13.4050 },
117
+ name: "Berlin Institute",
118
+ description: "Research institute in Germany",
119
+ total: 9,
120
+ sources: 2,
121
+ },
122
+ {
123
+ gps: { latitude: -34.6037, longitude: -58.3816 },
124
+ name: "Buenos Aires Union",
125
+ description: "Labor union in Argentina",
126
+ total: 11,
127
+ sources: 1,
128
+ },
129
+ ],
130
+ renderTooltip: (data) => [
131
+ { label: "Stakeholder", value: data.name || "-" },
132
+ { label: "Total Events", value: data.total || 0 },
133
+ { label: "Sources", value: data.sources || 0 },
134
+ { label: "Description", value: data.description || "-" },
135
+ ],
136
+ primaryLink: true,
137
+ showSider: false,
138
+ };
139
+
140
+ const ChainGlobeConfig = {
141
+ data: [
142
+ {
143
+ gps: { latitude: 23.1291, longitude: 113.2644 },
144
+ name: "Guangzhou Manufacturing",
145
+ description: "Electronics manufacturing hub in China",
146
+ total: 22,
147
+ sources: 4,
148
+ },
149
+ {
150
+ gps: { latitude: 12.9716, longitude: 77.5946 },
151
+ name: "Bangalore Tech Hub",
152
+ description: "Software development center in India",
153
+ total: 18,
154
+ sources: 3,
155
+ },
156
+ {
157
+ gps: { latitude: 41.8781, longitude: -87.6298 },
158
+ name: "Chicago Logistics",
159
+ description: "Transportation and logistics hub in USA",
160
+ total: 16,
161
+ sources: 2,
162
+ },
163
+ {
164
+ gps: { latitude: 25.2048, longitude: 55.2708 },
165
+ name: "Dubai Trade Center",
166
+ description: "International trade and commerce hub",
167
+ total: 14,
168
+ sources: 3,
169
+ },
170
+ {
171
+ gps: { latitude: -23.5505, longitude: -46.6333 },
172
+ name: "São Paulo Distribution",
173
+ description: "Distribution center in Brazil",
174
+ total: 12,
175
+ sources: 2,
176
+ },
177
+ ],
178
+ renderTooltip: (data) => [
179
+ { label: "Supply Chain Node", value: data.name || "-" },
180
+ { label: "Total Events", value: data.total || 0 },
181
+ { label: "Sources", value: data.sources || 0 },
182
+ { label: "Description", value: data.description || "-" },
183
+ ],
184
+ primaryLink: true,
185
+ showSider: false,
186
+ };
187
+
188
+ const ProjectGlobeConfig = {
189
+ data: [
190
+ {
191
+ gps: { latitude: 6.5244, longitude: 3.3792 },
192
+ name: "Lagos Solar Project",
193
+ description: "Renewable energy project in Nigeria",
194
+ total: 8,
195
+ sources: 2,
196
+ },
197
+ {
198
+ gps: { latitude: -1.2921, longitude: 36.8219 },
199
+ name: "Nairobi Water Initiative",
200
+ description: "Water management project in Kenya",
201
+ total: 12,
202
+ sources: 3,
203
+ },
204
+ {
205
+ gps: { latitude: 13.7563, longitude: 100.5018 },
206
+ name: "Bangkok Green City",
207
+ description: "Urban sustainability project in Thailand",
208
+ total: 15,
209
+ sources: 4,
210
+ },
211
+ {
212
+ gps: { latitude: -12.0464, longitude: -77.0428 },
213
+ name: "Lima Education Hub",
214
+ description: "Educational development project in Peru",
215
+ total: 10,
216
+ sources: 2,
217
+ },
218
+ {
219
+ gps: { latitude: 30.0444, longitude: 31.2357 },
220
+ name: "Cairo Infrastructure",
221
+ description: "Infrastructure development project in Egypt",
222
+ total: 14,
223
+ sources: 3,
224
+ },
225
+ {
226
+ gps: { latitude: 55.7558, longitude: 37.6176 },
227
+ name: "Moscow Innovation Center",
228
+ description: "Technology innovation project in Russia",
229
+ total: 9,
230
+ sources: 2,
231
+ },
232
+ ],
233
+ renderTooltip: (data) => [
234
+ { label: "Project Name", value: data.name || "-" },
235
+ { label: "Total Events", value: data.total || 0 },
236
+ { label: "Sources", value: data.sources || 0 },
237
+ { label: "Description", value: data.description || "-" },
238
+ ],
239
+ primaryLink: true,
240
+ showSider: false,
241
+ };
242
+
243
+ export { DefaultGlobeConfig, TerritoryGlobeConfig, StakeholderGlobeConfig, EventConfig, ChainGlobeConfig, ProjectGlobeConfig };