datastake-daf 0.6.294 β†’ 0.6.296

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.
@@ -1,345 +0,0 @@
1
- import React, { useEffect, useRef } from 'react';
2
- import mapboxgl from 'mapbox-gl';
3
-
4
- /**
5
- * IsolatedGlobe - Completely isolated Mapbox component
6
- * Uses scoped CSS and shadow DOM to prevent any conflicts
7
- */
8
- const IsolatedGlobe = ({
9
- projects = [],
10
- mapConfig = {},
11
- onProjectClick = () => {},
12
- type = "default",
13
- color = "#00809E"
14
- }) => {
15
- const mapContainer = useRef(null);
16
- const map = useRef(null);
17
- const shadowRoot = useRef(null);
18
- const boundsRef = useRef(null);
19
-
20
- useEffect(() => {
21
- if (map.current) return;
22
-
23
- console.log('πŸ—ΊοΈ [ISOLATED GLOBE] Creating isolated map...');
24
-
25
- // Set Mapbox access token
26
- mapboxgl.accessToken = 'pk.eyJ1IjoicmVkaXM5OTkiLCJhIjoiY2x4YWV5MzA5MmtuZzJpcXM5Y201Z2E2YiJ9.m5bwPg-Tj4Akesl1yQUa3w';
27
-
28
- // Create shadow DOM for complete isolation
29
- const container = mapContainer.current;
30
- shadowRoot.current = container.attachShadow({ mode: 'open' });
31
-
32
- // Create isolated styles
33
- const style = document.createElement('style');
34
- style.textContent = `
35
- :host {
36
- display: block;
37
- width: 100%;
38
- height: 100%;
39
- position: relative;
40
- overflow: hidden;
41
- }
42
-
43
- .mapboxgl-map {
44
- font: 12px/20px Helvetica Neue, Arial, Helvetica, sans-serif;
45
- overflow: hidden;
46
- position: relative;
47
- width: 100%;
48
- height: 100%;
49
- -webkit-tap-highlight-color: rgb(0 0 0/0);
50
- }
51
-
52
- .mapboxgl-canvas {
53
- left: 0;
54
- position: absolute;
55
- top: 0;
56
- }
57
-
58
- .mapboxgl-canvas-container {
59
- position: relative;
60
- width: 100%;
61
- height: 100%;
62
- }
63
-
64
- .mapboxgl-marker {
65
- position: absolute;
66
- z-index: 1;
67
- }
68
-
69
- .mapboxgl-marker svg {
70
- display: block;
71
- }
72
-
73
- .mapboxgl-popup {
74
- position: absolute;
75
- text-align: center;
76
- margin-bottom: 20px;
77
- }
78
-
79
- .mapboxgl-popup-content-wrapper {
80
- padding: 1px;
81
- text-align: left;
82
- border-radius: 12px;
83
- background: white;
84
- color: #333;
85
- box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
86
- }
87
-
88
- .mapboxgl-popup-content {
89
- margin: 13px 24px 13px 20px;
90
- line-height: 1.3;
91
- font-size: 13px;
92
- min-height: 1px;
93
- }
94
-
95
- .mapboxgl-popup-tip-container {
96
- width: 40px;
97
- height: 20px;
98
- position: absolute;
99
- left: 50%;
100
- margin-top: -1px;
101
- margin-left: -20px;
102
- overflow: hidden;
103
- pointer-events: none;
104
- }
105
-
106
- .mapboxgl-popup-tip {
107
- width: 17px;
108
- height: 17px;
109
- padding: 1px;
110
- margin: -10px auto 0;
111
- pointer-events: auto;
112
- transform: rotate(45deg);
113
- background: white;
114
- box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
115
- }
116
-
117
- .mapboxgl-popup-close-button {
118
- position: absolute;
119
- top: 0;
120
- right: 0;
121
- border: none;
122
- text-align: center;
123
- width: 24px;
124
- height: 24px;
125
- font: 16px/24px Tahoma, Verdana, sans-serif;
126
- color: #757575;
127
- text-decoration: none;
128
- background: transparent;
129
- cursor: pointer;
130
- }
131
-
132
- .mapboxgl-popup-close-button:hover {
133
- color: #585858;
134
- }
135
-
136
- .mapboxgl-ctrl-attribution,
137
- .mapboxgl-ctrl-logo {
138
- display: none !important;
139
- }
140
- `;
141
- shadowRoot.current.appendChild(style);
142
-
143
- // Create map container inside shadow DOM
144
- const mapDiv = document.createElement('div');
145
- mapDiv.style.width = '100%';
146
- mapDiv.style.height = '100%';
147
- shadowRoot.current.appendChild(mapDiv);
148
-
149
- // Create map
150
- map.current = new mapboxgl.Map({
151
- container: mapDiv,
152
- style: 'mapbox://styles/mapbox/satellite-v9',
153
- center: [0, 0],
154
- zoom: mapConfig.maxZoom || 3,
155
- projection: 'globe',
156
- attributionControl: false
157
- });
158
-
159
- // Add markers when map loads
160
- map.current.on('load', () => {
161
- console.log('πŸ—ΊοΈ [ISOLATED GLOBE] Map loaded, adding markers...');
162
-
163
- // Calculate bounds to fit all markers
164
- const bounds = new mapboxgl.LngLatBounds();
165
- let hasValidCoordinates = false;
166
-
167
- projects.forEach((project, index) => {
168
- console.log(`πŸ“ [ISOLATED GLOBE] Adding marker ${index}:`, project);
169
-
170
- // Create marker element
171
- const el = document.createElement('div');
172
- el.style.cursor = 'pointer';
173
- el.style.boxShadow = '0px 3.45px 3.45px 0px #00000029';
174
- el.style.display = 'flex';
175
- el.style.alignItems = 'center';
176
- el.style.justifyContent = 'center';
177
- el.style.position = 'relative';
178
- el.style.left = 'auto';
179
- el.style.top = 'auto';
180
- el.style.transform = 'none';
181
- el.style.zIndex = '1000';
182
-
183
- if (type === "location") {
184
- // Location marker - SVG map pin style
185
- el.style.width = '28px';
186
- el.style.height = '33px';
187
- el.innerHTML = `
188
- <svg
189
- width="28"
190
- height="33"
191
- viewBox="0 0 28 33"
192
- fill="none"
193
- xmlns="http://www.w3.org/2000/svg"
194
- >
195
- <path
196
- d="M5.14346 4.87419C10.0688 -0.15896 18.0528 -0.162058 22.9757 4.86861C27.6563 9.65161 27.8841 17.2616 23.6622 22.3255H23.6608C23.427 22.6141 23.1808 22.894 22.9211 23.1623L14.0671 32.2101L5.44057 23.3948L5.13868 23.096C0.215857 18.0655 0.218422 9.90737 5.14346 4.87419Z"
197
- fill="${color}"
198
- stroke="white"
199
- />
200
- </svg>
201
- `;
202
- } else {
203
- // Default circular marker style
204
- el.style.width = '30px';
205
- el.style.height = '30px';
206
- el.style.backgroundColor = color;
207
- el.style.borderRadius = '50%';
208
- el.style.border = '2px solid white';
209
- el.style.color = 'white';
210
- el.style.fontWeight = 'bold';
211
- el.style.fontSize = '14px';
212
- el.style.textAlign = 'center';
213
- el.style.lineHeight = '1';
214
- el.innerHTML = `<span style="display: block; line-height: 1;">${project.percentageCompletion || 0}</span>`;
215
- }
216
-
217
- // Create popup content
218
- const popupContent = `
219
- <div style="padding: 12px; min-width: 200px;">
220
- <h3 style="margin: 0 0 8px 0; font-size: 16px; color: #333;">${project.name}</h3>
221
- <p style="margin: 0 0 4px 0; font-size: 12px; color: #666;">
222
- <strong>Country:</strong> ${project.country || 'N/A'}
223
- </p>
224
- <p style="margin: 0 0 4px 0; font-size: 12px; color: #666;">
225
- <strong>Sector:</strong> ${project.sectoralScope || 'Project'}
226
- </p>
227
- <p style="margin: 0 0 4px 0; font-size: 12px; color: #666;">
228
- <strong>Completion:</strong> ${project.percentageCompletion || 0}%
229
- </p>
230
- <p style="margin: 4px 0 0 0; font-size: 12px; color: #666;">
231
- <strong>Coordinates:</strong> ${Number(project.latitude).toFixed(4)}, ${Number(project.longitude).toFixed(4)}
232
- </p>
233
- </div>
234
- `;
235
-
236
- // Create popup
237
- const popup = new mapboxgl.Popup({
238
- offset: 25,
239
- closeButton: true,
240
- closeOnClick: false
241
- }).setHTML(popupContent);
242
-
243
- // Ensure coordinates are valid numbers
244
- const lng = Number(project.longitude);
245
- const lat = Number(project.latitude);
246
-
247
- console.log(`πŸ“ [ISOLATED GLOBE] Marker ${index} coordinates:`, {
248
- original: { longitude: project.longitude, latitude: project.latitude },
249
- processed: { lng, lat },
250
- project: project.name
251
- });
252
-
253
- // Validate coordinates
254
- if (isNaN(lng) || isNaN(lat) || lng < -180 || lng > 180 || lat < -90 || lat > 90) {
255
- console.error(`❌ [ISOLATED GLOBE] Invalid coordinates for project ${index}:`, {
256
- lng, lat,
257
- original: { longitude: project.longitude, latitude: project.latitude },
258
- project: project.name
259
- });
260
- return;
261
- }
262
-
263
- // Add coordinates to bounds
264
- bounds.extend([lng, lat]);
265
- hasValidCoordinates = true;
266
-
267
- // Create marker with explicit positioning
268
- const marker = new mapboxgl.Marker({
269
- element: el,
270
- anchor: 'center'
271
- })
272
- .setLngLat([lng, lat])
273
- .setPopup(popup)
274
- .addTo(map.current);
275
-
276
- // Add click handler
277
- el.addEventListener('click', () => {
278
- console.log('πŸ“ [ISOLATED GLOBE] Marker clicked:', project);
279
- onProjectClick(project);
280
- });
281
-
282
- // Verify marker position after a short delay
283
- setTimeout(() => {
284
- const markerLngLat = marker.getLngLat();
285
- console.log(`πŸ” [ISOLATED GLOBE] Marker ${index} position verification:`, {
286
- expected: [lng, lat],
287
- actual: [markerLngLat.lng, markerLngLat.lat],
288
- project: project.name,
289
- match: Math.abs(markerLngLat.lng - lng) < 0.0001 && Math.abs(markerLngLat.lat - lat) < 0.0001
290
- });
291
- }, 100);
292
-
293
- console.log(`βœ… [ISOLATED GLOBE] Marker ${index} added at:`, [lng, lat]);
294
- });
295
-
296
- // Fit map to show all markers if we have valid coordinates
297
- if (hasValidCoordinates && !bounds.isEmpty()) {
298
- console.log('πŸ—ΊοΈ [ISOLATED GLOBE] Fitting map to bounds:', bounds);
299
- map.current.fitBounds(bounds, {
300
- padding: { top: 20, bottom: 20, left: 20, right: 20 },
301
- maxZoom: 6,
302
- duration: 1000
303
- });
304
- boundsRef.current = bounds;
305
- } else {
306
- boundsRef.current = null;
307
- }
308
- });
309
-
310
- return () => {
311
- if (map.current) {
312
- map.current.remove();
313
- map.current = null;
314
- }
315
- };
316
- }, [projects, onProjectClick, mapConfig]);
317
-
318
- const zoomIn = () => map.current && map.current.zoomIn();
319
- const zoomOut = () => map.current && map.current.zoomOut();
320
- const recenter = () => {
321
- if (!map.current) return;
322
- if (boundsRef.current && !boundsRef.current.isEmpty()) {
323
- map.current.fitBounds(boundsRef.current, {
324
- padding: { top: 20, bottom: 20, left: 20, right: 20 },
325
- maxZoom: 6,
326
- duration: 800,
327
- });
328
- return;
329
- }
330
- map.current.easeTo({ center: [0, 0], zoom: 3, duration: 800 });
331
- };
332
-
333
- return (
334
- <div
335
- ref={mapContainer}
336
- style={{
337
- width: '100%',
338
- height: '100%',
339
- position: 'relative'
340
- }}
341
- />
342
- );
343
- };
344
-
345
- export default IsolatedGlobe;