diff --git a/src/views/Dashboard/DashboardProjectCarousell.js b/src/views/Dashboard/DashboardProjectCarousell.js
new file mode 100644
index 0000000..64e9f94
--- /dev/null
+++ b/src/views/Dashboard/DashboardProjectCarousell.js
@@ -0,0 +1,977 @@
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import axios from "axios";
+import { Row, Col, Button, Input,Spin } from "antd";
+import {
+ CardDashboard,
+ CardExpenditure,
+ CardScheduleHealthPerDivision,
+} from "../../components/CardDashboard/CardDashboard";
+import L from "leaflet";
+import "../../assets/css/customscroll.css";
+import moment from "moment";
+import { renderFormatRupiah } from "../../const/CustomFunc";
+import { BASE_OSPRO, BASE_OSPRO_FE, VERSION_GANTT_SEARCH } from "../../const/ApiConst";
+import { SendOutlined } from "@ant-design/icons";
+import {
+ NotificationContainer,
+ NotificationManager,
+} from "react-notifications";
+import {
+ Carousel,
+ CarouselItem,
+ CarouselControl,
+ CarouselIndicators,
+ CarouselCaption,
+} from 'reactstrap';
+import ContentLoader from "react-content-loader";
+import {
+ BehindTaskItem,
+ Comment,
+ HealthByBudget,
+ HealthBySchedule,
+ ListLoader,
+ PopupContent,
+ ProgressActualBar,
+ ProgressPlanningBar,
+ SingleTextLoader,
+} from "./Components";
+import { Fab, Action } from "react-tiny-fab";
+import "react-tiny-fab/dist/styles.css";
+import { useHistory, useLocation, useParams } from "react-router-dom";
+
+const { TextArea } = Input;
+
+const styles = {
+ cardContainer: {
+ backgroundColor: "#F8F8F8",
+ margin: 2,
+ paddingLeft: 20,
+ paddingRight: 20,
+ paddingTop: 10,
+ },
+ cardHeaderContainer: {
+ display: "flex",
+ flexDirection: "row",
+ marginBottom: 10,
+ },
+ cardChartContainer: {
+ position: "relative",
+ height: "21vh",
+ margin: "auto",
+ paddingBottom: 10,
+ justifyContent: "center",
+ },
+ cardTitle: { color: "#444444", fontSize: 16, fontWeight: "bold" },
+ cardSubtitle: { color: "#888888", fontSize: 12 },
+};
+const center = {
+ lat: -6.2,
+ lng: 106.816666,
+};
+
+const DashboardProject = (args) => {
+ const token = localStorage.getItem("token");
+ const HEADER = {
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${token}`,
+ },
+ };
+ const { PROJECT_ID } = useParams();
+ const mapRef = useRef();
+ const [mymap, setMymap] = useState(null);
+ const [activeTabIdx, setActiveTabIdx] = useState(0);
+ const [activeTabCommentIdx, setActiveTabCommentIdx] = useState(0);
+ const [planningProgress, setPlanningProgress] = useState(0);
+ const [actualProgress, setActualProgress] = useState(0);
+ const [isReadyComments, setIsReadyComments] = useState(false);
+ const [isSendingComment, setIsSendingComment] = useState(false);
+ const [isReadyProjectDetail, setIsReadyProjectDetail] = useState(false);
+ const [isReadySCurve, setIsReadySCurve] = useState(false);
+ const [isReadyGantt, setIsReadyGantt] = useState(false);
+ const [reportDistribution, setReportDistribution] = useState([]);
+ const [isReadyOverdueActivities, setIsReadyOverdueActivities] =
+ useState(false);
+ const [healthBySchedule, setHealthBySchedule] = useState("-");
+ const [allDataMaster, sourceData] = useState([]);
+ const [isHierarchy, setIsHierarchy] = useState(false);
+ let history = useHistory();
+ // Carousell
+ const [activeIndex, setActiveIndex] = useState(0);
+ const [animating, setAnimating] = useState(false);
+ const [loading, setLoading] = useState(true);
+
+
+ useEffect(() => {
+ setLoading(true);
+ getAllData();
+ },[]);
+
+ useEffect(() => {
+ if (activeTabIdx === 1) {
+ initMap();
+ }
+ }, [activeTabIdx]);
+
+ const getAllData = async () => {
+ setIsReadyProjectDetail(false);
+ setIsReadySCurve(false)
+ setIsReadySCurve(false);
+ const URL = `${BASE_OSPRO}/api/project-carausell`;
+ const result = await axios
+ .get(URL, HEADER)
+ .then((res) => res)
+ .catch((err) => err.response);
+ if (!result) {
+ NotificationManager.error(`Could not connect to internet.`, "Failed");
+ setIsReadyProjectDetail(true);
+ setIsReadySCurve(true);
+ setLoading(false);
+ return;
+ }
+
+ if (result.status !== 200) {
+ NotificationManager.error(
+ `Get project detail failed, ${result.data.message}`,
+ "Failed"
+ );
+ setIsReadyProjectDetail(true);
+ setIsReadySCurve(true);
+ setLoading(false);
+ return;
+ } else if (result.status == 200 && result.data.data) {
+ const dataResault = result.data.data;
+ console.log("Resault Data",dataResault);
+ sourceData(dataResault);
+ setIsReadyGantt(true);
+ setIsReadyProjectDetail(true);
+ // // SCurve
+ // let statusHealthBySchedule = "on-schedule";
+ // let selisihProgress = 0;
+ // dataResault.map((item, idx) => {
+ // item.SCurve.map((itemSCurve, idx) => {
+ // let planningProgress = 0;
+ // let actualProgress = 0;
+ // let now = new Date().toISOString().slice(0, 10);
+ // let dates = itemSCurve.data?.date;
+ // let n = dates.findIndex(
+ // (element) => new Date(now) < new Date(element)
+ // );
+ // if (
+ // itemSCurve.length > 0 &&
+ // itemSCurve.data?.percentagePlan &&
+ // itemSCurve.data?.percentagePlan.length > 0
+ // ) {
+ // planningProgress = itemSCurve.data?.percentagePlan[n];
+ // if (n < 0) {
+ // planningProgress = 100;
+ // }
+ // setPlanningProgress(planningProgress);
+ // }
+ // if (
+ // itemSCurve.length > 0 &&
+ // itemSCurve.data?.percentageReal &&
+ // itemSCurve.data?.percentageReal.length > 0
+ // ) {
+ // actualProgress =
+ // itemSCurve.data?.percentageReal[
+ // itemSCurve.data?.percentageReal.length - 1
+ // ];
+ // setActualProgress(actualProgress);
+ // }
+ // });
+ // });
+
+ // selisihProgress = planningProgress - actualProgress;
+ // if (selisihProgress > 0 && selisihProgress <= 5) {
+ // statusHealthBySchedule = "warning";
+ // } else if (selisihProgress > 5) {
+ // statusHealthBySchedule = "danger";
+ // }
+ // setHealthBySchedule(statusHealthBySchedule);
+ setIsReadySCurve(true);
+ // setHierarchy
+ setIsHierarchy(true);
+ // Get Overdue
+ setIsReadyOverdueActivities(true);
+ // Distribution
+ setReportDistribution(dataResault);
+ // loading
+ setLoading(false);
+
+ }
+ };
+
+ const initMap = () => {
+ let mymap = L.map("map-area", {
+ center: center,
+ zoom: 13,
+ });
+
+ setMymap(mymap);
+ L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
+ attribution:
+ '© OpenStreetMap contributors',
+ }).addTo(mymap);
+ };
+
+ useEffect(() => {
+ if (mymap) {
+ reportDistribution.map((item, idx) => {
+ if (item.report_distribution.length > 0) {
+ item.report_distribution.map((itemDistribution, idx) => {
+ L.marker([itemDistribution.lat, itemDistribution.lon])
+ .addTo(mymap)
+ .bindPopup(PopupContent(itemDistribution));
+ })
+ }
+ });
+ }
+ }, [mymap, reportDistribution]);
+
+ useEffect(() => {
+ // Add event listener for receiving messages from the iframe
+ window.addEventListener("message", handleIframeMessage);
+
+ // Clean up the event listener on component unmount
+ return () => {
+ window.removeEventListener("message", handleIframeMessage);
+ };
+ }, []);
+
+ const handleIframeMessage = (event) => {
+ if (event.data && event.data.action === "getUrl") {
+ const childUrl = window.location.href;
+
+ // Send the URL back to the iframe
+ event.source.postMessage(
+ { action: "sendUrl", url: childUrl, isHierarchy: isHierarchy },
+ event.origin
+ );
+ }
+ };
+
+ const next = () => {
+ if (animating) return;
+ const nextIndex = activeIndex === allDataMaster.length - 1 ? 0 : activeIndex + 1;
+ setActiveIndex(nextIndex);
+ };
+
+ const previous = () => {
+ if (animating) return;
+ const nextIndex = activeIndex === 0 ? allDataMaster.length - 1 : activeIndex - 1;
+ setActiveIndex(nextIndex);
+ };
+
+ const goToIndex = (newIndex) => {
+ if (animating) return;
+ setActiveIndex(newIndex);
+ };
+
+ const slides = allDataMaster.map((item, index) => {
+ let URL_GANTT = "";
+ let version_gantt = "";
+ item.project.gantt.map((itemGantt, index) => {
+ URL_GANTT = `http://localhost:8444/adw-gantt/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${itemGantt.gantt_id}&proyek_id=${itemGantt.proyek_id}&token=${token}&ro=1`;
+ version_gantt = itemGantt.name_version
+ });
+ const today = moment();
+ const assignedList = item.assigned
+ .filter((itemAssigned) =>
+ today.isBetween(moment(itemAssigned.start_date), moment(itemAssigned.end_date))
+ )
+ .map((itemMap) => itemMap.user_id);
+ // SCurve
+ let statusHealthBySchedule = "on-schedule";
+ let selisihProgress = 0;
+ let SetplanningProgress = 0;
+ let SetactualProgress = 0;
+ let now = new Date().toISOString().slice(0, 10);
+ let dates = item.SCurve[0].data?.date;
+ let n = dates.findIndex(
+ (element) => new Date(now) < new Date(element)
+ );
+ if (
+ item.SCurve[0].length > 0 &&
+ item.SCurve[0].data?.percentagePlan &&
+ item.SCurve[0].data?.percentagePlan.length > 0
+ ) {
+ SetplanningProgress = item.SCurve[0].data?.percentagePlan[n];
+ if (n < 0) {
+ SetplanningProgress = 100;
+ }
+ }
+ if (
+ item.SCurve[0].length > 0 &&
+ item.SCurve[0].data?.percentageReal &&
+ item.SCurve[0].data?.percentageReal.length > 0
+ ) {
+ SetactualProgress =
+ item.SCurve[0].data?.percentageReal[
+ item.SCurve[0].data?.percentageReal.length - 1
+ ];
+ }
+
+ selisihProgress = SetplanningProgress - SetactualProgress;
+ if (selisihProgress > 0 && selisihProgress <= 5) {
+ statusHealthBySchedule = "warning";
+ } else if (selisihProgress > 5) {
+ statusHealthBySchedule = "danger";
+ }
+ return (
+