datastake-daf 0.6.280 โ 0.6.282
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 +564 -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 +373 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobe.stories.js +301 -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/SimpleGlobeTestDebug.jsx +150 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobeTestDebug.standalone.jsx +183 -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 +2 -0
- package/.env +0 -8
- package/.vscode/settings.json +0 -13
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import SimpleGlobe from "./SimpleGlobe";
|
|
2
|
+
import SimpleGlobeDebug from "./SimpleGlobeDebug";
|
|
3
|
+
import SimpleGlobeTestDebug from "./SimpleGlobeTestDebug";
|
|
4
|
+
import ThemeLayout from "../../ThemeLayout";
|
|
5
|
+
import Widget from "../Widget";
|
|
6
|
+
|
|
7
|
+
// Sample project data
|
|
8
|
+
const SAMPLE_PROJECTS = [
|
|
9
|
+
{
|
|
10
|
+
_id: "sample-1",
|
|
11
|
+
name: "Dakar Solar Initiative",
|
|
12
|
+
country: "SN",
|
|
13
|
+
datastakeId: "PRJ-SAMPLE-001",
|
|
14
|
+
sectoralScope: "energy",
|
|
15
|
+
percentageCompletion: 75,
|
|
16
|
+
projectDescription: "Large-scale solar energy project in Dakar region",
|
|
17
|
+
latitude: 14.7167,
|
|
18
|
+
longitude: -17.4677,
|
|
19
|
+
author: { name: "Dakar Energy Co." }
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
_id: "sample-2",
|
|
23
|
+
name: "Saint-Louis Wind Farm",
|
|
24
|
+
country: "SN",
|
|
25
|
+
datastakeId: "PRJ-SAMPLE-002",
|
|
26
|
+
sectoralScope: "energy",
|
|
27
|
+
percentageCompletion: 45,
|
|
28
|
+
projectDescription: "Wind energy project in Saint-Louis region",
|
|
29
|
+
latitude: 16.0167,
|
|
30
|
+
longitude: -16.4833,
|
|
31
|
+
author: { name: "Wind Power Solutions" }
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
_id: "sample-3",
|
|
35
|
+
name: "Casamance Reforestation",
|
|
36
|
+
country: "SN",
|
|
37
|
+
datastakeId: "PRJ-SAMPLE-003",
|
|
38
|
+
sectoralScope: "agricultureForestryAndOtherLandUse",
|
|
39
|
+
percentageCompletion: 60,
|
|
40
|
+
projectDescription: "Forest restoration project in Casamance region",
|
|
41
|
+
latitude: 12.5833,
|
|
42
|
+
longitude: -16.2667,
|
|
43
|
+
author: { name: "Green Casamance" }
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
_id: "sample-4",
|
|
47
|
+
name: "Lagos Tech Hub",
|
|
48
|
+
country: "NG",
|
|
49
|
+
datastakeId: "PRJ-SAMPLE-004",
|
|
50
|
+
sectoralScope: "technology",
|
|
51
|
+
percentageCompletion: 30,
|
|
52
|
+
projectDescription: "Technology innovation center in Lagos",
|
|
53
|
+
latitude: 6.5244,
|
|
54
|
+
longitude: 3.3792,
|
|
55
|
+
author: { name: "Lagos Tech Foundation" }
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
_id: "sample-5",
|
|
59
|
+
name: "Cairo Water Management",
|
|
60
|
+
country: "EG",
|
|
61
|
+
datastakeId: "PRJ-SAMPLE-005",
|
|
62
|
+
sectoralScope: "water",
|
|
63
|
+
percentageCompletion: 85,
|
|
64
|
+
projectDescription: "Water conservation project in Cairo",
|
|
65
|
+
latitude: 30.0444,
|
|
66
|
+
longitude: 31.2357,
|
|
67
|
+
author: { name: "Cairo Water Authority" }
|
|
68
|
+
}
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
export default {
|
|
72
|
+
title: "Dashboard/Globe/SimpleGlobe",
|
|
73
|
+
component: SimpleGlobe,
|
|
74
|
+
tags: ["autodocs"],
|
|
75
|
+
args: {
|
|
76
|
+
projects: SAMPLE_PROJECTS,
|
|
77
|
+
showSider: false,
|
|
78
|
+
onProjectClick: (project) => console.log('Project clicked:', project)
|
|
79
|
+
},
|
|
80
|
+
decorators: [
|
|
81
|
+
(Story) => (
|
|
82
|
+
<ThemeLayout>
|
|
83
|
+
<Widget title="Simple Globe with Project Pins" className="no-px no-pb-body">
|
|
84
|
+
<div style={{ width: '100%', height: '600px' }}>
|
|
85
|
+
<Story />
|
|
86
|
+
</div>
|
|
87
|
+
</Widget>
|
|
88
|
+
</ThemeLayout>
|
|
89
|
+
),
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const Default = {
|
|
94
|
+
name: "Default Project Globe",
|
|
95
|
+
args: {
|
|
96
|
+
projects: SAMPLE_PROJECTS,
|
|
97
|
+
showSider: false
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const TestSimple = {
|
|
102
|
+
name: "Test Simple Data",
|
|
103
|
+
args: {
|
|
104
|
+
projects: [
|
|
105
|
+
{
|
|
106
|
+
name: "Test Project 1",
|
|
107
|
+
latitude: 14.7167,
|
|
108
|
+
longitude: -17.4677,
|
|
109
|
+
percentageCompletion: 75,
|
|
110
|
+
projectDescription: "Test project in Dakar"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: "Test Project 2",
|
|
114
|
+
latitude: 16.0167,
|
|
115
|
+
longitude: -16.4833,
|
|
116
|
+
percentageCompletion: 45,
|
|
117
|
+
projectDescription: "Test project in Saint-Louis"
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
showSider: true
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const WithSidebar = {
|
|
125
|
+
name: "With Sidebar",
|
|
126
|
+
args: {
|
|
127
|
+
projects: SAMPLE_PROJECTS,
|
|
128
|
+
showSider: true
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const CustomMapConfig = {
|
|
133
|
+
name: "Custom Map Configuration",
|
|
134
|
+
args: {
|
|
135
|
+
projects: SAMPLE_PROJECTS,
|
|
136
|
+
showSider: true,
|
|
137
|
+
mapConfig: {
|
|
138
|
+
maxZoom: 6,
|
|
139
|
+
minZoom: 2
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const SingleProject = {
|
|
145
|
+
name: "Single Project",
|
|
146
|
+
args: {
|
|
147
|
+
projects: [SAMPLE_PROJECTS[0]],
|
|
148
|
+
showSider: true
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export const EmptyState = {
|
|
153
|
+
name: "Empty State",
|
|
154
|
+
args: {
|
|
155
|
+
projects: [],
|
|
156
|
+
showSider: false
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export const LocationMarkers = {
|
|
161
|
+
name: "Location Markers (Map Pin Style)",
|
|
162
|
+
args: {
|
|
163
|
+
projects: SAMPLE_PROJECTS,
|
|
164
|
+
showSider: true,
|
|
165
|
+
type: "location"
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const CustomColorMarkers = {
|
|
170
|
+
name: "Custom Color Markers",
|
|
171
|
+
args: {
|
|
172
|
+
projects: SAMPLE_PROJECTS,
|
|
173
|
+
showSider: true,
|
|
174
|
+
color: "#FF6B6B"
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export const LocationCustomColor = {
|
|
179
|
+
name: "Location Markers with Custom Color",
|
|
180
|
+
args: {
|
|
181
|
+
projects: SAMPLE_PROJECTS,
|
|
182
|
+
showSider: true,
|
|
183
|
+
type: "location",
|
|
184
|
+
color: "#4ECDC4"
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export const CustomTooltip = {
|
|
189
|
+
name: "Custom Tooltip Function",
|
|
190
|
+
args: {
|
|
191
|
+
projects: SAMPLE_PROJECTS,
|
|
192
|
+
showSider: true,
|
|
193
|
+
type: "location",
|
|
194
|
+
color: "#4ECDC4",
|
|
195
|
+
renderTooltip: (project) => [
|
|
196
|
+
{
|
|
197
|
+
label: "Project Name",
|
|
198
|
+
value: project.name || 'N/A'
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
label: "Completion",
|
|
202
|
+
value: `${project.percentageCompletion || 0}%`,
|
|
203
|
+
color: project.percentageCompletion > 50 ? "#12b76a" : "#FF7A45"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
label: "Country",
|
|
207
|
+
value: project.country || 'N/A'
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export const AdvancedCustomTooltip = {
|
|
214
|
+
name: "Advanced Custom Tooltip with Colors",
|
|
215
|
+
args: {
|
|
216
|
+
projects: SAMPLE_PROJECTS,
|
|
217
|
+
showSider: true,
|
|
218
|
+
type: "location",
|
|
219
|
+
color: "#4ECDC4",
|
|
220
|
+
renderTooltip: (project) => [
|
|
221
|
+
{
|
|
222
|
+
label: "Project Name",
|
|
223
|
+
value: project.name || 'N/A'
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
label: "Sector",
|
|
227
|
+
value: project.sectoralScope || 'Project',
|
|
228
|
+
color: "#12b76a"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
label: "Completion Status",
|
|
232
|
+
value: project.percentageCompletion > 75 ? "High" : project.percentageCompletion > 50 ? "Medium" : "Low",
|
|
233
|
+
color: project.percentageCompletion > 75 ? "#12b76a" : project.percentageCompletion > 50 ? "#FF7A45" : "#F04438"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
label: "Completion %",
|
|
237
|
+
value: `${project.percentageCompletion || 0}%`
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
label: "Author",
|
|
241
|
+
value: project.author?.name || 'N/A'
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
label: "Project ID",
|
|
245
|
+
value: project.datastakeId || 'N/A'
|
|
246
|
+
}
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
export const MinimalTooltip = {
|
|
252
|
+
name: "Minimal Custom Tooltip",
|
|
253
|
+
args: {
|
|
254
|
+
projects: SAMPLE_PROJECTS,
|
|
255
|
+
showSider: true,
|
|
256
|
+
type: "location",
|
|
257
|
+
color: "#4ECDC4",
|
|
258
|
+
renderTooltip: (project) => [
|
|
259
|
+
{
|
|
260
|
+
label: "Name",
|
|
261
|
+
value: project.name || 'N/A'
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
label: "Progress",
|
|
265
|
+
value: `${project.percentageCompletion || 0}%`
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
export const DebugVersion = {
|
|
272
|
+
name: "Debug Version (Direct Mapbox)",
|
|
273
|
+
render: () => (
|
|
274
|
+
<div style={{ margin: "3em" }}>
|
|
275
|
+
<ThemeLayout>
|
|
276
|
+
|
|
277
|
+
<Widget title="Debug Globe (Direct Mapbox)" className="no-px no-pb-body">
|
|
278
|
+
<div style={{ width: '100%', height: '600px' }}>
|
|
279
|
+
<SimpleGlobeDebug projects={SAMPLE_PROJECTS} />
|
|
280
|
+
</div>
|
|
281
|
+
</Widget>
|
|
282
|
+
</ThemeLayout>
|
|
283
|
+
</div>
|
|
284
|
+
)
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export const TestDebugVersion = {
|
|
288
|
+
name: "Test Debug Version (Minimal Setup)",
|
|
289
|
+
render: () => (
|
|
290
|
+
<div style={{ margin: "3em" }}>
|
|
291
|
+
<ThemeLayout>
|
|
292
|
+
<Widget title="Test Debug Globe (Minimal Mapbox)" className="no-px no-pb-body">
|
|
293
|
+
<SimpleGlobeTestDebug projects={SAMPLE_PROJECTS} />
|
|
294
|
+
</Widget>
|
|
295
|
+
</ThemeLayout>
|
|
296
|
+
</div>
|
|
297
|
+
)
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
// Export the component for reuse in other projects
|
|
301
|
+
export { SimpleGlobeTestDebug };
|
|
@@ -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;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import mapboxgl from 'mapbox-gl';
|
|
3
|
+
import 'mapbox-gl/dist/mapbox-gl.css';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SimpleGlobeTestDebug - A minimal test component to debug marker positioning issues
|
|
7
|
+
* This component uses the most basic Mapbox setup to isolate positioning problems
|
|
8
|
+
*/
|
|
9
|
+
const SimpleGlobeTestDebug = ({ projects = [] }) => {
|
|
10
|
+
const mapContainer = useRef(null);
|
|
11
|
+
const map = useRef(null);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (map.current) return;
|
|
15
|
+
|
|
16
|
+
console.log('๐งช [DEBUG TEST] Creating minimal map...');
|
|
17
|
+
|
|
18
|
+
// Set Mapbox access token
|
|
19
|
+
mapboxgl.accessToken = 'pk.eyJ1IjoicmVkaXM5OTkiLCJhIjoiY2x4YWV5MzA5MmtuZzJpcXM5Y201Z2E2YiJ9.m5bwPg-Tj4Akesl1yQUa3w';
|
|
20
|
+
|
|
21
|
+
// Create minimal map
|
|
22
|
+
map.current = new mapboxgl.Map({
|
|
23
|
+
container: mapContainer.current,
|
|
24
|
+
style: 'mapbox://styles/mapbox/satellite-v9',
|
|
25
|
+
center: [0, 0],
|
|
26
|
+
zoom: 2,
|
|
27
|
+
projection: 'globe'
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Add markers when map loads
|
|
31
|
+
map.current.on('load', () => {
|
|
32
|
+
console.log('๐งช [DEBUG TEST] Map loaded, adding test markers...');
|
|
33
|
+
|
|
34
|
+
projects.forEach((project, index) => {
|
|
35
|
+
console.log(`๐งช [DEBUG TEST] Processing project ${index}:`, project);
|
|
36
|
+
|
|
37
|
+
// Create simple marker
|
|
38
|
+
const el = document.createElement('div');
|
|
39
|
+
el.style.width = '20px';
|
|
40
|
+
el.style.height = '20px';
|
|
41
|
+
el.style.backgroundColor = '#FF0000';
|
|
42
|
+
el.style.borderRadius = '50%';
|
|
43
|
+
el.style.border = '2px solid white';
|
|
44
|
+
el.style.cursor = 'pointer';
|
|
45
|
+
el.style.boxShadow = '0px 3px 6px rgba(0,0,0,0.3)';
|
|
46
|
+
|
|
47
|
+
// Get coordinates
|
|
48
|
+
const lng = Number(project.longitude);
|
|
49
|
+
const lat = Number(project.latitude);
|
|
50
|
+
|
|
51
|
+
console.log(`๐งช [DEBUG TEST] Coordinates for ${project.name}:`, {
|
|
52
|
+
original: { longitude: project.longitude, latitude: project.latitude },
|
|
53
|
+
processed: { lng, lat },
|
|
54
|
+
valid: !isNaN(lng) && !isNaN(lat) && lng >= -180 && lng <= 180 && lat >= -90 && lat <= 90
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (isNaN(lng) || isNaN(lat) || lng < -180 || lng > 180 || lat < -90 || lat > 90) {
|
|
58
|
+
console.error(`โ [DEBUG TEST] Invalid coordinates for ${project.name}:`, { lng, lat });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Create popup
|
|
63
|
+
const popup = new mapboxgl.Popup({ offset: 25 })
|
|
64
|
+
.setHTML(`
|
|
65
|
+
<div style="padding: 8px;">
|
|
66
|
+
<h3 style="margin: 0 0 8px 0; font-size: 14px;">${project.name}</h3>
|
|
67
|
+
<p style="margin: 0; font-size: 12px; color: #666;">
|
|
68
|
+
Lat: ${lat.toFixed(4)}, Lng: ${lng.toFixed(4)}
|
|
69
|
+
</p>
|
|
70
|
+
<p style="margin: 4px 0 0 0; font-size: 12px;">
|
|
71
|
+
${project.projectDescription || 'No description'}
|
|
72
|
+
</p>
|
|
73
|
+
</div>
|
|
74
|
+
`);
|
|
75
|
+
|
|
76
|
+
// Add marker with explicit positioning
|
|
77
|
+
const marker = new mapboxgl.Marker({
|
|
78
|
+
element: el,
|
|
79
|
+
anchor: 'center'
|
|
80
|
+
})
|
|
81
|
+
.setLngLat([lng, lat])
|
|
82
|
+
.setPopup(popup)
|
|
83
|
+
.addTo(map.current);
|
|
84
|
+
|
|
85
|
+
// Verify position after a delay
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
const markerLngLat = marker.getLngLat();
|
|
88
|
+
const positionMatch = Math.abs(markerLngLat.lng - lng) < 0.0001 && Math.abs(markerLngLat.lat - lat) < 0.0001;
|
|
89
|
+
|
|
90
|
+
console.log(`๐ [DEBUG TEST] Position verification for ${project.name}:`, {
|
|
91
|
+
expected: [lng, lat],
|
|
92
|
+
actual: [markerLngLat.lng, markerLngLat.lat],
|
|
93
|
+
match: positionMatch,
|
|
94
|
+
difference: {
|
|
95
|
+
lng: Math.abs(markerLngLat.lng - lng),
|
|
96
|
+
lat: Math.abs(markerLngLat.lat - lat)
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
if (!positionMatch) {
|
|
101
|
+
console.error(`โ [DEBUG TEST] Position mismatch for ${project.name}!`);
|
|
102
|
+
}
|
|
103
|
+
}, 200);
|
|
104
|
+
|
|
105
|
+
console.log(`โ
[DEBUG TEST] Marker added for ${project.name} at:`, [lng, lat]);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return () => {
|
|
110
|
+
if (map.current) {
|
|
111
|
+
map.current.remove();
|
|
112
|
+
map.current = null;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}, [projects]);
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<div style={{
|
|
119
|
+
width: '100%',
|
|
120
|
+
height: '600px',
|
|
121
|
+
border: '2px solid #ccc',
|
|
122
|
+
position: 'relative'
|
|
123
|
+
}}>
|
|
124
|
+
<div
|
|
125
|
+
ref={mapContainer}
|
|
126
|
+
style={{
|
|
127
|
+
width: '100%',
|
|
128
|
+
height: '100%',
|
|
129
|
+
position: 'relative'
|
|
130
|
+
}}
|
|
131
|
+
/>
|
|
132
|
+
<div style={{
|
|
133
|
+
position: 'absolute',
|
|
134
|
+
top: '10px',
|
|
135
|
+
left: '10px',
|
|
136
|
+
background: 'rgba(255,255,255,0.9)',
|
|
137
|
+
padding: '8px',
|
|
138
|
+
borderRadius: '4px',
|
|
139
|
+
fontSize: '12px',
|
|
140
|
+
zIndex: 1000
|
|
141
|
+
}}>
|
|
142
|
+
<strong>Debug Test Map</strong><br/>
|
|
143
|
+
Projects: {projects.length}<br/>
|
|
144
|
+
Check console for position verification
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export default SimpleGlobeTestDebug;
|