datastake-daf 0.6.250 → 0.6.252
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 +65 -35
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/DashboardLayout/index.jsx +1 -6
- package/src/@daf/core/components/Dashboard/Globe/Globe.stories.js +8 -0
- package/src/@daf/core/components/Dashboard/Globe/hook.js +42 -0
- package/src/@daf/core/components/Dashboard/Map/hook.js +1 -1
- package/src/@daf/core/components/Dashboard/Map/storyConfig.js +2 -1
- package/src/@daf/core/components/Dashboard/Map/storyConfig6.js +366 -0
- package/src/@daf/core/components/Dashboard/Widget/ProjectWidget/components/SdgList.jsx +6 -6
- package/src/@daf/core/components/Dashboard/Widget/ProjectWidget/index.jsx +0 -1
- package/src/@daf/core/components/ViewForm/helper.js +1 -1
- package/.env +0 -8
- package/.vscode/settings.json +0 -13
package/dist/components/index.js
CHANGED
|
@@ -12655,7 +12655,7 @@ const {
|
|
|
12655
12655
|
Paragraph: Paragraph$1
|
|
12656
12656
|
} = antd.Typography;
|
|
12657
12657
|
const checkHasActiveFilterValues = filtersConfig => {
|
|
12658
|
-
if (!filtersConfig
|
|
12658
|
+
if (!(filtersConfig !== null && filtersConfig !== void 0 && filtersConfig.filtersConfig) || !(filtersConfig !== null && filtersConfig !== void 0 && filtersConfig.selectedFilters)) return false;
|
|
12659
12659
|
const filterConfigKeys = Object.keys(filtersConfig.filtersConfig);
|
|
12660
12660
|
const selectedFilters = filtersConfig.selectedFilters;
|
|
12661
12661
|
return filterConfigKeys.some(key => {
|
|
@@ -12663,27 +12663,28 @@ const checkHasActiveFilterValues = filtersConfig => {
|
|
|
12663
12663
|
return value !== undefined && value !== null && value !== '';
|
|
12664
12664
|
});
|
|
12665
12665
|
};
|
|
12666
|
-
const useHeader =
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
|
|
12685
|
-
|
|
12686
|
-
|
|
12666
|
+
const useHeader = _ref => {
|
|
12667
|
+
let {
|
|
12668
|
+
title = '',
|
|
12669
|
+
tooltip = '',
|
|
12670
|
+
supportText = '',
|
|
12671
|
+
tags = [],
|
|
12672
|
+
actionButtons: _actionButtons = [],
|
|
12673
|
+
titleTooltip,
|
|
12674
|
+
className,
|
|
12675
|
+
addedHeader = null,
|
|
12676
|
+
addedHeaderFirst,
|
|
12677
|
+
extraButtons: _extraButtons = [],
|
|
12678
|
+
onDownload,
|
|
12679
|
+
downloadDisabled,
|
|
12680
|
+
goBackTo,
|
|
12681
|
+
loading,
|
|
12682
|
+
renderExtraComponents,
|
|
12683
|
+
app = '',
|
|
12684
|
+
isViewMode = false,
|
|
12685
|
+
filtersConfig = {}
|
|
12686
|
+
} = _ref;
|
|
12687
|
+
const hasActiveFilterValues = React.useMemo(() => checkHasActiveFilterValues(filtersConfig), [filtersConfig === null || filtersConfig === void 0 ? void 0 : filtersConfig.filtersConfig, filtersConfig === null || filtersConfig === void 0 ? void 0 : filtersConfig.selectedFilters]);
|
|
12687
12688
|
const [showFilters, setShowFilters] = React.useState(() => checkHasActiveFilterValues(filtersConfig));
|
|
12688
12689
|
const hasFilters = filtersConfig && Object.keys(filtersConfig).length > 0;
|
|
12689
12690
|
React.useEffect(() => {
|
|
@@ -12725,9 +12726,9 @@ const useHeader = ({
|
|
|
12725
12726
|
const buttonCont = React.useRef();
|
|
12726
12727
|
const [mainContWidth, setMainContWidth] = React.useState(600);
|
|
12727
12728
|
const [buttonContWidth, setButtonContWidth] = React.useState(0);
|
|
12728
|
-
const hasSupportText = !!supportText
|
|
12729
|
-
const hasTags = !!tags
|
|
12730
|
-
const hasButtons = !!(actionButtons
|
|
12729
|
+
const hasSupportText = !!(supportText !== null && supportText !== void 0 && supportText.length);
|
|
12730
|
+
const hasTags = !!(tags !== null && tags !== void 0 && tags.length);
|
|
12731
|
+
const hasButtons = !!(actionButtons !== null && actionButtons !== void 0 && actionButtons.length || extraButtons !== null && extraButtons !== void 0 && extraButtons.length);
|
|
12731
12732
|
React.useEffect(() => {
|
|
12732
12733
|
const mainContObserver = new ResizeObserver(entries => {
|
|
12733
12734
|
const _mainEntry = entries[0];
|
|
@@ -18407,7 +18408,7 @@ const useMap$1 = ({
|
|
|
18407
18408
|
const pos = allData.map(m => Array.isArray(m.area) ? m.area : [Number(m.marker?.lat ?? 0), Number(m.marker?.lng ?? 0)]);
|
|
18408
18409
|
const bounds = new L__namespace.LatLngBounds(pos);
|
|
18409
18410
|
mapRef.fitBounds(bounds, {
|
|
18410
|
-
padding: [
|
|
18411
|
+
padding: [10, 10]
|
|
18411
18412
|
});
|
|
18412
18413
|
}
|
|
18413
18414
|
}
|
|
@@ -19698,6 +19699,39 @@ const useGlobe = ({
|
|
|
19698
19699
|
}));
|
|
19699
19700
|
roots.current.push(root);
|
|
19700
19701
|
}
|
|
19702
|
+
} else if (type === "project") {
|
|
19703
|
+
// Handle project markers
|
|
19704
|
+
const el = document.createElement('div');
|
|
19705
|
+
el.className = 'mapboxgl-marker project-marker';
|
|
19706
|
+
el.style.width = '30px';
|
|
19707
|
+
el.style.height = '30px';
|
|
19708
|
+
el.style.backgroundColor = '#52c41a'; // Green color for projects
|
|
19709
|
+
el.style.borderRadius = '50%';
|
|
19710
|
+
el.style.border = '3px solid white';
|
|
19711
|
+
el.style.cursor = 'pointer';
|
|
19712
|
+
el.style.boxShadow = '0px 3.45px 3.45px 0px #00000029';
|
|
19713
|
+
el.style.display = 'flex';
|
|
19714
|
+
el.style.alignItems = 'center';
|
|
19715
|
+
el.style.justifyContent = 'center';
|
|
19716
|
+
el.style.color = 'white';
|
|
19717
|
+
el.style.fontWeight = 'bold';
|
|
19718
|
+
el.style.fontSize = '12px';
|
|
19719
|
+
|
|
19720
|
+
// Add project icon (you can customize this)
|
|
19721
|
+
el.innerHTML = '📋';
|
|
19722
|
+
const div = document.createElement("div");
|
|
19723
|
+
const root = client.createRoot(div);
|
|
19724
|
+
root.render( /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
19725
|
+
children: renderTooltipJsx({
|
|
19726
|
+
title: d.name,
|
|
19727
|
+
items: renderTooltip(d),
|
|
19728
|
+
link,
|
|
19729
|
+
total: d.sources,
|
|
19730
|
+
onClickLink: () => onClickLink(d)
|
|
19731
|
+
})
|
|
19732
|
+
}));
|
|
19733
|
+
roots.current.push(root);
|
|
19734
|
+
marker = new mapboxgl.Marker(el).setLngLat([d.marker.lng, d.marker.lat]).setPopup(new mapboxgl.Popup().setDOMContent(div)).addTo(mapRef);
|
|
19701
19735
|
} else {
|
|
19702
19736
|
// Default marker for other types
|
|
19703
19737
|
const el = document.createElement('div');
|
|
@@ -20543,16 +20577,13 @@ function DashboardLayout(_ref) {
|
|
|
20543
20577
|
let {
|
|
20544
20578
|
children,
|
|
20545
20579
|
header,
|
|
20546
|
-
footer
|
|
20547
|
-
isCollapsed
|
|
20580
|
+
footer
|
|
20548
20581
|
} = _ref;
|
|
20549
20582
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
20550
20583
|
className: "daf-analysis",
|
|
20551
|
-
style:
|
|
20584
|
+
style: {
|
|
20552
20585
|
backgroundColor: "#F9FAFB"
|
|
20553
|
-
},
|
|
20554
|
-
maxWidth: isCollapsed ? "calc(100vw - 70px)" : "calc(100vw - 250px)"
|
|
20555
|
-
}),
|
|
20586
|
+
},
|
|
20556
20587
|
children: [header, /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
20557
20588
|
className: "content",
|
|
20558
20589
|
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -21094,7 +21125,7 @@ function SdgList({
|
|
|
21094
21125
|
}) {
|
|
21095
21126
|
return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
21096
21127
|
children: [/*#__PURE__*/jsxRuntime.jsx(Label, {
|
|
21097
|
-
children: "SDGs"
|
|
21128
|
+
children: "SDGs:"
|
|
21098
21129
|
}), /*#__PURE__*/jsxRuntime.jsx(SDGIcons, {
|
|
21099
21130
|
sdgList: sdgList,
|
|
21100
21131
|
t: t
|
|
@@ -21177,8 +21208,7 @@ function ProjectWidget(_ref) {
|
|
|
21177
21208
|
}), !hideSDGList && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21178
21209
|
style: {
|
|
21179
21210
|
borderTop: "1px solid var(--base-gray-30)",
|
|
21180
|
-
paddingTop: "10px"
|
|
21181
|
-
minHeight: "61px"
|
|
21211
|
+
paddingTop: "10px"
|
|
21182
21212
|
},
|
|
21183
21213
|
children: /*#__PURE__*/jsxRuntime.jsx(SdgList, {
|
|
21184
21214
|
sdgList: sdgList,
|
package/dist/utils/index.js
CHANGED
|
@@ -3835,7 +3835,7 @@ function showHideForm(form, formsValue) {
|
|
|
3835
3835
|
|
|
3836
3836
|
/* eslint-disable no-constant-condition */
|
|
3837
3837
|
const getNkey = namespace => {
|
|
3838
|
-
if (['location', 'scl', 'village', 'event', 'incidents', 'corrective-actions', 'testimonials', 'initiatives', 'victims', 'pictures', 'documents', 'lir', 'sp', 'im', 'sci', 'bpe', 'gm'].includes(namespace)) {
|
|
3838
|
+
if (['location', 'scl', 'village', 'event', 'incidents', 'corrective-actions', 'testimonials', 'initiatives', 'victims', 'pictures', 'documents', 'lir', 'sp', 'im', 'sci', 'bpe', 'gm', 'project-readiness'].includes(namespace)) {
|
|
3839
3839
|
return 'scoping';
|
|
3840
3840
|
}
|
|
3841
3841
|
return namespace;
|
package/package.json
CHANGED
|
@@ -5,17 +5,12 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Every Widget inside the component (children) must be wrapped by a section tag, because i say so and if you dont like it you can change the code in the entire codebase, included but not limited to the following projects: nashiriki, tazama, kustawi, sbg, cukura, kota, mmt, and wherever the daf library is used.
|
|
7
7
|
*/
|
|
8
|
-
export default function DashboardLayout({ children, header, footer
|
|
8
|
+
export default function DashboardLayout({ children, header, footer }) {
|
|
9
9
|
return (
|
|
10
10
|
<div
|
|
11
11
|
className="daf-analysis"
|
|
12
12
|
style={{
|
|
13
13
|
backgroundColor: `#F9FAFB`,
|
|
14
|
-
...(isCollapsed === undefined
|
|
15
|
-
? {}
|
|
16
|
-
: {
|
|
17
|
-
maxWidth: isCollapsed ? `calc(100vw - 70px)` : `calc(100vw - 250px)`,
|
|
18
|
-
}),
|
|
19
14
|
}}
|
|
20
15
|
>
|
|
21
16
|
{header}
|
|
@@ -264,6 +264,48 @@ export const useGlobe = ({
|
|
|
264
264
|
|
|
265
265
|
roots.current.push(root);
|
|
266
266
|
}
|
|
267
|
+
} else if (type === "project") {
|
|
268
|
+
// Handle project markers
|
|
269
|
+
const el = document.createElement('div');
|
|
270
|
+
el.className = 'mapboxgl-marker project-marker';
|
|
271
|
+
el.style.width = '30px';
|
|
272
|
+
el.style.height = '30px';
|
|
273
|
+
el.style.backgroundColor = '#52c41a'; // Green color for projects
|
|
274
|
+
el.style.borderRadius = '50%';
|
|
275
|
+
el.style.border = '3px solid white';
|
|
276
|
+
el.style.cursor = 'pointer';
|
|
277
|
+
el.style.boxShadow = '0px 3.45px 3.45px 0px #00000029';
|
|
278
|
+
el.style.display = 'flex';
|
|
279
|
+
el.style.alignItems = 'center';
|
|
280
|
+
el.style.justifyContent = 'center';
|
|
281
|
+
el.style.color = 'white';
|
|
282
|
+
el.style.fontWeight = 'bold';
|
|
283
|
+
el.style.fontSize = '12px';
|
|
284
|
+
|
|
285
|
+
// Add project icon (you can customize this)
|
|
286
|
+
el.innerHTML = '📋';
|
|
287
|
+
|
|
288
|
+
const div = document.createElement("div");
|
|
289
|
+
const root = createRoot(div);
|
|
290
|
+
|
|
291
|
+
root.render(
|
|
292
|
+
<>
|
|
293
|
+
{renderTooltipJsx({
|
|
294
|
+
title: d.name,
|
|
295
|
+
items: renderTooltip(d),
|
|
296
|
+
link,
|
|
297
|
+
total: d.sources,
|
|
298
|
+
onClickLink: () => onClickLink(d),
|
|
299
|
+
})}
|
|
300
|
+
</>,
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
roots.current.push(root);
|
|
304
|
+
|
|
305
|
+
marker = new mapboxgl.Marker(el)
|
|
306
|
+
.setLngLat([d.marker.lng, d.marker.lat])
|
|
307
|
+
.setPopup(new mapboxgl.Popup().setDOMContent(div))
|
|
308
|
+
.addTo(mapRef);
|
|
267
309
|
} else {
|
|
268
310
|
// Default marker for other types
|
|
269
311
|
const el = document.createElement('div');
|
|
@@ -306,7 +306,7 @@ export const useMap = ({
|
|
|
306
306
|
: [Number(m.marker?.lat ?? 0), Number(m.marker?.lng ?? 0)],
|
|
307
307
|
);
|
|
308
308
|
const bounds = new L.LatLngBounds(pos);
|
|
309
|
-
mapRef.fitBounds(bounds, { padding: [
|
|
309
|
+
mapRef.fitBounds(bounds, { padding: [10, 10] });
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
312
|
}, [allData, mapRef]);
|
|
@@ -3,5 +3,6 @@ import { storyConfig as DefaultMapConfig } from "./storyConfig2.js";
|
|
|
3
3
|
import { storyConfig as TerritoryMapConfig } from "./storyConfig3.js";
|
|
4
4
|
import { storyConfig as StakeholderMapConfig } from "./storyConfig4.js";
|
|
5
5
|
import { storyConfig as ChainMapConfig } from "./storyConfig5.js";
|
|
6
|
+
import { storyConfig as ProjectConfig } from "./storyConfig6.js";
|
|
6
7
|
|
|
7
|
-
export { DefaultMapConfig, TerritoryMapConfig, StakeholderMapConfig, EventConfig, ChainMapConfig };
|
|
8
|
+
export { DefaultMapConfig, TerritoryMapConfig, StakeholderMapConfig, EventConfig, ChainMapConfig, ProjectConfig };
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { findCoordinatesByCountry } from "../Globe/globeHelpers";
|
|
2
|
+
|
|
3
|
+
// Transform project data to match Globe component expectations
|
|
4
|
+
const transformProjectsToGlobeData = (projects) => {
|
|
5
|
+
return projects.map(project => {
|
|
6
|
+
// Get coordinates from country code
|
|
7
|
+
const coordinates = findCoordinatesByCountry(project.country);
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
...project,
|
|
11
|
+
marker: {
|
|
12
|
+
lat: coordinates[0],
|
|
13
|
+
lng: coordinates[1]
|
|
14
|
+
},
|
|
15
|
+
name: project.name || project.title,
|
|
16
|
+
description: project.projectDescription || "No description available",
|
|
17
|
+
total: 1, // Each project is a single marker
|
|
18
|
+
sources: 1,
|
|
19
|
+
type: "project",
|
|
20
|
+
// Add project-specific data for tooltip
|
|
21
|
+
projectData: {
|
|
22
|
+
datastakeId: project.datastakeId,
|
|
23
|
+
sectoralScope: project.sectoralScope,
|
|
24
|
+
percentageCompletion: project.percentageCompletion,
|
|
25
|
+
country: project.country,
|
|
26
|
+
author: project.author?.name,
|
|
27
|
+
createdAt: project.createdAt,
|
|
28
|
+
mainImage: project.mainImage?.[0]?.url
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Sample project data from the user
|
|
35
|
+
const sampleProjects = [
|
|
36
|
+
{
|
|
37
|
+
"_id": "687a4d9a4cfa60f30db94c52",
|
|
38
|
+
"createdAt": "2025-07-18T00:00:00.000Z",
|
|
39
|
+
"updatedAt": "2025-07-18T00:00:00.000Z",
|
|
40
|
+
"form": "straatosProject",
|
|
41
|
+
"id": "3129457d-b787-4955-ba25-04d67fecfaaa",
|
|
42
|
+
"name": "ABC Mangrove Senegal",
|
|
43
|
+
"country": "SN",
|
|
44
|
+
"datastakeId": "PRJ-00000000103",
|
|
45
|
+
"title": "ABC Mangrove Senegal",
|
|
46
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
47
|
+
"sdgs": [],
|
|
48
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
49
|
+
"percentageCompletion": 11.76470588235294,
|
|
50
|
+
"projectDescription": "ABC Mangrove Senegal is an environmental and community-focused initiative dedicated to the restoration, preservation, and sustainable management of mangrove ecosystems in Senegal.",
|
|
51
|
+
"mainImage": [
|
|
52
|
+
{
|
|
53
|
+
"url": "https://cdn.straatos.io/dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09601/auth-bg_cropped-1754901830065.png",
|
|
54
|
+
"path": "dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09601/auth-bg_cropped-1754901830065.png",
|
|
55
|
+
"name": "auth-bg_cropped-1754901830065.png",
|
|
56
|
+
"size": 1693409,
|
|
57
|
+
"type": "image/png"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"author": {
|
|
61
|
+
"name": "Geri SHPK",
|
|
62
|
+
"country": "AL",
|
|
63
|
+
"category": "civilSociety",
|
|
64
|
+
"subCategory": "internationalNGO"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"_id": "687a57e24cfa60f30db954ca",
|
|
69
|
+
"createdAt": "2025-07-18T00:00:00.000Z",
|
|
70
|
+
"updatedAt": "2025-07-18T00:00:00.000Z",
|
|
71
|
+
"form": "project",
|
|
72
|
+
"id": "10e09c02-1986-4eb5-9069-355bffdfb93d",
|
|
73
|
+
"name": "Testing",
|
|
74
|
+
"country": "SN",
|
|
75
|
+
"datastakeId": "PRJ-00000000104",
|
|
76
|
+
"title": "Testing",
|
|
77
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
78
|
+
"sdgs": [],
|
|
79
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
80
|
+
"percentageCompletion": 28.57142857142857,
|
|
81
|
+
"author": {
|
|
82
|
+
"name": "Geri SHPK",
|
|
83
|
+
"country": "AL",
|
|
84
|
+
"category": "civilSociety",
|
|
85
|
+
"subCategory": "internationalNGO"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"_id": "687e619d4cfa60f30db967ea",
|
|
90
|
+
"createdAt": "2025-07-21T15:49:49.431Z",
|
|
91
|
+
"updatedAt": "2025-07-21T15:49:49.431Z",
|
|
92
|
+
"form": "straatosProject",
|
|
93
|
+
"id": "51440c46-2d42-452d-8ea1-614002589d4c",
|
|
94
|
+
"name": "Pietra's Project",
|
|
95
|
+
"country": "BR",
|
|
96
|
+
"datastakeId": "PRJ-00000000105",
|
|
97
|
+
"title": "Pietra's Project",
|
|
98
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
99
|
+
"sdgs": [],
|
|
100
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
101
|
+
"author": {
|
|
102
|
+
"name": "Geri SHPK",
|
|
103
|
+
"country": "AL",
|
|
104
|
+
"category": "civilSociety",
|
|
105
|
+
"subCategory": "internationalNGO"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"_id": "6883918729bcd5751e8dd579",
|
|
110
|
+
"createdAt": "2025-07-25T14:15:35.305Z",
|
|
111
|
+
"updatedAt": "2025-07-25T14:15:35.305Z",
|
|
112
|
+
"form": "straatosProject",
|
|
113
|
+
"id": "275acff8-c478-40a5-a23d-94968dca01d1",
|
|
114
|
+
"name": "efwefwe",
|
|
115
|
+
"country": "AX",
|
|
116
|
+
"datastakeId": "PRJ-00000000106",
|
|
117
|
+
"title": "efwefwe",
|
|
118
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
119
|
+
"sdgs": [],
|
|
120
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
121
|
+
"percentageCompletion": 100,
|
|
122
|
+
"author": {
|
|
123
|
+
"name": "Geri SHPK",
|
|
124
|
+
"country": "AL",
|
|
125
|
+
"category": "civilSociety",
|
|
126
|
+
"subCategory": "internationalNGO"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"_id": "6883b50e29bcd5751e8dda3e",
|
|
131
|
+
"createdAt": "2025-07-25T00:00:00.000Z",
|
|
132
|
+
"updatedAt": "2025-07-25T00:00:00.000Z",
|
|
133
|
+
"form": "project",
|
|
134
|
+
"id": "3bac13f1-4ebc-4428-9230-af1dc6ab1ab9",
|
|
135
|
+
"name": "Geri Test",
|
|
136
|
+
"country": "AS",
|
|
137
|
+
"datastakeId": "PRJ-00000000107",
|
|
138
|
+
"title": "Geri Test",
|
|
139
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
140
|
+
"sdgs": [],
|
|
141
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
142
|
+
"percentageCompletion": 33.33333333333333,
|
|
143
|
+
"projectDescription": "ABC Mangrove Senegal is an environmental and community-focused initiative dedicated to the restoration, preservation, and sustainable management of mangrove ecosystems in Senegal.",
|
|
144
|
+
"mainImage": [
|
|
145
|
+
{
|
|
146
|
+
"url": "https://cdn.straatos.io/dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09600/screenshot-from-2024-11-11-09-29-22-1758200879648.png",
|
|
147
|
+
"path": "dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09600/screenshot-from-2024-11-11-09-29-22-1758200879648.png",
|
|
148
|
+
"name": "screenshot-from-2024-11-11-09-29-22-1758200879648.png",
|
|
149
|
+
"size": 414991,
|
|
150
|
+
"type": "image/png"
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"author": {
|
|
154
|
+
"name": "Geri SHPK",
|
|
155
|
+
"country": "AL",
|
|
156
|
+
"category": "civilSociety",
|
|
157
|
+
"subCategory": "internationalNGO"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"_id": "688c66c62fb165d7a389fbf7",
|
|
162
|
+
"createdAt": "2025-08-01T07:03:34.501Z",
|
|
163
|
+
"updatedAt": "2025-08-01T07:03:34.501Z",
|
|
164
|
+
"form": "straatosProject",
|
|
165
|
+
"id": "39fd860e-412c-456f-9b70-a67d4dc82433",
|
|
166
|
+
"name": "test 777",
|
|
167
|
+
"country": "AL",
|
|
168
|
+
"datastakeId": "PRJ-00000000109",
|
|
169
|
+
"title": "test 777",
|
|
170
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
171
|
+
"sdgs": [],
|
|
172
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
173
|
+
"author": {
|
|
174
|
+
"name": "Geri SHPK",
|
|
175
|
+
"country": "AL",
|
|
176
|
+
"category": "civilSociety",
|
|
177
|
+
"subCategory": "internationalNGO"
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"_id": "68927b8d3c4650496ed9003f",
|
|
182
|
+
"createdAt": "2025-08-05T00:00:00.000Z",
|
|
183
|
+
"updatedAt": "2025-08-05T00:00:00.000Z",
|
|
184
|
+
"form": "straatosProject",
|
|
185
|
+
"id": "468204d2-28d6-4097-a362-ad12d642bf4f",
|
|
186
|
+
"name": "Current",
|
|
187
|
+
"country": "AL",
|
|
188
|
+
"datastakeId": "PRJ-00000000111",
|
|
189
|
+
"title": "Current",
|
|
190
|
+
"mainImage": [
|
|
191
|
+
{
|
|
192
|
+
"url": "https://cdn.straatos.io/dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09600/screenshot-from-2024-11-28-12-41-52-1754465225229.png",
|
|
193
|
+
"path": "dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09600/screenshot-from-2024-11-28-12-41-52-1754465225229.png",
|
|
194
|
+
"name": "screenshot-from-2024-11-28-12-41-52-1754465225229.png",
|
|
195
|
+
"size": 92090,
|
|
196
|
+
"type": "image/png"
|
|
197
|
+
}
|
|
198
|
+
],
|
|
199
|
+
"sectoralScope": "energy",
|
|
200
|
+
"sdgs": [],
|
|
201
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
202
|
+
"percentageCompletion": 17.647058823529413,
|
|
203
|
+
"projectDescription": "testing testing testing",
|
|
204
|
+
"author": {
|
|
205
|
+
"name": "Geri SHPK",
|
|
206
|
+
"country": "AL",
|
|
207
|
+
"category": "civilSociety",
|
|
208
|
+
"subCategory": "internationalNGO"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"_id": "68985abea7d389ab99d611e4",
|
|
213
|
+
"createdAt": "2025-08-10T00:00:00.000Z",
|
|
214
|
+
"updatedAt": "2025-08-10T00:00:00.000Z",
|
|
215
|
+
"form": "project",
|
|
216
|
+
"id": "c949c1a4-f83d-45fa-820f-0ee56bc023ba",
|
|
217
|
+
"name": "project 1",
|
|
218
|
+
"country": "AL",
|
|
219
|
+
"datastakeId": "PRJ-00000000112",
|
|
220
|
+
"title": "project 1",
|
|
221
|
+
"mainImage": [
|
|
222
|
+
{
|
|
223
|
+
"url": "https://cdn.straatos.io/dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09601/abcmangrove_allcot-10-1756470770827.jpg",
|
|
224
|
+
"path": "dev/company-df5378ae-704a-4a46-93b2-336cc5341456/user-e8d71443-339f-4b45-bbf5-22f0e5f09601/abcmangrove_allcot-10-1756470770827.jpg",
|
|
225
|
+
"name": "abcmangrove_allcot-10-1756470770827.jpg",
|
|
226
|
+
"size": 146120,
|
|
227
|
+
"type": "image/jpeg"
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
231
|
+
"sdgs": [],
|
|
232
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
233
|
+
"percentageCompletion": 25,
|
|
234
|
+
"author": {
|
|
235
|
+
"name": "Geri SHPK",
|
|
236
|
+
"country": "AL",
|
|
237
|
+
"category": "civilSociety",
|
|
238
|
+
"subCategory": "internationalNGO"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"_id": "68c3e1817ce6a6d7d8c16250",
|
|
243
|
+
"createdAt": "2025-09-12T00:00:00.000Z",
|
|
244
|
+
"updatedAt": "2025-09-12T00:00:00.000Z",
|
|
245
|
+
"form": "project",
|
|
246
|
+
"id": "b7a6ce62-dda3-4ffd-8f5a-e9721e15fe9f",
|
|
247
|
+
"name": "test fran",
|
|
248
|
+
"country": "CL",
|
|
249
|
+
"datastakeId": "PRJ-00000000113",
|
|
250
|
+
"title": "test fran",
|
|
251
|
+
"sectoralScope": "agricultureForestryAndOtherLandUse",
|
|
252
|
+
"sdgs": [],
|
|
253
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
254
|
+
"percentageCompletion": 25,
|
|
255
|
+
"author": {
|
|
256
|
+
"name": "Geri SHPK",
|
|
257
|
+
"country": "AL",
|
|
258
|
+
"category": "civilSociety",
|
|
259
|
+
"subCategory": "internationalNGO"
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"_id": "68cab88001892530c66c3079",
|
|
264
|
+
"createdAt": "2025-09-17T13:32:48.646Z",
|
|
265
|
+
"updatedAt": "2025-09-17T13:32:48.646Z",
|
|
266
|
+
"form": "project",
|
|
267
|
+
"id": "a64070b0-74bc-4694-8e29-8006f9de70f7",
|
|
268
|
+
"name": "Pietra's Project",
|
|
269
|
+
"country": "AL",
|
|
270
|
+
"datastakeId": "PRJ-00000000114",
|
|
271
|
+
"title": "Pietra's Project",
|
|
272
|
+
"sectoralScope": "fugitiveEmissionsFromIndustrialGases",
|
|
273
|
+
"sdgs": [],
|
|
274
|
+
"authorId": "df5378ae-704a-4a46-93b2-336cc5341456",
|
|
275
|
+
"percentageCompletion": 25,
|
|
276
|
+
"author": {
|
|
277
|
+
"name": "Geri SHPK",
|
|
278
|
+
"country": "AL",
|
|
279
|
+
"category": "civilSociety",
|
|
280
|
+
"subCategory": "internationalNGO"
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
];
|
|
284
|
+
|
|
285
|
+
export const storyConfig = {
|
|
286
|
+
data: transformProjectsToGlobeData(sampleProjects),
|
|
287
|
+
type: "project",
|
|
288
|
+
primaryLink: true,
|
|
289
|
+
showSider: true,
|
|
290
|
+
siderTitle: "Project Details",
|
|
291
|
+
renderTooltip: (project) => {
|
|
292
|
+
return [
|
|
293
|
+
{ label: "Project ID", value: project.projectData?.datastakeId || "N/A" },
|
|
294
|
+
{ label: "Sector", value: project.projectData?.sectoralScope || "N/A" },
|
|
295
|
+
{ label: "Completion", value: `${Math.round(project.projectData?.percentageCompletion || 0)}%` },
|
|
296
|
+
{ label: "Country", value: project.projectData?.country || "N/A" },
|
|
297
|
+
{ label: "Author", value: project.projectData?.author || "N/A" },
|
|
298
|
+
{ label: "Created", value: project.projectData?.createdAt ? new Date(project.projectData.createdAt).toLocaleDateString() : "N/A" }
|
|
299
|
+
];
|
|
300
|
+
},
|
|
301
|
+
renderSider: (activeMarker) => {
|
|
302
|
+
const project = activeMarker.data;
|
|
303
|
+
const projectData = project.projectData;
|
|
304
|
+
|
|
305
|
+
return (
|
|
306
|
+
<div className="project-sider">
|
|
307
|
+
{projectData?.mainImage && (
|
|
308
|
+
<div className="project-image mb-3">
|
|
309
|
+
<img
|
|
310
|
+
src={projectData.mainImage}
|
|
311
|
+
alt={project.name}
|
|
312
|
+
style={{ width: '100%', height: '200px', objectFit: 'cover', borderRadius: '8px' }}
|
|
313
|
+
/>
|
|
314
|
+
</div>
|
|
315
|
+
)}
|
|
316
|
+
|
|
317
|
+
<div className="project-details">
|
|
318
|
+
<div className="detail-row mb-2">
|
|
319
|
+
<span className="label">Project ID:</span>
|
|
320
|
+
<span className="value">{projectData?.datastakeId || "N/A"}</span>
|
|
321
|
+
</div>
|
|
322
|
+
|
|
323
|
+
<div className="detail-row mb-2">
|
|
324
|
+
<span className="label">Sectoral Scope:</span>
|
|
325
|
+
<span className="value">{projectData?.sectoralScope || "N/A"}</span>
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
<div className="detail-row mb-2">
|
|
329
|
+
<span className="label">Completion:</span>
|
|
330
|
+
<span className="value">{Math.round(projectData?.percentageCompletion || 0)}%</span>
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
<div className="detail-row mb-2">
|
|
334
|
+
<span className="label">Country:</span>
|
|
335
|
+
<span className="value">{projectData?.country || "N/A"}</span>
|
|
336
|
+
</div>
|
|
337
|
+
|
|
338
|
+
<div className="detail-row mb-2">
|
|
339
|
+
<span className="label">Author:</span>
|
|
340
|
+
<span className="value">{projectData?.author || "N/A"}</span>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
343
|
+
<div className="detail-row mb-2">
|
|
344
|
+
<span className="label">Created:</span>
|
|
345
|
+
<span className="value">
|
|
346
|
+
{projectData?.createdAt ? new Date(projectData.createdAt).toLocaleDateString() : "N/A"}
|
|
347
|
+
</span>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
{project.description && (
|
|
351
|
+
<div className="detail-row mt-3">
|
|
352
|
+
<span className="label">Description:</span>
|
|
353
|
+
<p className="value mt-1" style={{ fontSize: '14px', lineHeight: '1.4' }}>
|
|
354
|
+
{project.description}
|
|
355
|
+
</p>
|
|
356
|
+
</div>
|
|
357
|
+
)}
|
|
358
|
+
</div>
|
|
359
|
+
</div>
|
|
360
|
+
);
|
|
361
|
+
},
|
|
362
|
+
onClickLink: (project) => {
|
|
363
|
+
console.log('Project clicked:', project);
|
|
364
|
+
// You can add navigation logic here
|
|
365
|
+
}
|
|
366
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Label } from "../style";
|
|
2
2
|
import SDGIcons from "../../../../UI/SDGIcon/index.jsx";
|
|
3
3
|
export default function SdgList({ sdgList = [], t }) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
return (
|
|
5
|
+
<>
|
|
6
|
+
<Label>SDGs:</Label>
|
|
7
|
+
<SDGIcons sdgList={sdgList} t={t} />
|
|
8
|
+
</>
|
|
9
|
+
);
|
|
10
10
|
}
|
|
@@ -144,7 +144,7 @@ export const filterInputs = (form, data, repeatValues) => {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
export const getNkey = (namespace) => {
|
|
147
|
-
if (['location', 'scl', 'village', 'event', 'incidents', 'corrective-actions', 'testimonials', 'initiatives', 'victims', 'pictures', 'documents', 'lir', 'sp', 'im', 'sci', 'bpe', 'gm'].includes(namespace)) {
|
|
147
|
+
if (['location', 'scl', 'village', 'event', 'incidents', 'corrective-actions', 'testimonials', 'initiatives', 'victims', 'pictures', 'documents', 'lir', 'sp', 'im', 'sci', 'bpe', 'gm', 'project-readiness'].includes(namespace)) {
|
|
148
148
|
return 'scoping';
|
|
149
149
|
}
|
|
150
150
|
|
package/.env
DELETED
package/.vscode/settings.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"cSpell.words": ["cukura"],
|
|
3
|
-
"files.autoSave": "afterDelay",
|
|
4
|
-
"editor.wordWrap": "on",
|
|
5
|
-
"editor.autoClosingBrackets": "always",
|
|
6
|
-
"editor.autoClosingComments": "always",
|
|
7
|
-
"editor.autoClosingQuotes": "always",
|
|
8
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
9
|
-
"editor.formatOnPaste": true,
|
|
10
|
-
"editor.formatOnSave": true,
|
|
11
|
-
"notebook.defaultFormatter": "esbenp.prettier-vscode",
|
|
12
|
-
"javascript.format.semicolons": "insert"
|
|
13
|
-
}
|