datastake-daf 0.6.280 β 0.6.281
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.
- package/dist/components/index.js +387 -15
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/Globe/Globe.stories.js +30 -5
- package/src/@daf/core/components/Dashboard/Globe/README.md +106 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobe.jsx +331 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobe.stories.js +284 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobeDebug.jsx +85 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobeExample.jsx +75 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobeTest.jsx +48 -0
- package/src/@daf/core/components/Dashboard/Globe/hook.js +63 -7
- package/src/@daf/core/components/Dashboard/Globe/index.jsx +24 -6
- package/src/@daf/core/components/Dashboard/Globe/storyConfig.js +243 -0
- package/src/@daf/core/components/Dashboard/Globe/storyConfig1.js +354 -0
- package/src/@daf/core/components/Dashboard/Globe/style.js +29 -0
- package/src/index.js +1 -0
- package/.env +0 -8
- package/.vscode/settings.json +0 -13
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import SimpleGlobe from "./SimpleGlobe";
|
|
2
|
+
import SimpleGlobeDebug from "./SimpleGlobeDebug";
|
|
3
|
+
import ThemeLayout from "../../ThemeLayout";
|
|
4
|
+
import Widget from "../Widget";
|
|
5
|
+
|
|
6
|
+
// Sample project data
|
|
7
|
+
const SAMPLE_PROJECTS = [
|
|
8
|
+
{
|
|
9
|
+
_id: "sample-1",
|
|
10
|
+
name: "Dakar Solar Initiative",
|
|
11
|
+
country: "SN",
|
|
12
|
+
datastakeId: "PRJ-SAMPLE-001",
|
|
13
|
+
sectoralScope: "energy",
|
|
14
|
+
percentageCompletion: 75,
|
|
15
|
+
projectDescription: "Large-scale solar energy project in Dakar region",
|
|
16
|
+
latitude: 14.7167,
|
|
17
|
+
longitude: -17.4677,
|
|
18
|
+
author: { name: "Dakar Energy Co." }
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
_id: "sample-2",
|
|
22
|
+
name: "Saint-Louis Wind Farm",
|
|
23
|
+
country: "SN",
|
|
24
|
+
datastakeId: "PRJ-SAMPLE-002",
|
|
25
|
+
sectoralScope: "energy",
|
|
26
|
+
percentageCompletion: 45,
|
|
27
|
+
projectDescription: "Wind energy project in Saint-Louis region",
|
|
28
|
+
latitude: 16.0167,
|
|
29
|
+
longitude: -16.4833,
|
|
30
|
+
author: { name: "Wind Power Solutions" }
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
_id: "sample-3",
|
|
34
|
+
name: "Casamance Reforestation",
|
|
35
|
+
country: "SN",
|
|
36
|
+
datastakeId: "PRJ-SAMPLE-003",
|
|
37
|
+
sectoralScope: "agricultureForestryAndOtherLandUse",
|
|
38
|
+
percentageCompletion: 60,
|
|
39
|
+
projectDescription: "Forest restoration project in Casamance region",
|
|
40
|
+
latitude: 12.5833,
|
|
41
|
+
longitude: -16.2667,
|
|
42
|
+
author: { name: "Green Casamance" }
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
_id: "sample-4",
|
|
46
|
+
name: "Lagos Tech Hub",
|
|
47
|
+
country: "NG",
|
|
48
|
+
datastakeId: "PRJ-SAMPLE-004",
|
|
49
|
+
sectoralScope: "technology",
|
|
50
|
+
percentageCompletion: 30,
|
|
51
|
+
projectDescription: "Technology innovation center in Lagos",
|
|
52
|
+
latitude: 6.5244,
|
|
53
|
+
longitude: 3.3792,
|
|
54
|
+
author: { name: "Lagos Tech Foundation" }
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
_id: "sample-5",
|
|
58
|
+
name: "Cairo Water Management",
|
|
59
|
+
country: "EG",
|
|
60
|
+
datastakeId: "PRJ-SAMPLE-005",
|
|
61
|
+
sectoralScope: "water",
|
|
62
|
+
percentageCompletion: 85,
|
|
63
|
+
projectDescription: "Water conservation project in Cairo",
|
|
64
|
+
latitude: 30.0444,
|
|
65
|
+
longitude: 31.2357,
|
|
66
|
+
author: { name: "Cairo Water Authority" }
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
export default {
|
|
71
|
+
title: "Dashboard/Globe/SimpleGlobe",
|
|
72
|
+
component: SimpleGlobe,
|
|
73
|
+
tags: ["autodocs"],
|
|
74
|
+
args: {
|
|
75
|
+
projects: SAMPLE_PROJECTS,
|
|
76
|
+
showSider: false,
|
|
77
|
+
onProjectClick: (project) => console.log('Project clicked:', project)
|
|
78
|
+
},
|
|
79
|
+
decorators: [
|
|
80
|
+
(Story) => (
|
|
81
|
+
<ThemeLayout>
|
|
82
|
+
<Widget title="Simple Globe with Project Pins" className="no-px no-pb-body">
|
|
83
|
+
<div style={{ width: '100%', height: '600px' }}>
|
|
84
|
+
<Story />
|
|
85
|
+
</div>
|
|
86
|
+
</Widget>
|
|
87
|
+
</ThemeLayout>
|
|
88
|
+
),
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const Default = {
|
|
93
|
+
name: "Default Project Globe",
|
|
94
|
+
args: {
|
|
95
|
+
projects: SAMPLE_PROJECTS,
|
|
96
|
+
showSider: false
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const TestSimple = {
|
|
101
|
+
name: "Test Simple Data",
|
|
102
|
+
args: {
|
|
103
|
+
projects: [
|
|
104
|
+
{
|
|
105
|
+
name: "Test Project 1",
|
|
106
|
+
latitude: 14.7167,
|
|
107
|
+
longitude: -17.4677,
|
|
108
|
+
percentageCompletion: 75,
|
|
109
|
+
projectDescription: "Test project in Dakar"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "Test Project 2",
|
|
113
|
+
latitude: 16.0167,
|
|
114
|
+
longitude: -16.4833,
|
|
115
|
+
percentageCompletion: 45,
|
|
116
|
+
projectDescription: "Test project in Saint-Louis"
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
showSider: true
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const WithSidebar = {
|
|
124
|
+
name: "With Sidebar",
|
|
125
|
+
args: {
|
|
126
|
+
projects: SAMPLE_PROJECTS,
|
|
127
|
+
showSider: true
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const CustomMapConfig = {
|
|
132
|
+
name: "Custom Map Configuration",
|
|
133
|
+
args: {
|
|
134
|
+
projects: SAMPLE_PROJECTS,
|
|
135
|
+
showSider: true,
|
|
136
|
+
mapConfig: {
|
|
137
|
+
maxZoom: 6,
|
|
138
|
+
minZoom: 2
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export const SingleProject = {
|
|
144
|
+
name: "Single Project",
|
|
145
|
+
args: {
|
|
146
|
+
projects: [SAMPLE_PROJECTS[0]],
|
|
147
|
+
showSider: true
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const EmptyState = {
|
|
152
|
+
name: "Empty State",
|
|
153
|
+
args: {
|
|
154
|
+
projects: [],
|
|
155
|
+
showSider: false
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const LocationMarkers = {
|
|
160
|
+
name: "Location Markers (Map Pin Style)",
|
|
161
|
+
args: {
|
|
162
|
+
projects: SAMPLE_PROJECTS,
|
|
163
|
+
showSider: true,
|
|
164
|
+
type: "location"
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const CustomColorMarkers = {
|
|
169
|
+
name: "Custom Color Markers",
|
|
170
|
+
args: {
|
|
171
|
+
projects: SAMPLE_PROJECTS,
|
|
172
|
+
showSider: true,
|
|
173
|
+
color: "#FF6B6B"
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export const LocationCustomColor = {
|
|
178
|
+
name: "Location Markers with Custom Color",
|
|
179
|
+
args: {
|
|
180
|
+
projects: SAMPLE_PROJECTS,
|
|
181
|
+
showSider: true,
|
|
182
|
+
type: "location",
|
|
183
|
+
color: "#4ECDC4"
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export const CustomTooltip = {
|
|
188
|
+
name: "Custom Tooltip Function",
|
|
189
|
+
args: {
|
|
190
|
+
projects: SAMPLE_PROJECTS,
|
|
191
|
+
showSider: true,
|
|
192
|
+
type: "location",
|
|
193
|
+
color: "#4ECDC4",
|
|
194
|
+
renderTooltip: (project) => [
|
|
195
|
+
{
|
|
196
|
+
label: "Project Name",
|
|
197
|
+
value: project.name || 'N/A'
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
label: "Completion",
|
|
201
|
+
value: `${project.percentageCompletion || 0}%`,
|
|
202
|
+
color: project.percentageCompletion > 50 ? "#12b76a" : "#FF7A45"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
label: "Country",
|
|
206
|
+
value: project.country || 'N/A'
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export const AdvancedCustomTooltip = {
|
|
213
|
+
name: "Advanced Custom Tooltip with Colors",
|
|
214
|
+
args: {
|
|
215
|
+
projects: SAMPLE_PROJECTS,
|
|
216
|
+
showSider: true,
|
|
217
|
+
type: "location",
|
|
218
|
+
color: "#4ECDC4",
|
|
219
|
+
renderTooltip: (project) => [
|
|
220
|
+
{
|
|
221
|
+
label: "Project Name",
|
|
222
|
+
value: project.name || 'N/A'
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
label: "Sector",
|
|
226
|
+
value: project.sectoralScope || 'Project',
|
|
227
|
+
color: "#12b76a"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
label: "Completion Status",
|
|
231
|
+
value: project.percentageCompletion > 75 ? "High" : project.percentageCompletion > 50 ? "Medium" : "Low",
|
|
232
|
+
color: project.percentageCompletion > 75 ? "#12b76a" : project.percentageCompletion > 50 ? "#FF7A45" : "#F04438"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
label: "Completion %",
|
|
236
|
+
value: `${project.percentageCompletion || 0}%`
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
label: "Author",
|
|
240
|
+
value: project.author?.name || 'N/A'
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
label: "Project ID",
|
|
244
|
+
value: project.datastakeId || 'N/A'
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
export const MinimalTooltip = {
|
|
251
|
+
name: "Minimal Custom Tooltip",
|
|
252
|
+
args: {
|
|
253
|
+
projects: SAMPLE_PROJECTS,
|
|
254
|
+
showSider: true,
|
|
255
|
+
type: "location",
|
|
256
|
+
color: "#4ECDC4",
|
|
257
|
+
renderTooltip: (project) => [
|
|
258
|
+
{
|
|
259
|
+
label: "Name",
|
|
260
|
+
value: project.name || 'N/A'
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
label: "Progress",
|
|
264
|
+
value: `${project.percentageCompletion || 0}%`
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export const DebugVersion = {
|
|
271
|
+
name: "Debug Version (Direct Mapbox)",
|
|
272
|
+
render: () => (
|
|
273
|
+
<div style={{ margin: "3em" }}>
|
|
274
|
+
<ThemeLayout>
|
|
275
|
+
|
|
276
|
+
<Widget title="Debug Globe (Direct Mapbox)" className="no-px no-pb-body">
|
|
277
|
+
<div style={{ width: '100%', height: '600px' }}>
|
|
278
|
+
<SimpleGlobeDebug projects={SAMPLE_PROJECTS} />
|
|
279
|
+
</div>
|
|
280
|
+
</Widget>
|
|
281
|
+
</ThemeLayout>
|
|
282
|
+
</div>
|
|
283
|
+
)
|
|
284
|
+
};
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
|