From ee9362e71a54a200485e4847f8b762a6f2f8e2b3 Mon Sep 17 00:00:00 2001
From: Limber Mamani <154026979+LimberHope@users.noreply.github.com>
Date: Thu, 30 Jan 2025 14:21:47 -0400
Subject: [PATCH] [TM-1605] site landing page progress goals (#858)
* [TM-1605] add component to progress and goals pie chart
* [TM-1605] add mapping to data charts
* [TM-1605] add params to chartData component
* [TM-1605] add external component to progress and goals site
* [TM-1605] update name chartData
* [TM-1605] update styles to tooltip text
* [TM-1605] add total trees restored const
* [TM-1605] add GoalsAndProgressSiteTab component to overview tab
* [TM-1605] update snapshots
* [TM-1605] update mapping param
* [TM-1605] update ProgressGoalsDoughnutChart component
* [TM-1605] change ChartData => ProgressDataCard
* [TM-1605] change terrafund => framework
---
.../components/ProgressGoalsDoughnutChart.tsx | 92 +++++++++
.../GoalProgressCard/GoalProgressCard.tsx | 25 ++-
.../GoalProgressCard.stories.storyshot | 2 +
.../components/GoalsAndProgressSiteTab.tsx | 190 ++++++++++++++++++
.../site/[uuid]/tabs/GoalsAndProgress.tsx | 89 +-------
src/pages/site/[uuid]/tabs/Overview.tsx | 34 +---
6 files changed, 302 insertions(+), 130 deletions(-)
create mode 100644 src/admin/components/ResourceTabs/MonitoredTab/components/ProgressGoalsDoughnutChart.tsx
create mode 100644 src/pages/site/[uuid]/components/GoalsAndProgressSiteTab.tsx
diff --git a/src/admin/components/ResourceTabs/MonitoredTab/components/ProgressGoalsDoughnutChart.tsx b/src/admin/components/ResourceTabs/MonitoredTab/components/ProgressGoalsDoughnutChart.tsx
new file mode 100644
index 000000000..1cab72c5b
--- /dev/null
+++ b/src/admin/components/ResourceTabs/MonitoredTab/components/ProgressGoalsDoughnutChart.tsx
@@ -0,0 +1,92 @@
+import React from "react";
+import { Cell, Label, Pie, PieChart, ResponsiveContainer } from "recharts";
+
+interface ChartDataItem {
+ name: string;
+ value: number;
+}
+
+export interface ProgressGoalsData {
+ chartData: ChartDataItem[];
+}
+
+interface ProgressGoalsDoughnutChartProps {
+ data?: ProgressGoalsData;
+}
+const percentage = (current: number, total: number) => {
+ const percentValue = Math.min((current / total) * 100, 100);
+ return percentValue.toFixed(0);
+};
+
+const ProgressGoalsDoughnutChart: React.FC = ({ data }) => {
+ const { chartData } = data as any;
+
+ const currentValue = chartData[0]?.value || 0;
+ const totalValue = chartData[1]?.value || 0;
+
+ const remainingValue = Math.max(totalValue - currentValue, 0);
+
+ const transformedData =
+ currentValue > totalValue
+ ? [{ value: 1, isProgress: true }]
+ : [
+ { value: currentValue, isProgress: true },
+ { value: remainingValue, isProgress: false }
+ ];
+ const COLORS = ["#27A9E0", "#DFF2FB"];
+
+ return (
+
+
+
+
+ {totalValue > 0 && (
+
+
+
+
+ );
+};
+
+export default ProgressGoalsDoughnutChart;
diff --git a/src/components/elements/Cards/GoalProgressCard/GoalProgressCard.tsx b/src/components/elements/Cards/GoalProgressCard/GoalProgressCard.tsx
index 73939e398..2fd4c4258 100644
--- a/src/components/elements/Cards/GoalProgressCard/GoalProgressCard.tsx
+++ b/src/components/elements/Cards/GoalProgressCard/GoalProgressCard.tsx
@@ -1,6 +1,6 @@
import classNames from "classnames";
import { DetailedHTMLProps, FC, HTMLAttributes } from "react";
-import { Else, If, Then, When } from "react-if";
+import { When } from "react-if";
import Text from "@/components/elements/Text/Text";
import { withFrameworkShow } from "@/context/framework.provider";
@@ -22,6 +22,9 @@ export interface GoalProgressCardProps extends DetailedHTMLProps = ({
@@ -38,6 +41,9 @@ const GoalProgressCard: FC = ({
labelVariant,
classNameCard,
classNameLabelValue,
+ chart,
+ hectares = false,
+ graph = true,
...rest
}) => {
const value = _val ?? 0;
@@ -53,20 +59,13 @@ const GoalProgressCard: FC = ({
{label}
-
-
-
-
-
-
-
-
-
-
+ {graph ? chart : null}
{value?.toLocaleString()}
-
- of {limit?.toLocaleString() ?? totalValue?.toLocaleString()}
+
+
+ of {limit?.toLocaleString() ?? totalValue?.toLocaleString()} {hectares ? "ha" : null}
+
{labelValue}
diff --git a/src/components/elements/Cards/GoalProgressCard/__snapshots__/GoalProgressCard.stories.storyshot b/src/components/elements/Cards/GoalProgressCard/__snapshots__/GoalProgressCard.stories.storyshot
index 60cb08de7..5c2eb30f3 100644
--- a/src/components/elements/Cards/GoalProgressCard/__snapshots__/GoalProgressCard.stories.storyshot
+++ b/src/components/elements/Cards/GoalProgressCard/__snapshots__/GoalProgressCard.stories.storyshot
@@ -69,6 +69,7 @@ exports[`Storyshots Components/Elements/Cards/GoalProgressCard/Card Progress And
>
of
732
+
of
150
+
{
+ return (
+
}
+ />
+ );
+};
+
+const GoalsAndProgressSiteTab = ({ site }: GoalsAndProgressSiteTabProps) => {
+ const t = useT();
+ const totaTreesRestoredCount = site?.trees_planted_count + site?.regenerated_trees_count + site?.seeds_planted_count;
+ const chartDataHectares = {
+ chartData: [
+ { name: t("HECTARES RESTORED"), value: site.total_hectares_restored_sum },
+ site.framework_key !== Framework.PPC
+ ? {
+ name: t("TOTAL HECTARES RESTORED"),
+ value: parseFloat(site.hectares_to_restore_goal)
+ }
+ : {}
+ ],
+ cardValues: {
+ label: t("HECTARES RESTORED"),
+ value: site.total_hectares_restored_sum,
+ totalName: t("TOTAL HECTARES RESTORED"),
+ totalValue: parseFloat(site.hectares_to_restore_goal)
+ }
+ };
+ const chartDataTreesRestored = {
+ chartData: [{ name: t("TREES RESTORED"), value: totaTreesRestoredCount }],
+ cardValues: {
+ label: t("TREES RESTORED"),
+ value: totaTreesRestoredCount
+ }
+ };
+ const chartDataWorkdays = {
+ chartData: [
+ {
+ name: t("WORKDAYS CREATED"),
+ value: site.framework_key == Framework.PPC ? site.combined_workday_count : site.workday_count
+ }
+ ],
+ cardValues: {
+ label: t("WORKDAYS CREATED"),
+ value: site.framework_key == Framework.PPC ? site.combined_workday_count : site.workday_count
+ }
+ };
+ const chartDataSaplings = {
+ chartData: [{ name: t("SAPLINGS RESTORED"), value: totaTreesRestoredCount }],
+ cardValues: {
+ label: t("SAPLINGS RESTORED"),
+ value: totaTreesRestoredCount
+ }
+ };
+
+ const chartsDataMapping: ChartsData = {
+ terrafund: [
+
,
+
+ ],
+ ppc: [
+
,
+
,
+
+ ],
+ hbf: [
+
,
+
,
+
+ ]
+ };
+ const framework = ALL_TF.includes(site.framework_key as Framework) ? "terrafund" : site.framework_key;
+ return (
+
+ {chartsDataMapping[framework as keyof ChartsData]?.map((chart, index) => (
+ {chart}
+ ))}
+
+
+ );
+};
+export default GoalsAndProgressSiteTab;
diff --git a/src/pages/site/[uuid]/tabs/GoalsAndProgress.tsx b/src/pages/site/[uuid]/tabs/GoalsAndProgress.tsx
index 6c4aa4bf2..7aa4cb5de 100644
--- a/src/pages/site/[uuid]/tabs/GoalsAndProgress.tsx
+++ b/src/pages/site/[uuid]/tabs/GoalsAndProgress.tsx
@@ -1,4 +1,5 @@
import { useT } from "@transifex/react";
+import React from "react";
import { Else, If, Then, When } from "react-if";
import GoalProgressCard from "@/components/elements/Cards/GoalProgressCard/GoalProgressCard";
@@ -11,6 +12,8 @@ import TreeSpeciesTablePD from "@/components/extensive/Tables/TreeSpeciesTablePD
import { Framework } from "@/context/framework.provider";
import { TextVariants } from "@/types/common";
+import GoalsAndProgressSiteTab from "../components/GoalsAndProgressSiteTab";
+
interface GoalsAndProgressTabProps {
site: any;
}
@@ -109,91 +112,7 @@ const GoalsAndProgressTab = ({ site }: GoalsAndProgressTabProps) => {
-
-
-
-
-
-
-
-
-
+
diff --git a/src/pages/site/[uuid]/tabs/Overview.tsx b/src/pages/site/[uuid]/tabs/Overview.tsx
index 9a9b16eb5..5b0824b5c 100644
--- a/src/pages/site/[uuid]/tabs/Overview.tsx
+++ b/src/pages/site/[uuid]/tabs/Overview.tsx
@@ -7,7 +7,6 @@ import ModalIdentified from "@/admin/components/extensive/Modal/ModalIdentified"
import { AuditLogButtonStates } from "@/admin/components/ResourceTabs/AuditLogTab/constants/enum";
import AddDataButton from "@/admin/components/ResourceTabs/PolygonReviewTab/components/AddDataButton";
import Button from "@/components/elements/Button/Button";
-import GoalProgressCard from "@/components/elements/Cards/GoalProgressCard/GoalProgressCard";
import ItemMonitoringCards from "@/components/elements/Cards/ItemMonitoringCard/ItemMonitoringCards";
import Dropdown from "@/components/elements/Inputs/Dropdown/Dropdown";
import { VARIANT_FILE_INPUT_MODAL_ADD_IMAGES } from "@/components/elements/Inputs/FileInput/FileInputVariants";
@@ -23,7 +22,6 @@ import PageBody from "@/components/extensive/PageElements/Body/PageBody";
import PageCard from "@/components/extensive/PageElements/Card/PageCard";
import PageColumn from "@/components/extensive/PageElements/Column/PageColumn";
import PageRow from "@/components/extensive/PageElements/Row/PageRow";
-import { Framework } from "@/context/framework.provider";
import { useLoading } from "@/context/loaderAdmin.provider";
import { useMapAreaContext } from "@/context/mapArea.provider";
import { useModalContext } from "@/context/modal.provider";
@@ -43,6 +41,7 @@ import { FileType, UploadedFile } from "@/types/common";
import { getErrorMessageFromPayload } from "@/utils/errors";
import Log from "@/utils/log";
+import GoalsAndProgressSiteTab from "../components/GoalsAndProgressSiteTab";
import SiteArea from "../components/SiteArea";
interface SiteOverviewTabProps {
@@ -409,36 +408,7 @@ const SiteOverviewTab = ({ site, refetch: refetchEntity }: SiteOverviewTabProps)
}
>
-
+