datastake-daf 0.6.784 → 0.6.785

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.
Files changed (21) hide show
  1. package/dist/components/index.js +99 -99
  2. package/dist/pages/index.js +846 -65
  3. package/dist/style/datastake/mapbox-gl.css +330 -0
  4. package/dist/utils/index.js +58 -0
  5. package/package.json +1 -1
  6. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/KeyInformation/index.jsx +48 -0
  7. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/PlantedSpecies.jsx +73 -0
  8. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/SeedlingsHeight.jsx +44 -0
  9. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/Stats.jsx +86 -0
  10. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/VegetationHealth.jsx +73 -0
  11. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/index.jsx +92 -0
  12. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MonitoringScopeAndFindings/index.jsx +348 -0
  13. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/config.js +35 -0
  14. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/index.jsx +30 -0
  15. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CommunityParticipation/CommunityStats/helper.js +1 -1
  16. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/index.jsx +1 -1
  17. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleOutcomes/index.jsx +1 -1
  18. package/src/@daf/pages/Summary/Activities/PlantingCycle/helper.js +0 -56
  19. package/src/@daf/utils/numbers.js +57 -0
  20. package/src/pages.js +1 -0
  21. package/src/utils.js +1 -1
@@ -36289,7 +36289,7 @@ const getKeyIndicatorConfig = ({
36289
36289
  }
36290
36290
  }];
36291
36291
 
36292
- const KeyInformation$1 = ({
36292
+ const KeyInformation$2 = ({
36293
36293
  options = {},
36294
36294
  selectedPartners = {},
36295
36295
  t = () => {},
@@ -38001,7 +38001,7 @@ const OperatorSummary = ({
38001
38001
  size: "small"
38002
38002
  }) : null
38003
38003
  })
38004
- }), /*#__PURE__*/jsxRuntime.jsx(KeyInformation$1, {
38004
+ }), /*#__PURE__*/jsxRuntime.jsx(KeyInformation$2, {
38005
38005
  options: options,
38006
38006
  selectedPartners: selectedPartners,
38007
38007
  t: t,
@@ -42120,6 +42120,63 @@ const renderNumber = (val, doubleDigit = false) => {
42120
42120
  return _string;
42121
42121
  };
42122
42122
 
42123
+ /**
42124
+ * Calculates stat change object for StatCard component based on current and previous values
42125
+ * @param {Object} data - Object with current and previous values
42126
+ * @param {number} data.current - Current value
42127
+ * @param {number} data.previous - Previous value
42128
+ * @param {Object} options - Optional configuration
42129
+ * @param {string} options.tooltipText - Custom tooltip text
42130
+ * @param {string} options.format - Format type: 'percentage' (default) or 'absolute'
42131
+ * @param {number} options.decimalPlaces - Number of decimal places for percentage (default: 1)
42132
+ * @returns {Object|null} Change object for StatCard or null if data is invalid
42133
+ */
42134
+ const calculateStatChange = (data, options = {}) => {
42135
+ if (!data || typeof data !== 'object') {
42136
+ return null;
42137
+ }
42138
+ const {
42139
+ current,
42140
+ previous
42141
+ } = data;
42142
+
42143
+ // Validate that both values are numbers
42144
+ if (typeof current !== 'number' || typeof previous !== 'number') {
42145
+ return null;
42146
+ }
42147
+
42148
+ // If previous is 0, we can't calculate percentage change
42149
+ if (previous === 0) {
42150
+ return null;
42151
+ }
42152
+ const {
42153
+ tooltipText,
42154
+ format = 'percentage',
42155
+ decimalPlaces = 1
42156
+ } = options;
42157
+
42158
+ // Calculate the difference
42159
+ const difference = current - previous;
42160
+ const isPositive = difference >= 0;
42161
+ const direction = isPositive ? 'up' : 'down';
42162
+
42163
+ // Format the value
42164
+ let value;
42165
+ if (format === 'absolute') {
42166
+ // Show absolute difference
42167
+ value = Math.abs(difference).toLocaleString();
42168
+ } else {
42169
+ // Show percentage change
42170
+ const percentageChange = Math.abs(difference) / previous * 100;
42171
+ value = `${percentageChange.toFixed(decimalPlaces)}%`;
42172
+ }
42173
+ return {
42174
+ value,
42175
+ direction,
42176
+ tooltipText: tooltipText || undefined
42177
+ };
42178
+ };
42179
+
42123
42180
  styled__default["default"].div`
42124
42181
  height: 333px;
42125
42182
  width: calc(100% - 48px);
@@ -43274,7 +43331,7 @@ styled__default["default"].div`
43274
43331
  flex: 1;
43275
43332
  `;
43276
43333
 
43277
- const getKeyIndicatorsRowConfig$1 = ({
43334
+ const getKeyIndicatorsRowConfig$2 = ({
43278
43335
  t,
43279
43336
  data = {}
43280
43337
  }) => [{
@@ -43933,7 +43990,7 @@ const RestorationActivitySummary = ({
43933
43990
  loading,
43934
43991
  t = () => {}
43935
43992
  }) => {
43936
- const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig$1({
43993
+ const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig$2({
43937
43994
  t,
43938
43995
  data: activityData
43939
43996
  }), [t, activityData]);
@@ -44143,63 +44200,6 @@ const PlantingLocations = ({
44143
44200
  });
44144
44201
  };
44145
44202
 
44146
- /**
44147
- * Calculates stat change object for StatCard component based on current and previous values
44148
- * @param {Object} data - Object with current and previous values
44149
- * @param {number} data.current - Current value
44150
- * @param {number} data.previous - Previous value
44151
- * @param {Object} options - Optional configuration
44152
- * @param {string} options.tooltipText - Custom tooltip text
44153
- * @param {string} options.format - Format type: 'percentage' (default) or 'absolute'
44154
- * @param {number} options.decimalPlaces - Number of decimal places for percentage (default: 1)
44155
- * @returns {Object|null} Change object for StatCard or null if data is invalid
44156
- */
44157
- const calculateStatChange = (data, options = {}) => {
44158
- if (!data || typeof data !== 'object') {
44159
- return null;
44160
- }
44161
- const {
44162
- current,
44163
- previous
44164
- } = data;
44165
-
44166
- // Validate that both values are numbers
44167
- if (typeof current !== 'number' || typeof previous !== 'number') {
44168
- return null;
44169
- }
44170
-
44171
- // If previous is 0, we can't calculate percentage change
44172
- if (previous === 0) {
44173
- return null;
44174
- }
44175
- const {
44176
- tooltipText,
44177
- format = 'percentage',
44178
- decimalPlaces = 1
44179
- } = options;
44180
-
44181
- // Calculate the difference
44182
- const difference = current - previous;
44183
- const isPositive = difference >= 0;
44184
- const direction = isPositive ? 'up' : 'down';
44185
-
44186
- // Format the value
44187
- let value;
44188
- if (format === 'absolute') {
44189
- // Show absolute difference
44190
- value = Math.abs(difference).toLocaleString();
44191
- } else {
44192
- // Show percentage change
44193
- const percentageChange = Math.abs(difference) / previous * 100;
44194
- value = `${percentageChange.toFixed(decimalPlaces)}%`;
44195
- }
44196
- return {
44197
- value,
44198
- direction,
44199
- tooltipText: tooltipText || undefined
44200
- };
44201
- };
44202
-
44203
44203
  /**
44204
44204
  * Formats a date based on the time filter
44205
44205
  * @param {dayjs.Dayjs} date - The date to format
@@ -46557,7 +46557,7 @@ const AssociatedInformation = ({
46557
46557
  });
46558
46558
  };
46559
46559
 
46560
- const getKeyIndicatorsRowConfig = ({
46560
+ const getKeyIndicatorsRowConfig$1 = ({
46561
46561
  t,
46562
46562
  data = {}
46563
46563
  }) => [{
@@ -46597,7 +46597,7 @@ const getKeyIndicatorsRowConfig = ({
46597
46597
  }
46598
46598
  }];
46599
46599
 
46600
- const KeyInformation = ({
46600
+ const KeyInformation$1 = ({
46601
46601
  id,
46602
46602
  t = () => {},
46603
46603
  getSummaryDetail,
@@ -46631,7 +46631,7 @@ const KeyInformation = ({
46631
46631
  config: defaultConfig,
46632
46632
  getData: customGetData
46633
46633
  });
46634
- const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig({
46634
+ const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig$1({
46635
46635
  t,
46636
46636
  data: keyInformationData
46637
46637
  }), [t, keyInformationData]);
@@ -46666,7 +46666,7 @@ const PlantingCycleSummary = ({
46666
46666
  goBackTo: header?.goBackTo,
46667
46667
  loading: header?.loading
46668
46668
  }),
46669
- children: [/*#__PURE__*/jsxRuntime.jsx(KeyInformation, {
46669
+ children: [/*#__PURE__*/jsxRuntime.jsx(KeyInformation$1, {
46670
46670
  id: id,
46671
46671
  t: t,
46672
46672
  getSummaryDetail: getSummaryDetail,
@@ -46703,6 +46703,786 @@ const PlantingCycleSummary = ({
46703
46703
  });
46704
46704
  };
46705
46705
 
46706
+ const getKeyIndicatorsRowConfig = ({
46707
+ t,
46708
+ data = {}
46709
+ }) => [{
46710
+ label: t('Region'),
46711
+ render: () => {
46712
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
46713
+ children: data?.region || '-'
46714
+ });
46715
+ }
46716
+ }, {
46717
+ label: t('Associated Plots'),
46718
+ render: () => {
46719
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
46720
+ children: data?.associatedPlotsCount || '0'
46721
+ });
46722
+ }
46723
+ }, {
46724
+ label: t('Implementation Partners'),
46725
+ render: () => {
46726
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
46727
+ children: data?.partnersCount || '0'
46728
+ });
46729
+ }
46730
+ }, {
46731
+ label: t('Total Activities'),
46732
+ render: () => {
46733
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
46734
+ children: data?.activitiesCount || '0'
46735
+ });
46736
+ }
46737
+ }, {
46738
+ label: t('Information Sources'),
46739
+ render: () => {
46740
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
46741
+ children: data?.informationSourcesCount || '0'
46742
+ });
46743
+ }
46744
+ }];
46745
+
46746
+ const KeyInformation = ({
46747
+ id,
46748
+ t = () => {},
46749
+ getSummaryDetail,
46750
+ loading = false
46751
+ }) => {
46752
+ const defaultConfig = React.useMemo(() => ({
46753
+ basepath: "events/monitoring-campaign",
46754
+ url: `/summary/${id}/key-information`,
46755
+ stop: !id
46756
+ }), [id]);
46757
+ const customGetData = React.useMemo(() => {
46758
+ if (getSummaryDetail && id) {
46759
+ return ({
46760
+ url,
46761
+ params = {}
46762
+ }) => {
46763
+ const match = url.match(/\/summary\/[^/]+\/(.+)/);
46764
+ if (match) {
46765
+ const [, type] = match;
46766
+ return getSummaryDetail(id, type, params);
46767
+ }
46768
+ throw new Error(`Invalid URL format: ${url}`);
46769
+ };
46770
+ }
46771
+ return undefined;
46772
+ }, [getSummaryDetail, id]);
46773
+ const {
46774
+ loading: keyInformationLoading,
46775
+ data: keyInformationData
46776
+ } = useWidgetFetch({
46777
+ config: defaultConfig,
46778
+ getData: customGetData
46779
+ });
46780
+ const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig({
46781
+ t,
46782
+ data: keyInformationData
46783
+ }), [t, keyInformationData]);
46784
+ return /*#__PURE__*/jsxRuntime.jsx("section", {
46785
+ children: /*#__PURE__*/jsxRuntime.jsx(KeyIndicatorsWidget, {
46786
+ title: t("Key Information"),
46787
+ config: keyIndicatorsConfig,
46788
+ loading: loading || keyInformationLoading
46789
+ })
46790
+ });
46791
+ };
46792
+
46793
+ const VISITS_TAB = "visits";
46794
+ const GROWTH_AND_SURVIVAL_TAB = "growthAndSurvival";
46795
+ const FAUNA_SIGHTINGS_TAB = "faunaSightings";
46796
+ const INVASIVE_SPECIES_TAB = "invasiveSpecies";
46797
+ const SYMPTOM_HOTSPOTS_TAB = "symptomHotspots";
46798
+ const SOIL_TAB = "soil";
46799
+ const MonitoringScopeAndFindings = ({
46800
+ id,
46801
+ getSummaryDetail,
46802
+ loading = false,
46803
+ t = s => s
46804
+ }) => {
46805
+ const [activeTab, setActiveTab] = React.useState(VISITS_TAB);
46806
+ const defaultConfig = React.useMemo(() => ({
46807
+ basepath: "events/monitoring-campaign",
46808
+ url: `/summary/${id}/monitoring-scope`,
46809
+ stop: !id
46810
+ }), [id]);
46811
+ const customGetData = React.useMemo(() => {
46812
+ if (getSummaryDetail && id) {
46813
+ return ({
46814
+ url,
46815
+ params = {}
46816
+ }) => {
46817
+ const match = url.match(/\/summary\/[^/]+\/(.+)/);
46818
+ if (match) {
46819
+ const [, type] = match;
46820
+ return getSummaryDetail(id, type, {
46821
+ ...params,
46822
+ tab: activeTab
46823
+ });
46824
+ }
46825
+ throw new Error(`Invalid URL format: ${url}`);
46826
+ };
46827
+ }
46828
+ return undefined;
46829
+ }, [getSummaryDetail, id, activeTab]);
46830
+ const {
46831
+ loading: monitoringScopeLoading,
46832
+ data: monitoringScopeData
46833
+ } = useWidgetFetch({
46834
+ config: defaultConfig,
46835
+ getData: customGetData
46836
+ });
46837
+ const filtersConfig = React.useMemo(() => {
46838
+ switch (activeTab) {
46839
+ case GROWTH_AND_SURVIVAL_TAB:
46840
+ return [{
46841
+ label: t("Mangrove Survival Rate"),
46842
+ placeholder: t("Select"),
46843
+ key: "mangroveSurvivalRate",
46844
+ type: "slider"
46845
+ }, {
46846
+ label: t("Planting Density"),
46847
+ placeholder: t("Select"),
46848
+ key: "plantingDensity",
46849
+ type: "select"
46850
+ }];
46851
+ case FAUNA_SIGHTINGS_TAB:
46852
+ return [{
46853
+ label: t("Fauna Observed"),
46854
+ placeholder: t("Select"),
46855
+ key: "faunaSightings",
46856
+ type: "select",
46857
+ options: [{
46858
+ label: t("Birds"),
46859
+ value: "birds"
46860
+ }, {
46861
+ label: t("Crabs"),
46862
+ value: "crabs"
46863
+ }, {
46864
+ label: t("Fish"),
46865
+ value: "fish"
46866
+ }, {
46867
+ label: t("Molluscs"),
46868
+ value: "molluscs"
46869
+ }, {
46870
+ label: t("Oysters"),
46871
+ value: "oysters"
46872
+ }]
46873
+ }];
46874
+ case INVASIVE_SPECIES_TAB:
46875
+ return [{
46876
+ label: t("Fauna Observed"),
46877
+ placeholder: t("Select"),
46878
+ key: "invasiveSpecies",
46879
+ type: "select",
46880
+ options: [{
46881
+ label: t("Spiders"),
46882
+ value: "spiders"
46883
+ }, {
46884
+ label: t("Scale insects"),
46885
+ value: "scaleInsects"
46886
+ }, {
46887
+ label: t("Caterpillars"),
46888
+ value: "caterpillars"
46889
+ }, {
46890
+ label: t("Unidentified pests"),
46891
+ value: "unidentifiedPests"
46892
+ }, {
46893
+ label: t("Other"),
46894
+ value: "other"
46895
+ }]
46896
+ }];
46897
+ case SYMPTOM_HOTSPOTS_TAB:
46898
+ return [{
46899
+ label: t("Symptom Hotspots"),
46900
+ placeholder: t("Select"),
46901
+ key: "symptomHotspots",
46902
+ type: "select",
46903
+ options: [{
46904
+ label: t("Reddish spots on leaves"),
46905
+ value: "reddishSpotsOnLeaves"
46906
+ }, {
46907
+ label: t("Black spots on leaves"),
46908
+ value: "blackSpotsOnLeaves"
46909
+ }, {
46910
+ label: t("Yellowing of leaves"),
46911
+ value: "yellowingOfLeaves"
46912
+ }, {
46913
+ label: t("Presence of mosaic"),
46914
+ value: "presenceOfMosaic"
46915
+ }]
46916
+ }];
46917
+ case SOIL_TAB:
46918
+ return [{
46919
+ label: t("Soil"),
46920
+ placeholder: t("Select"),
46921
+ key: "soil",
46922
+ type: "select",
46923
+ options: [{
46924
+ label: t("Sandy"),
46925
+ value: "sandy"
46926
+ }, {
46927
+ label: t("Clay"),
46928
+ value: "clay"
46929
+ }, {
46930
+ label: t("Muddy"),
46931
+ value: "muddy"
46932
+ }, {
46933
+ label: t("Loamy"),
46934
+ value: "loamy"
46935
+ }, {
46936
+ label: t("Mixed"),
46937
+ value: "mixed"
46938
+ }]
46939
+ }];
46940
+ default:
46941
+ return [];
46942
+ }
46943
+ }, [activeTab, t]);
46944
+ const mappedData = React.useMemo(() => {
46945
+ if (!monitoringScopeData || !monitoringScopeData.plots) {
46946
+ return [];
46947
+ }
46948
+ const {
46949
+ plots = [],
46950
+ monitoringActivities = []
46951
+ } = monitoringScopeData;
46952
+ if (activeTab === VISITS_TAB) {
46953
+ return plots.map((plot, index) => {
46954
+ const area = plot?.perimeter ? plot.perimeter.map(coord => Array.isArray(coord) && coord.length >= 2 ? [coord[1], coord[0]] : coord) : null;
46955
+ const validArea = area && Array.isArray(area) && area.length >= 3 ? area : null;
46956
+ const matchingActivity = monitoringActivities?.find(activity => activity.plotId === plot.id || activity.plotId === plot._id);
46957
+ const gps = matchingActivity?.locationCheckArrival ? {
46958
+ latitude: matchingActivity.locationCheckArrival.latitude,
46959
+ longitude: matchingActivity.locationCheckArrival.longitude
46960
+ } : null;
46961
+ return {
46962
+ _id: plot._id || {},
46963
+ area: validArea,
46964
+ color: "#15FFFFB2",
46965
+ datastakeId: plot.datastakeId || `PLOT-${String(index + 1).padStart(9, '0')}`,
46966
+ gps: gps,
46967
+ id: plot.id || plot._id || `plot-${index}`,
46968
+ name: plot.name || t("Plot"),
46969
+ date: matchingActivity?.date,
46970
+ subTitle: matchingActivity?.date ? renderDateFormatted(matchingActivity.date, "DD MMM YY") : plot.name,
46971
+ plotName: plot.name,
46972
+ territoryTitle: plot.name,
46973
+ type: plot.type || 'Operational Plot',
46974
+ lastVisit: matchingActivity?.date,
46975
+ implementer: matchingActivity?.implementer,
46976
+ areaHa: plot.area
46977
+ };
46978
+ });
46979
+ }
46980
+ return plots.map((plot, index) => {
46981
+ const area = plot?.perimeter ? plot.perimeter.map(coord => Array.isArray(coord) && coord.length >= 2 ? [coord[1], coord[0]] : coord) : null;
46982
+ const validArea = area && Array.isArray(area) && area.length >= 3 ? area : null;
46983
+ return {
46984
+ _id: plot._id || {},
46985
+ area: validArea,
46986
+ color: "#15FFFFB2",
46987
+ datastakeId: plot.datastakeId || `PLOT-${String(index + 1).padStart(9, '0')}`,
46988
+ id: plot.id || plot._id || `plot-${index}`,
46989
+ name: plot.name || t("Plot"),
46990
+ plotName: plot.name,
46991
+ territoryTitle: plot.name,
46992
+ type: plot.type || 'Operational Plot'
46993
+ };
46994
+ });
46995
+ }, [monitoringScopeData, activeTab, t]);
46996
+ return /*#__PURE__*/jsxRuntime.jsx("section", {
46997
+ children: /*#__PURE__*/jsxRuntime.jsx(Widget, {
46998
+ title: t("Monitoring Scope & Findings"),
46999
+ className: "v2-widget no-px no-p-body h-w-btn-header with-border-header",
47000
+ style: {
47001
+ height: '100%',
47002
+ display: 'flex',
47003
+ flexDirection: 'column'
47004
+ },
47005
+ tabsConfig: {
47006
+ tabs: [{
47007
+ label: t("Visits"),
47008
+ value: VISITS_TAB
47009
+ }, {
47010
+ label: t("Growth & Survival"),
47011
+ value: GROWTH_AND_SURVIVAL_TAB
47012
+ }, {
47013
+ label: t("Fauna Sightings"),
47014
+ value: FAUNA_SIGHTINGS_TAB
47015
+ }, {
47016
+ label: t("Invasive Species"),
47017
+ value: INVASIVE_SPECIES_TAB
47018
+ }, {
47019
+ label: t("Symptom Hotspots"),
47020
+ value: SYMPTOM_HOTSPOTS_TAB
47021
+ }, {
47022
+ label: t("Soil"),
47023
+ value: SOIL_TAB
47024
+ }],
47025
+ value: activeTab,
47026
+ onChange: setActiveTab
47027
+ },
47028
+ children: /*#__PURE__*/jsxRuntime.jsx(Map$1, {
47029
+ data: mappedData,
47030
+ link: false,
47031
+ style: {
47032
+ height: '100%',
47033
+ width: '100%'
47034
+ },
47035
+ maxZoom: 18,
47036
+ isSatellite: true,
47037
+ onClickLink: () => {},
47038
+ onFilterChange: () => {},
47039
+ primaryLink: true,
47040
+ showSider: false,
47041
+ filtersConfig: filtersConfig,
47042
+ renderTooltipForLocation: data => {
47043
+ if (activeTab === VISITS_TAB && data.gps) {
47044
+ const coordinates = data.gps?.latitude && data.gps?.longitude ? convertDMS(data.gps.latitude, data.gps.longitude) : null;
47045
+ if (!coordinates) {
47046
+ return [];
47047
+ }
47048
+ const iconColor = "#016C6E";
47049
+ const tooltipItems = [{
47050
+ label: t("Coordinates"),
47051
+ value: /*#__PURE__*/jsxRuntime.jsxs("div", {
47052
+ style: {
47053
+ display: 'flex',
47054
+ alignItems: 'center',
47055
+ gap: '6px',
47056
+ flexWrap: 'nowrap'
47057
+ },
47058
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
47059
+ style: {
47060
+ display: 'flex',
47061
+ alignItems: 'center'
47062
+ },
47063
+ children: [/*#__PURE__*/jsxRuntime.jsx(CustomIcon, {
47064
+ name: "SpacingHeight",
47065
+ width: 14,
47066
+ height: 14,
47067
+ color: iconColor
47068
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
47069
+ style: {
47070
+ fontWeight: 600,
47071
+ marginLeft: '4px'
47072
+ },
47073
+ children: coordinates[0]
47074
+ })]
47075
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47076
+ style: {
47077
+ display: 'flex',
47078
+ alignItems: 'center'
47079
+ },
47080
+ children: [/*#__PURE__*/jsxRuntime.jsx(CustomIcon, {
47081
+ name: "SpacingWidth",
47082
+ width: 14,
47083
+ height: 14,
47084
+ color: iconColor
47085
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
47086
+ style: {
47087
+ fontWeight: 600,
47088
+ marginLeft: '4px'
47089
+ },
47090
+ children: coordinates[1]
47091
+ })]
47092
+ })]
47093
+ })
47094
+ }];
47095
+ if (data.date) {
47096
+ tooltipItems.push({
47097
+ label: t("Date"),
47098
+ value: renderDateFormatted(data.date, "DD MMM YY")
47099
+ });
47100
+ }
47101
+ if (data.implementer) {
47102
+ tooltipItems.push({
47103
+ label: t("Implementer"),
47104
+ value: data.implementer
47105
+ });
47106
+ }
47107
+ return tooltipItems;
47108
+ }
47109
+ return [];
47110
+ },
47111
+ renderTooltipForTerritory: data => {
47112
+ const items = [{
47113
+ label: t("Plot Name"),
47114
+ value: data.plotName || data.name || "--"
47115
+ }];
47116
+ if (activeTab === VISITS_TAB && data.lastVisit) {
47117
+ items.push({
47118
+ label: t("Last visit"),
47119
+ value: renderDateFormatted(data.lastVisit, "DD MMM YY")
47120
+ });
47121
+ }
47122
+ if (activeTab === VISITS_TAB && data.areaHa) {
47123
+ items.push({
47124
+ label: t("Area"),
47125
+ value: `${data.areaHa} ha`
47126
+ });
47127
+ }
47128
+ return items;
47129
+ },
47130
+ renderTooltipTags: () => {},
47131
+ type: "location-territory",
47132
+ loading: loading || monitoringScopeLoading
47133
+ })
47134
+ })
47135
+ });
47136
+ };
47137
+
47138
+ const COLORS$1 = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
47139
+ const VegetationHealth = ({
47140
+ vegetationHealthChart,
47141
+ t = s => s
47142
+ }) => {
47143
+ const pieData = React.useMemo(() => {
47144
+ const data = vegetationHealthChart || [];
47145
+ const total = data.reduce((sum, item) => sum + (Number(item?.value) || 0), 0);
47146
+ return data.map((item, index) => ({
47147
+ value: Number(item?.value) || 0,
47148
+ percent: total > 0 ? (Number(item?.value) || 0) / total : 0,
47149
+ color: COLORS$1[index % COLORS$1.length],
47150
+ label: item?.type || '',
47151
+ key: item?.type || `item-${index}`
47152
+ }));
47153
+ }, [vegetationHealthChart]);
47154
+ const isEmpty = React.useMemo(() => {
47155
+ return !vegetationHealthChart || vegetationHealthChart.length === 0 || vegetationHealthChart.every(item => !item?.value || Number(item.value) === 0);
47156
+ }, [vegetationHealthChart]);
47157
+ const getTooltipChildren = React.useCallback(item => {
47158
+ if (isEmpty) {
47159
+ return null;
47160
+ }
47161
+ return renderTooltipJsx({
47162
+ title: t("Vegetation Health"),
47163
+ items: [{
47164
+ color: item.color,
47165
+ label: item.label || '',
47166
+ value: `${item.value || 0}%`
47167
+ }]
47168
+ });
47169
+ }, [t, isEmpty]);
47170
+ return /*#__PURE__*/jsxRuntime.jsx(Widget, {
47171
+ title: t("Vegetation Health"),
47172
+ className: "with-border-header h-w-btn-header",
47173
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
47174
+ className: "flex flex-1 flex-column justify-content-center",
47175
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
47176
+ className: "flex justify-content-center w-full",
47177
+ children: /*#__PURE__*/jsxRuntime.jsx(Chart, {
47178
+ data: pieData,
47179
+ isPie: true,
47180
+ isEmpty: isEmpty,
47181
+ getTooltipChildren: getTooltipChildren,
47182
+ mouseXOffset: 10,
47183
+ mouseYOffset: 10,
47184
+ changeOpacityOnHover: false,
47185
+ doConstraints: false
47186
+ })
47187
+ })
47188
+ })
47189
+ });
47190
+ };
47191
+
47192
+ const SeedlingsHeight = ({
47193
+ seedlingsHeightChart,
47194
+ t = s => s
47195
+ }) => {
47196
+ return /*#__PURE__*/jsxRuntime.jsx(Widget, {
47197
+ title: t("Seedlings Height"),
47198
+ className: "with-border-header h-w-btn-header",
47199
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
47200
+ className: "flex flex-1 flex-column justify-content-center",
47201
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
47202
+ className: "flex justify-content-center w-full",
47203
+ children: /*#__PURE__*/jsxRuntime.jsx(ColumnChart, {
47204
+ data: seedlingsHeightChart || [],
47205
+ xFieldKey: "label",
47206
+ yFieldKey: "value",
47207
+ animated: true,
47208
+ height: 200,
47209
+ color: "#016C6E",
47210
+ renderTooltipContent: (title, data) => {
47211
+ if (!data || data.length === 0) return {};
47212
+ const item = data[0]?.data || data[0];
47213
+ return {
47214
+ title: t("Seedlings Height"),
47215
+ subTitle: title,
47216
+ items: [{
47217
+ label: t("Count"),
47218
+ value: item?.value || 0
47219
+ }]
47220
+ };
47221
+ }
47222
+ })
47223
+ })
47224
+ })
47225
+ });
47226
+ };
47227
+
47228
+ const COLORS = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
47229
+ const PlantedSpecies = ({
47230
+ plantedSpeciesChart,
47231
+ t = s => s
47232
+ }) => {
47233
+ const pieData = React.useMemo(() => {
47234
+ const data = plantedSpeciesChart || [];
47235
+ const total = data.reduce((sum, item) => sum + (Number(item?.value) || 0), 0);
47236
+ return data.map((item, index) => ({
47237
+ value: Number(item?.value) || 0,
47238
+ percent: total > 0 ? (Number(item?.value) || 0) / total : 0,
47239
+ color: COLORS[index % COLORS.length],
47240
+ label: item?.type || '',
47241
+ key: item?.type || `item-${index}`
47242
+ }));
47243
+ }, [plantedSpeciesChart]);
47244
+ const isEmpty = React.useMemo(() => {
47245
+ return !plantedSpeciesChart || plantedSpeciesChart.length === 0 || plantedSpeciesChart.every(item => !item?.value || Number(item.value) === 0);
47246
+ }, [plantedSpeciesChart]);
47247
+ const getTooltipChildren = React.useCallback(item => {
47248
+ if (isEmpty) {
47249
+ return null;
47250
+ }
47251
+ return renderTooltipJsx({
47252
+ title: t("Planted Species"),
47253
+ items: [{
47254
+ color: item.color,
47255
+ label: item.label || '',
47256
+ value: item.value || 0
47257
+ }]
47258
+ });
47259
+ }, [t, isEmpty]);
47260
+ return /*#__PURE__*/jsxRuntime.jsx(Widget, {
47261
+ title: t("Planted Species"),
47262
+ className: "with-border-header h-w-btn-header",
47263
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
47264
+ className: "flex flex-1 flex-column justify-content-center",
47265
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
47266
+ className: "flex justify-content-center w-full",
47267
+ children: /*#__PURE__*/jsxRuntime.jsx(Chart, {
47268
+ data: pieData,
47269
+ isPie: true,
47270
+ isEmpty: isEmpty,
47271
+ getTooltipChildren: getTooltipChildren,
47272
+ mouseXOffset: 10,
47273
+ mouseYOffset: 10,
47274
+ changeOpacityOnHover: false,
47275
+ doConstraints: false
47276
+ })
47277
+ })
47278
+ })
47279
+ });
47280
+ };
47281
+
47282
+ const Stats = ({
47283
+ survivalRate,
47284
+ averageHeight,
47285
+ averageDiameter,
47286
+ t = s => s
47287
+ }) => {
47288
+ const survivalRateChange = React.useMemo(() => {
47289
+ if (!survivalRate) return null;
47290
+ return calculateStatChange({
47291
+ current: Number(survivalRate.current) || 0,
47292
+ previous: Number(survivalRate.previous) || 0
47293
+ }, {
47294
+ tooltipText: t("In comparison to last period"),
47295
+ format: 'absolute'
47296
+ });
47297
+ }, [survivalRate, t]);
47298
+ const averageHeightChange = React.useMemo(() => {
47299
+ if (!averageHeight) return null;
47300
+ return calculateStatChange({
47301
+ current: Number(averageHeight.current) || 0,
47302
+ previous: Number(averageHeight.previous) || 0
47303
+ }, {
47304
+ tooltipText: t("In comparison to last period"),
47305
+ format: 'absolute'
47306
+ });
47307
+ }, [averageHeight, t]);
47308
+ const averageDiameterChange = React.useMemo(() => {
47309
+ if (!averageDiameter) return null;
47310
+ return calculateStatChange({
47311
+ current: Number(averageDiameter.current) || 0,
47312
+ previous: Number(averageDiameter.previous) || 0
47313
+ }, {
47314
+ tooltipText: t("In comparison to last period"),
47315
+ format: 'absolute'
47316
+ });
47317
+ }, [averageDiameter, t]);
47318
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
47319
+ style: {
47320
+ display: "flex",
47321
+ gap: "24px",
47322
+ marginBottom: "24px"
47323
+ },
47324
+ children: [/*#__PURE__*/jsxRuntime.jsx("section", {
47325
+ style: {
47326
+ flex: 1
47327
+ },
47328
+ children: /*#__PURE__*/jsxRuntime.jsx(StatCard, {
47329
+ title: t("Survival Rate"),
47330
+ value: survivalRate ? Number(survivalRate.current).toLocaleString() : "0",
47331
+ icon: "EventCalendar",
47332
+ change: survivalRateChange
47333
+ })
47334
+ }), /*#__PURE__*/jsxRuntime.jsx("section", {
47335
+ style: {
47336
+ flex: 1
47337
+ },
47338
+ children: /*#__PURE__*/jsxRuntime.jsx(StatCard, {
47339
+ title: t("Average Height"),
47340
+ value: averageHeight ? Number(averageHeight.current).toLocaleString() + " cm" : "0 cm",
47341
+ icon: "ProjectLocation",
47342
+ change: averageHeightChange
47343
+ })
47344
+ }), /*#__PURE__*/jsxRuntime.jsx("section", {
47345
+ style: {
47346
+ flex: 1
47347
+ },
47348
+ children: /*#__PURE__*/jsxRuntime.jsx(StatCard, {
47349
+ title: t("Average Diameter"),
47350
+ value: averageDiameter ? Number(averageDiameter.current).toLocaleString() + " mm" : "0 mm",
47351
+ icon: "Activity",
47352
+ change: averageDiameterChange
47353
+ })
47354
+ })]
47355
+ });
47356
+ };
47357
+
47358
+ const MangroveGrowth = ({
47359
+ id,
47360
+ getSummaryDetail,
47361
+ loading = false,
47362
+ t = s => s
47363
+ }) => {
47364
+ const defaultConfig = React.useMemo(() => ({
47365
+ basepath: "events/monitoring-campaign",
47366
+ url: `/summary/${id}/outcomes`,
47367
+ stop: !id
47368
+ }), [id]);
47369
+ const customGetData = React.useMemo(() => {
47370
+ if (getSummaryDetail && id) {
47371
+ return ({
47372
+ url,
47373
+ params = {}
47374
+ }) => {
47375
+ const match = url.match(/\/summary\/[^/]+\/(.+)/);
47376
+ if (match) {
47377
+ const [, type] = match;
47378
+ return getSummaryDetail(id, type, params);
47379
+ }
47380
+ throw new Error(`Invalid URL format: ${url}`);
47381
+ };
47382
+ }
47383
+ return undefined;
47384
+ }, [getSummaryDetail, id]);
47385
+ const {
47386
+ loading: outcomesLoading,
47387
+ data: outcomesData
47388
+ } = useWidgetFetch({
47389
+ config: defaultConfig,
47390
+ getData: customGetData
47391
+ });
47392
+ const {
47393
+ survivalRate,
47394
+ averageHeight,
47395
+ averageDiameter,
47396
+ vegetationHealthChart,
47397
+ seedlingsHeightChart,
47398
+ plantedSpeciesChart
47399
+ } = outcomesData || {};
47400
+ return /*#__PURE__*/jsxRuntime.jsx("section", {
47401
+ children: /*#__PURE__*/jsxRuntime.jsxs(Widget, {
47402
+ title: t("Mangrove Growth"),
47403
+ loading: loading || outcomesLoading,
47404
+ className: "with-border-header h-w-btn-header",
47405
+ children: [/*#__PURE__*/jsxRuntime.jsx(Stats, {
47406
+ survivalRate: survivalRate,
47407
+ averageHeight: averageHeight,
47408
+ averageDiameter: averageDiameter,
47409
+ t: t
47410
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47411
+ style: {
47412
+ display: "flex",
47413
+ gap: "24px"
47414
+ },
47415
+ children: [/*#__PURE__*/jsxRuntime.jsx("section", {
47416
+ style: {
47417
+ flex: 1
47418
+ },
47419
+ children: /*#__PURE__*/jsxRuntime.jsx(VegetationHealth, {
47420
+ vegetationHealthChart: vegetationHealthChart,
47421
+ t: t
47422
+ })
47423
+ }), /*#__PURE__*/jsxRuntime.jsx("section", {
47424
+ style: {
47425
+ flex: 1
47426
+ },
47427
+ children: /*#__PURE__*/jsxRuntime.jsx(SeedlingsHeight, {
47428
+ seedlingsHeightChart: seedlingsHeightChart,
47429
+ t: t
47430
+ })
47431
+ }), /*#__PURE__*/jsxRuntime.jsx("section", {
47432
+ style: {
47433
+ flex: 1
47434
+ },
47435
+ children: /*#__PURE__*/jsxRuntime.jsx(PlantedSpecies, {
47436
+ plantedSpeciesChart: plantedSpeciesChart,
47437
+ t: t
47438
+ })
47439
+ })]
47440
+ })]
47441
+ })
47442
+ });
47443
+ };
47444
+
47445
+ const MonitoringCampaignSummary = ({
47446
+ header,
47447
+ activityData,
47448
+ loading = false,
47449
+ id,
47450
+ projectId,
47451
+ t = () => {},
47452
+ getSummaryDetail,
47453
+ navigate,
47454
+ selectOptions
47455
+ }) => {
47456
+ return /*#__PURE__*/jsxRuntime.jsxs(DashboardLayout, {
47457
+ header: /*#__PURE__*/jsxRuntime.jsx(DAFHeader, {
47458
+ title: header?.title + ' Summary' || '',
47459
+ supportText: header?.supportText || '',
47460
+ onDownload: header?.onDownload,
47461
+ downloadDisabled: header?.downloadDisabled,
47462
+ actionButtons: header?.actionButtons,
47463
+ breadcrumbs: header?.breadcrumbs,
47464
+ goBackTo: header?.goBackTo,
47465
+ loading: header?.loading
47466
+ }),
47467
+ children: [/*#__PURE__*/jsxRuntime.jsx(KeyInformation, {
47468
+ id: id,
47469
+ t: t,
47470
+ getSummaryDetail: getSummaryDetail,
47471
+ loading: loading
47472
+ }), /*#__PURE__*/jsxRuntime.jsx(MonitoringScopeAndFindings, {
47473
+ id: id,
47474
+ t: t,
47475
+ getSummaryDetail: getSummaryDetail,
47476
+ loading: loading
47477
+ }), /*#__PURE__*/jsxRuntime.jsx(MangroveGrowth, {
47478
+ id: id,
47479
+ t: t,
47480
+ getSummaryDetail: getSummaryDetail,
47481
+ loading: loading
47482
+ })]
47483
+ });
47484
+ };
47485
+
46706
47486
  const IconNodesConfig = {
46707
47487
  operator: {
46708
47488
  name: "Operators",
@@ -48270,6 +49050,7 @@ exports.EventsTable = EventsTable;
48270
49050
  exports.IncidentsTable = IncidentsTable;
48271
49051
  exports.LocationsTable = LocationsTable;
48272
49052
  exports.MineSummary = MineSummary;
49053
+ exports.MonitoringCampaignSummary = MonitoringCampaignSummary;
48273
49054
  exports.OperatorSummary = OperatorSummary;
48274
49055
  exports.OperatorsTable = OperatorsTable;
48275
49056
  exports.PartnersTable = PartnersTable;