diff --git a/src/admin/components/Actions/ListActionsCreate.tsx b/src/admin/components/Actions/ListActionsCreate.tsx
index 1b7763c24..5d0d8afc2 100644
--- a/src/admin/components/Actions/ListActionsCreate.tsx
+++ b/src/admin/components/Actions/ListActionsCreate.tsx
@@ -6,11 +6,11 @@ interface ListActionsCreateProps {
onExport?: () => void;
}
-const ListActionsCreate = (props: ListActionsCreateProps) => (
+const ListActionsCreate = ({ onExport }: ListActionsCreateProps) => (
-
- } onClick={props.onExport} />
+
+ } onClick={onExport} />
);
diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/components/ComentarySection/ComentarySection.tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/components/ComentarySection/ComentarySection.tsx
new file mode 100644
index 000000000..82971c190
--- /dev/null
+++ b/src/admin/components/ResourceTabs/PolygonReviewTab/components/ComentarySection/ComentarySection.tsx
@@ -0,0 +1,69 @@
+import { When } from "react-if";
+
+import Commentary from "@/components/elements/Commentary/Commentary";
+import CommentaryBox from "@/components/elements/CommentaryBox/CommentaryBox";
+import Text from "@/components/elements/Text/Text";
+import Loader from "@/components/generic/Loading/Loader";
+import { useGetAuthMe } from "@/generated/apiComponents";
+
+const ComentarySection = ({
+ auditLogData,
+ refresh,
+ record,
+ entity,
+ viewCommentsList = true,
+ attachmentRefetch
+}: {
+ auditLogData?: any;
+ refresh?: any;
+ record?: any;
+ entity?: "Project" | "SitePolygon" | "Site";
+ viewCommentsList?: boolean;
+ attachmentRefetch?: any;
+}) => {
+ const { data: authMe } = useGetAuthMe({}) as {
+ data: {
+ data: any;
+ first_name: string;
+ last_name: string;
+ };
+ };
+
+ return (
+
+
Send Comment
+
+
+
+ {auditLogData ? (
+ auditLogData.length > 0 ? (
+ auditLogData
+ .filter((item: any) => item.type === "comment")
+ .map((item: any) => (
+
+ ))
+ ) : (
+ <>>
+ )
+ ) : (
+
+ )}
+
+
+
+ );
+};
+
+export default ComentarySection;
diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/PolygonValidation.tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/PolygonValidation.tsx
new file mode 100644
index 000000000..6423f11be
--- /dev/null
+++ b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/PolygonValidation.tsx
@@ -0,0 +1,91 @@
+import React, { useEffect, useRef, useState } from "react";
+import { Else, If, Then } from "react-if";
+
+import Button from "@/components/elements/Button/Button";
+import Text from "@/components/elements/Text/Text";
+import Icon from "@/components/extensive/Icon/Icon";
+import { IconNames } from "@/components/extensive/Icon/Icon";
+
+export interface ICriteriaCheckItemProps {
+ id: string;
+ status: boolean;
+ label: string;
+ date?: string;
+}
+
+export interface ICriteriaCheckProps {
+ menu: ICriteriaCheckItemProps[];
+ clickedValidation: (value: boolean) => void;
+ status: boolean;
+}
+const PolygonValidation = (props: ICriteriaCheckProps) => {
+ const { clickedValidation, status, menu } = props;
+ const [failedValidationCounter, setFailedValidationCounter] = useState(0);
+ const [lastValidationDate, setLastValidationDate] = useState(new Date("1970-01-01"));
+ const containerRef = useRef(null);
+
+ const formattedDate = (dateObject: Date) => {
+ const localDate = new Date(dateObject.getTime() - dateObject.getTimezoneOffset() * 60000);
+ return `${localDate.toLocaleTimeString("en-US", {
+ hour: "2-digit",
+ minute: "2-digit"
+ })} on ${localDate.toLocaleDateString("en-US", {
+ month: "short",
+ day: "2-digit",
+ year: "numeric"
+ })}`;
+ };
+
+ useEffect(() => {
+ if (menu) {
+ const lastValidationDate = menu.reduce((latestDate, record) => {
+ const currentDate = record.date ? new Date(record.date) : null;
+ return currentDate && currentDate > latestDate ? currentDate : latestDate;
+ }, new Date("1970-01-01"));
+ setLastValidationDate(lastValidationDate);
+
+ const failedValidationCounter = menu.reduce((count, record) => {
+ return record.status === false ? count + 1 : count;
+ }, 0);
+ setFailedValidationCounter(failedValidationCounter);
+ }
+ }, [menu]);
+
+ return (
+
+
+
+
+
+
+ {`${failedValidationCounter} out of ${menu.length}`}
+
+
+ criteria are not met
+
+
+
+ Last check at {formattedDate(lastValidationDate)}
+
+
+ {menu.map(item => (
+
+
+ {item.label}
+
+ ))}
+
+
+
+
+ No criteria checked yet
+
+
+
+
+ );
+};
+
+export default PolygonValidation;
diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/VersionHistory.tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/VersionHistory.tsx
new file mode 100644
index 000000000..2ce4d833b
--- /dev/null
+++ b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/VersionHistory.tsx
@@ -0,0 +1,40 @@
+import { useT } from "@transifex/react";
+
+import Button from "@/components/elements/Button/Button";
+import Dropdown from "@/components/elements/Inputs/Dropdown/Dropdown";
+
+const dropdownOptions = [
+ {
+ title: "1213023412",
+ value: 1
+ },
+ {
+ title: "1213023414",
+ value: 2
+ }
+];
+const VersionHistory = () => {
+ const t = useT();
+ return (
+
+
{}}
+ />
+
+
+
+
+
+ );
+};
+
+export default VersionHistory;
diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonStatus/StatusDisplay .tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonStatus/StatusDisplay .tsx
new file mode 100644
index 000000000..78bd72d6b
--- /dev/null
+++ b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonStatus/StatusDisplay .tsx
@@ -0,0 +1,248 @@
+import { useState } from "react";
+import { useShowContext } from "react-admin";
+
+import Button from "@/components/elements/Button/Button";
+import Notification from "@/components/elements/Notification/Notification";
+import Text from "@/components/elements/Text/Text";
+import ModalConfirm from "@/components/extensive/Modal/ModalConfirm";
+import { useModalContext } from "@/context/modal.provider";
+
+const menuPolygonOptions = [
+ {
+ title: "Submitted",
+ status: "submitted",
+ value: 1
+ },
+ {
+ title: "Needs More Information",
+ status: "needs-more-information",
+ value: 2
+ },
+ {
+ title: "Approved",
+ status: "approved",
+ value: 3
+ }
+];
+const menuSiteOptions = [
+ {
+ title: "Draft",
+ status: "draft",
+ value: 1
+ },
+ {
+ title: "Awaiting Approval",
+ status: "awaiting-approval",
+ value: 2
+ },
+ {
+ title: "Needs More Information",
+ status: "needs-more-information",
+ value: 3
+ },
+ {
+ title: "Planting in Progress",
+ status: "planting-in-progress",
+ value: 4
+ },
+ {
+ title: "Approved",
+ status: "approved",
+ value: 5
+ }
+];
+const menuProjectOptions = [
+ {
+ title: "Draft",
+ status: "draft",
+ value: 1
+ },
+ {
+ title: "Awaiting Approval",
+ status: "awaiting-approval",
+ value: 2
+ },
+ {
+ title: "Needs More Information",
+ status: "needs-more-information",
+ value: 3
+ },
+ {
+ title: "Approved",
+ status: "approved",
+ value: 4
+ }
+];
+
+export interface StatusProps {
+ titleStatus: "Site" | "Project" | "Polygon";
+ mutate?: any;
+ record?: any;
+ refresh?: any;
+ name: any;
+ refetchPolygon?: any;
+ setSelectedPolygon?: any;
+}
+
+const menuOptionsMap = {
+ Polygon: menuPolygonOptions,
+ Site: menuSiteOptions,
+ Project: menuProjectOptions
+};
+
+const DescriptionStatusMap = {
+ Polygon: "Are you sure you want to change the polygon status to",
+ Site: "Are you sure you want to change the site status to",
+ Project: "Are you sure you want to change the project status to"
+};
+
+const DescriptionRequestMap = {
+ Polygon: "Provide an explanation for your change request for the polygon",
+ Site: "Provide an explanation for your change request for the site",
+ Project: "Provide an explanation for your change request for the project"
+};
+
+const StatusDisplay = ({ titleStatus = "Polygon", mutate, refresh, name, record, setSelectedPolygon }: StatusProps) => {
+ const { refetch: reloadEntity } = useShowContext();
+ const [notificationStatus, setNotificationStatus] = useState<{
+ open: boolean;
+ message: string;
+ type: "success" | "error" | "warning";
+ title: string;
+ }>({
+ open: false,
+ message: "",
+ type: "success",
+ title: "Success!"
+ });
+
+ const { openModal, closeModal } = useModalContext();
+ const contentStatus = (
+
+ {DescriptionStatusMap[titleStatus]} {name}?
+
+ );
+ const contentRequest = (
+
+ {DescriptionRequestMap[titleStatus]} {name}?
+
+ );
+
+ const openFormModalHandlerStatus = () => {
+ openModal(
+ {
+ const option = menuOptionsMap[titleStatus].find(option => option.value === opt[0]);
+ try {
+ const response = await mutate({
+ pathParams: { uuid: record?.uuid },
+ body: {
+ status: option?.status,
+ comment: text,
+ type: "status"
+ }
+ });
+ if (response.poly_id) {
+ setSelectedPolygon(response?.poly_id);
+ }
+ setNotificationStatus({
+ open: true,
+ message: "Your Status Update was just saved!",
+ type: "success",
+ title: "Success!"
+ });
+ setTimeout(() => {
+ setNotificationStatus({
+ open: false,
+ message: "",
+ type: "success",
+ title: "Success!"
+ });
+ }, 3000);
+ } catch (e) {
+ alert("The request encountered an issue, or the comment exceeds 255 characters.");
+ console.error(e);
+ } finally {
+ refresh();
+ reloadEntity();
+ closeModal();
+ }
+ }}
+ />
+ );
+ };
+
+ const openFormModalHandlerRequest = () => {
+ openModal(
+ {
+ const option = menuOptionsMap[titleStatus].find(option => option.value === opt[0]);
+ try {
+ await mutate({
+ pathParams: { uuid: record?.uuid },
+ body: {
+ status: option?.status,
+ comment: text,
+ type: "change-request",
+ is_active: true,
+ request_removed: false
+ }
+ });
+ setNotificationStatus({
+ open: true,
+ message: "Your Change Request was just added!",
+ type: "success",
+ title: "Success!"
+ });
+ setTimeout(() => {
+ setNotificationStatus({
+ open: false,
+ message: "",
+ type: "success",
+ title: "Success!"
+ });
+ }, 3000);
+ } catch (e) {
+ alert("The request encountered an issue, or the comment exceeds 255 characters.");
+ console.error(e);
+ } finally {
+ refresh();
+ reloadEntity();
+ closeModal();
+ }
+ }}
+ />
+ );
+ };
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default StatusDisplay;
diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/components/SitePolygonStatus/SitePolygonStatus.tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/components/SitePolygonStatus/SitePolygonStatus.tsx
new file mode 100644
index 000000000..69c60f858
--- /dev/null
+++ b/src/admin/components/ResourceTabs/PolygonReviewTab/components/SitePolygonStatus/SitePolygonStatus.tsx
@@ -0,0 +1,18 @@
+import StepProgressbar from "@/components/elements/ProgressBar/StepProgressbar/StepProgressbar";
+
+const polygonStatusLabels = [
+ { id: "1", label: "Draft" },
+ { id: "2", label: "Awaiting approval" },
+ { id: "3", label: "Needs more information" },
+ { id: "4", label: "Planting in progress" },
+ { id: "5", label: "Approved" }
+];
+
+const SitePolygonStatus = ({ statusLabel }: { statusLabel: string }) => {
+ let status = statusLabel === "Unkown" ? "Planting in progress" : statusLabel;
+ const statusIndex = polygonStatusLabels.findIndex(({ label }) => label === status);
+ const progress = statusIndex === -1 ? 0 : statusIndex * 25;
+ return ;
+};
+
+export default SitePolygonStatus;
diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/components/StatusLeyend.tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/components/StatusLeyend.tsx
new file mode 100644
index 000000000..8d257677d
--- /dev/null
+++ b/src/admin/components/ResourceTabs/PolygonReviewTab/components/StatusLeyend.tsx
@@ -0,0 +1,27 @@
+import Text from "@/components/elements/Text/Text";
+
+const StatusLeyend = () => {
+ return (
+
+
+ Status Legend
+
+
+
+ Status Legend
+
+
+ Submitted
+
+
+ Approved
+
+
+ Needs More Info
+
+
+
+ );
+};
+
+export default StatusLeyend;