diff --git a/src/views/Dashboard/Components/index.js b/src/views/Dashboard/Components/index.js new file mode 100644 index 0000000..894e7d8 --- /dev/null +++ b/src/views/Dashboard/Components/index.js @@ -0,0 +1,166 @@ +import React from 'react' +import moment from "moment" +import ContentLoader from "react-content-loader" + +export const SingleTextLoader = ({width, height}) => ( + + + +) + +export const ListLoader = () => ( + //
Loading overdue activities...
+
+ +
+ +
+ +
+ +
+ +
+) + +export const Comment = ({name, comment, created_at}) => ( +
+
{name}
+
{created_at ? moment(created_at).format('D MMMM YYYY HH:mm:ss') : '-'}
+
{comment}
+
+) + +export const BehindTaskItem = ({name, message}) => ( +
+
{name}
+
{message}
+ {/*
{division}
*/} +
+) + +export const ProgressPlanningBar = ({progress}) => { + if (progress) { + if (progress > 30) { + return ( +
+
Planning : {progress}%
+
+ ) + } + else { + return ( +
+
+ Planning : {progress}% +
+ ) + } + } + else { + return null; + } +} + +export const ProgressActualBar = ({progress}) => { + if (progress) { + if (progress > 30) { + return ( +
+
Actual : {progress}%
+
+ ) + } + else { + return ( +
+
+ Actual : {progress}% +
+ ) + } + } + else { + return null; + } +} + +export const HealthByBudget = ({status}) => { + let bgColor = '#52AC0B'; // on-budget + if (status && status !== '-') { + if (status === 'warning') bgColor = '#ED7014'; + else if (status === 'danger') bgColor = '#D0312D'; + } + return ( +
+
{status.toUpperCase()}
+
+ ) +} + +export const HealthBySchedule = ({status}) => { + // let bgColor = '#E80053'; // pink + let bgColor = '#52AC0B'; // green + if (status && status !== '-') { + if (status === 'warning') bgColor = '#ED7014'; + else if (status === 'danger') bgColor = '#D0312D'; + } + return ( +
+
{status.toUpperCase()}
+
+ ) +} + +export const PopupContent = (item) => { + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; +} \ No newline at end of file diff --git a/src/views/Dashboard/DashboardCustomer.js b/src/views/Dashboard/DashboardCustomer.js index 5b8a3e5..ce3045e 100644 --- a/src/views/Dashboard/DashboardCustomer.js +++ b/src/views/Dashboard/DashboardCustomer.js @@ -9,6 +9,7 @@ import moment from 'moment'; import { BASE_OSPRO } from '../../const/ApiConst'; import { SendOutlined } from '@ant-design/icons'; import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { BehindTaskItem, Comment, HealthBySchedule, ListLoader, PopupContent, ProgressActualBar, ProgressPlanningBar, SingleTextLoader } from './Components'; const { TextArea } = Input; const styles = { @@ -34,31 +35,42 @@ const DashboardCustomer = () => { } const { PROJECT_ID, GANTT_ID } = useParams(); // const URL_GANTT = `http://103.73.125.81:8446/index.html?base_url=http://103.73.125.81:8444/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`; - const URL_GANTT = `https://adw-gantt.ospro.id/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`; + // const URL_GANTT = `https://adw-gantt.ospro.id/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`; // const URL_GANTT = ''; + const URL_GANTT = `http://192.168.1.104:8446/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`; const mapRef = useRef() - const [projectName, setProjectName] = useState("Project Tower ABC"); - const [customerName, setCustomerName] = useState("Jaya Gedung Group"); - const [plannedStart, setPlannedStart] = useState("2019-03-04") - const [plannedFinish, setPlannedFinish] = useState("2020-05-28") - const [actualStart, setActualStart] = useState("2019-03-04") - const [actualFinish, setActualFinish] = useState("2020-05-28") - const [estimatedFinish, setEstimatedFinish] = useState("2020-05-28") + const [projectName, setProjectName] = useState(""); + const [projectManagerName, setProjectManagerName] = useState(''); + const [customerName, setCustomerName] = useState(""); + const [plannedStart, setPlannedStart] = useState(null) + const [plannedFinish, setPlannedFinish] = useState(null) + const [actualStart, setActualStart] = useState(null) + const [actualFinish, setActualFinish] = useState(null) + const [estimatedFinish, setEstimatedFinish] = useState(null) const [mymap, setMymap] = useState(null); const [activeTabIdx, setActiveTabIdx] = useState(0); const [activeTabCommentIdx, setActiveTabCommentIdx] = useState(0); - const [planningProgress, setPlanningProgress] = useState(79); - const [actualProgress, setActualProgress] = useState(50); + const [planningProgress, setPlanningProgress] = useState(0); + const [actualProgress, setActualProgress] = useState(0); const [comment, setComment] = useState(''); const [comments, setComments] = useState([]); const [isReadyComments, setIsReadyComments] = useState(false); const [isSendingComment, setIsSendingComment] = useState(false); - const [behindTasks, setBehindTasks] = useState([]); + const [isReadyProjectDetail, setIsReadyProjectDetail] = useState(false); + const [isReadySCurve, setIsReadySCurve] = useState(false); + const [isReadyOverdueActivities, setIsReadyOverdueActivities] = useState(false); + const [isReadyReportDistribution, setIsReadyReportDistribution] = useState(false); + const [overdueActivities, setOverdueActivities] = useState([]); + const [healthBySchedule, setHealthBySchedule] = useState('-'); + const [healthByBudget, setHealthByBudget] = useState('-'); + const [reportDistribution, setReportDistribution] = useState([]); useEffect(() => { - // console.log('URL_GANTT', URL_GANTT); + getProjectDetail(); + getSCurve() + getOverdueActivities(); + getReportDistribution() getComments(); - getBehindTasks(); return () => { console.log('unmount RenderMap'); } @@ -70,6 +82,138 @@ const DashboardCustomer = () => { } }, [activeTabIdx]); + const getProjectDetail = async () => { + setIsReadyProjectDetail(false); + const URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}`; + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + console.log('getProjectDetail', result); + if (!result) { + NotificationManager.error(`Could not connect to internet.`, "Failed"); + setIsReadyProjectDetail(true); + return; + } + + if (result.status !== 200) { + NotificationManager.error(`Get project detail failed, ${result.data.message}`, "Failed"); + setIsReadyProjectDetail(true); + return; + } + else if (result.status == 200 && result.data.data) { + console.log(result.data.data); + // setComments(result.data.data); + setProjectName(result.data.data.nama ? result.data.data.nama : '-'); + setProjectManagerName(result.data.data.projectManager ? result.data.data.projectManager : '-'); + setCustomerName(result.data.data.company ? result.data.data.company : '-') + setPlannedStart(result.data.data?.mulai_proyek ? result.data.data.mulai_proyek : null) + setPlannedFinish(result.data.data?.akhir_proyek ? result.data.data.akhir_proyek : null) + setActualStart(result.data.data.header?.start_date ? result.data.data.header.start_date : null) + setEstimatedFinish(result.data.data.header?.end_date ? result.data.data.header.end_date : null) + setIsReadyProjectDetail(true); + } + } + + const getSCurve = async () => { + setIsReadySCurve(false); + const URL = `${BASE_OSPRO}/api/project/get-s-curve`; + const payload = { + "project_id": PROJECT_ID.toString(), + "period": "week", + "end_date": moment(new Date()).format('YYYY-MM-DD') + } + const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response) + console.log('getSCurve', result); + if (!result) { + NotificationManager.error(`Could not connect to internet.`, "Failed"); + setIsReadySCurve(true); + return; + } + + if (result.status !== 200) { + NotificationManager.error(`Get S Curve failed, ${result.data.message}`, "Failed"); + setIsReadySCurve(true); + return; + } + else if (result.status == 200 && result.data.data) { + let selisihProgress = 0; + let planningProgress = 0; + let actualProgress = 0; + let statusHealthBySchedule = 'on-schedule'; + if (result.data.data.length > 0 && result.data.data[0].data?.percentagePlan && result.data.data[0].data?.percentagePlan.length > 0) { + let planningProgress = result.data.data[0].data?.percentagePlan[result.data.data[0].data?.percentagePlan.length-1]; + setPlanningProgress(planningProgress); + } + if (result.data.data.length > 0 && result.data.data[0].data?.percentageReal && result.data.data[0].data?.percentageReal.length > 0) { + let actualProgress = result.data.data[0].data?.percentageReal[result.data.data[0].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); + } + } + + const getOverdueActivities = async () => { + setIsReadyOverdueActivities(false); + const URL = `${BASE_OSPRO}/api/project/get-overdue-activities`; + const payload = { + "id": PROJECT_ID.toString(), + "till_date": moment(new Date()).format('YYYY-MM-DD') + } + const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response) + console.log('getOverdueActivities', result); + if (!result) { + NotificationManager.error(`Could not connect to internet.`, "Failed"); + setIsReadyOverdueActivities(true); + return; + } + + if (result.status !== 200) { + NotificationManager.error(`Get Overdue Activities failed, ${result.data.message}`, "Failed"); + setIsReadyOverdueActivities(true); + return; + } + else if (result.status == 200 && result.data.data) { + if (result.data.data.overdueActivities) { + setOverdueActivities(result.data.data.overdueActivities) + } + setHealthByBudget(result.data.data.budget_health) + setIsReadyOverdueActivities(true); + } + } + + const getReportDistribution = async () => { + setIsReadyReportDistribution(false); + const URL = `${BASE_OSPRO}/api/project/get-report-distribution`; + const payload = { + "project_id": PROJECT_ID, + "start_date": moment().startOf('month').subtract(1, 'years').format('YYYY-MM-DD'), + "end_date": moment(new Date()).subtract(1, 'years').format('YYYY-MM-DD') + } + const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response) + console.log('getReportDistribution', result); + if (!result) { + NotificationManager.error(`Could not connect to internet.`, "Failed"); + setIsReadyReportDistribution(true); + return; + } + + if (result.status !== 200) { + NotificationManager.error(`Get report distribution failed, ${result.data.message}`, "Failed"); + setIsReadyReportDistribution(true); + return; + } + else if (result.status == 200 && result.data.data) { + setReportDistribution(result.data.data); + setIsReadyReportDistribution(true); + } + } + const getComments = async () => { setIsReadyComments(false); const URL = `${BASE_OSPRO}/api/project-comment/search`; @@ -108,19 +252,18 @@ const DashboardCustomer = () => { } if (result.status !== 200) { - NotificationManager.error(`Post comment failed, ${result.data.message}`, "Failed"); + NotificationManager.error(`Get comments failed, ${result.data.message}`, "Failed"); setIsReadyComments(true); return; } else if (result.status == 200 && result.data.data) { - console.log(result.data.data); setComments(result.data.data); setIsReadyComments(true); } } const handleSendComment = async () => { - console.log('handleSendComment', comment); + // console.log('handleSendComment', comment); setIsSendingComment(true); if (comment === '') { NotificationManager.error("Please leave a comment before you send it.", "Failed"); @@ -159,34 +302,25 @@ const DashboardCustomer = () => { setIsSendingComment(false); } - const getBehindTasks = () => { - setBehindTasks([ - { - id: 1, - name: "Tom", - message: "Overdue by 5 days", - division: "IT" - }, - { - id: 1, - name: "Jerry", - message: "Overdue by 3 days", - division: "Finance" - } - ]) - } - 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) { + if (reportDistribution.length > 0) { + reportDistribution.map((item, idx) => { + L.marker([item.lat, item.lon]).addTo(mymap).bindPopup(PopupContent(item)) + }); + } + } + }, [mymap, reportDistribution]) + const RenderGantt = useMemo(() => ( ), [activeTabIdx]) - const Comment = ({name, comment, created_at}) => ( -
-
{name}
-
{created_at ? moment(created_at).format('D MMMM YYYY HH:mm:ss') : '-'}
-
{comment}
-
- ) - - const BehindTaskItem = ({name, message, division}) => ( -
-
{name}
-
{message}
-
{division}
-
- ) - const RenderComments = useMemo(() => { return ( <> @@ -227,7 +345,7 @@ const DashboardCustomer = () => {
- {!isReadyComments &&
Loading comments...
} + {!isReadyComments && } {isReadyComments && comments && comments.length < 1 &&
No comments found.
} {comments && comments.length > 0 && comments.map((item, idx) => @@ -240,13 +358,24 @@ const DashboardCustomer = () => { const RenderBehindTasks = useMemo(() => { return (
- {behindTasks && behindTasks.length < 1 &&
No behind task found.
} - {behindTasks && behindTasks.length > 0 && behindTasks.map((item, idx) => - - )} + {!isReadyOverdueActivities && } + {isReadyOverdueActivities && overdueActivities && overdueActivities.length < 1 &&
No behind task found.
} + {isReadyOverdueActivities && overdueActivities && overdueActivities.length > 0 && overdueActivities.map((item, idx) => { + let end_date = null; + let today = null; + let diffDays = 0; + let message = ''; + if (item.end_date && item.end_date !== null) { + end_date = moment(item.end_date); + today = moment(new Date()); + diffDays = today.diff(end_date, 'days'); + message = `Overdue by ${diffDays} days`; + } + return + })}
) - }, [behindTasks]) + }, [overdueActivities, isReadyOverdueActivities]) return (
@@ -270,7 +399,7 @@ const DashboardCustomer = () => {
Project
-
{projectName}
+
{isReadyProjectDetail ? projectName : }
@@ -284,7 +413,7 @@ const DashboardCustomer = () => {
Customer
-
{customerName}
+
{isReadyProjectDetail ? customerName : }
@@ -302,18 +431,36 @@ const DashboardCustomer = () => {
-
Planned Start - {plannedStart ? moment(plannedStart).format('D MMMM YYYY') : '-'} - Planned Finish - {plannedFinish ? moment(plannedFinish).format('D MMMM YYYY') : '-'} - Actual Finish - {actualFinish ? moment(actualFinish).format('D MMMM YYYY') : '-'} + Planned Start + + {isReadyProjectDetail ? + plannedStart ? moment(plannedStart).format('D MMMM YYYY') : '-' + : + } + + Planned Finish + + {isReadyProjectDetail ? + plannedFinish ? moment(plannedFinish).format('D MMMM YYYY') : '-' + : + } + - Actual Start - {actualStart ? moment(actualStart).format('D MMMM YYYY') : '-'} - Estimated Finish - {estimatedFinish ? moment(estimatedFinish).format('D MMMM YYYY') : '-'} + Actual Start + + {isReadyProjectDetail ? + actualStart ? moment(actualStart).format('D MMMM YYYY') : '-' + : + } + + Estimated Finish + + {isReadyProjectDetail ? + estimatedFinish ? moment(estimatedFinish).format('D MMMM YYYY') : '-' + : + } + @@ -347,12 +494,17 @@ const DashboardCustomer = () => {
Progress
-
-
Planning : {planningProgress}%
-
-
-
{actualProgress && actualProgress < 50 ? `${actualProgress}%` : `Actual : ${actualProgress}%` }
-
+ {isReadySCurve ? + + : + + } +
+ {isReadySCurve ? + + : + + }
@@ -360,9 +512,7 @@ const DashboardCustomer = () => {
Health By Schedule
-
-
Behind Schedule
-
+ {isReadySCurve ? : }
diff --git a/src/views/Dashboard/DashboardProject.js b/src/views/Dashboard/DashboardProject.js index 388ca3e..d6130a6 100644 --- a/src/views/Dashboard/DashboardProject.js +++ b/src/views/Dashboard/DashboardProject.js @@ -11,6 +11,7 @@ import { BASE_OSPRO } from '../../const/ApiConst'; import { SendOutlined } from '@ant-design/icons'; import { NotificationContainer, NotificationManager } from 'react-notifications'; import ContentLoader from 'react-content-loader'; +import { BehindTaskItem, Comment, HealthByBudget, HealthBySchedule, ListLoader, PopupContent, ProgressActualBar, ProgressPlanningBar, SingleTextLoader } from './Components'; const { TextArea } = Input; const styles = { @@ -37,7 +38,8 @@ const DashboardProject = () => { const { PROJECT_ID, GANTT_ID } = useParams(); // const URL_GANTT = `http://103.73.125.81:8446/index.html?base_url=http://103.73.125.81:8444/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`; // const URL_GANTT = `https://adw-gantt.ospro.id/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`; - const URL_GANTT = ''; + // const URL_GANTT = ''; + const URL_GANTT = `http://192.168.1.104:8446/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`; const mapRef = useRef() const [projectName, setProjectName] = useState(""); const [projectManagerName, setProjectManagerName] = useState(""); @@ -50,8 +52,8 @@ const DashboardProject = () => { const [mymap, setMymap] = useState(null); const [activeTabIdx, setActiveTabIdx] = useState(0); const [activeTabCommentIdx, setActiveTabCommentIdx] = useState(0); - const [planningProgress, setPlanningProgress] = useState(79); - const [actualProgress, setActualProgress] = useState(43); + const [planningProgress, setPlanningProgress] = useState(0); + const [actualProgress, setActualProgress] = useState(0); const [currentBudget, setCurrentBudget] = useState(null) const [addCostToComplete, setAddCostToComplete] = useState(null) const [actualToDate, setActualToDate] = useState(null) @@ -66,21 +68,23 @@ const DashboardProject = () => { const [comments, setComments] = useState([]); const [isReadyComments, setIsReadyComments] = useState(false); const [isSendingComment, setIsSendingComment] = useState(false); - const [isReadyProjectDetail, setIsReadyProjectDetail] = useState(false); const [isReadySCurve, setIsReadySCurve] = useState(false); const [isReadyOverdueActivities, setIsReadyOverdueActivities] = useState(false); + const [isReadyIntegrationInvoice, setIsReadyIntegrationInvoice] = useState(false); + const [isReadyReportDistribution, setIsReadyReportDistribution] = useState(false); const [overdueActivities, setOverdueActivities] = useState([]); - const [healthBySchedule, setHealthBySchedule] = useState('-') const [healthByBudget, setHealthByBudget] = useState('-') + const [reportDistribution, setReportDistribution] = useState([]); + useEffect(() => { - // console.log('URL_GANTT', URL_GANTT); - getProjectDetail(); - getSCurve(); - getOverdueActivities(); - getComments(); + getProjectDetail() + getSCurve() + getOverdueActivities() + getReportDistribution() + getComments() return () => { console.log('unmount RenderMap'); } @@ -119,6 +123,10 @@ const DashboardProject = () => { setActualStart(result.data.data.header?.start_date ? result.data.data.header.start_date : null) setEstimatedFinish(result.data.data.header?.end_date ? result.data.data.header.end_date : null) setIsReadyProjectDetail(true); + + if (result.data.data.kode_sortname && result.data.data.kode_sortname !== '') { + getIntegrationInvoice(result.data.data.kode_sortname) + } } } @@ -144,7 +152,10 @@ const DashboardProject = () => { return; } else if (result.status == 200 && result.data.data) { - console.log(result.data.data); + let selisihProgress = 0; + let planningProgress = 0; + let actualProgress = 0; + let statusHealthBySchedule = 'on-schedule'; if (result.data.data.length > 0 && result.data.data[0].data?.budget_control) { setCurrentBudget(result.data.data[0].data.budget_control.current_budget?.toString()) setActualToDate(result.data.data[0].data.budget_control.acwp?.toString()) @@ -154,6 +165,24 @@ const DashboardProject = () => { setEstAtCompletion(result.data.data[0].data.budget_control.estimated_at_completion?.toString()) setCostDeviation(result.data.data[0].data.budget_control.cost_deviation?.toString()) } + if (result.data.data.length > 0 && result.data.data[0].data?.percentagePlan && result.data.data[0].data?.percentagePlan.length > 0) { + let planningProgress = result.data.data[0].data?.percentagePlan[result.data.data[0].data?.percentagePlan.length-1]; + setPlanningProgress(planningProgress); + } + if (result.data.data.length > 0 && result.data.data[0].data?.percentageReal && result.data.data[0].data?.percentageReal.length > 0) { + let actualProgress = result.data.data[0].data?.percentageReal[result.data.data[0].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); } } @@ -179,7 +208,6 @@ const DashboardProject = () => { return; } else if (result.status == 200 && result.data.data) { - console.log(result.data.data); if (result.data.data.overdueActivities) { setOverdueActivities(result.data.data.overdueActivities) } @@ -188,6 +216,66 @@ const DashboardProject = () => { } } + const getIntegrationInvoice = async (kode_sortname) => { + setIsReadyIntegrationInvoice(false); + const URL = `${BASE_OSPRO}/api/project/get-integration-invoice`; + const payload = { + "search": kode_sortname + } + const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response) + console.log('getIntegrationInvoice', result); + if (!result) { + NotificationManager.error(`Could not connect to internet.`, "Failed"); + setIsReadyIntegrationInvoice(true); + return; + } + + if (result.status !== 200) { + NotificationManager.error(`Get integration invoice failed, ${result.data.message}`, "Failed"); + setIsReadyIntegrationInvoice(true); + return; + } + else if (result.status == 200 && result.data.data) { + // console.log() + if (result.data.data.data) { + let total_invoice = result.data.data.data.total_invoice_amount; + let cash_in = result.data.data.data.total_invoice_paid_amount; + let outstanding_balance = total_invoice - cash_in; + setTotalInvoice(total_invoice ? total_invoice.toString() : null); + setCashIn(cash_in ? total_invoice.toString() : null) + setOutstandingBalance(outstanding_balance ? outstanding_balance.toString() : null); + } + setIsReadyIntegrationInvoice(true); + } + } + + const getReportDistribution = async () => { + setIsReadyReportDistribution(false); + const URL = `${BASE_OSPRO}/api/project/get-report-distribution`; + const payload = { + "project_id": PROJECT_ID, + "start_date": moment().startOf('month').subtract(1, 'years').format('YYYY-MM-DD'), + "end_date": moment(new Date()).subtract(1, 'years').format('YYYY-MM-DD') + } + const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response) + console.log('getReportDistribution', result); + if (!result) { + NotificationManager.error(`Could not connect to internet.`, "Failed"); + setIsReadyReportDistribution(true); + return; + } + + if (result.status !== 200) { + NotificationManager.error(`Get report distribution failed, ${result.data.message}`, "Failed"); + setIsReadyReportDistribution(true); + return; + } + else if (result.status == 200 && result.data.data) { + setReportDistribution(result.data.data); + setIsReadyReportDistribution(true); + } + } + const getComments = async () => { setIsReadyComments(false); const URL = `${BASE_OSPRO}/api/project-comment/search`; @@ -231,7 +319,6 @@ const DashboardProject = () => { return; } else if (result.status == 200 && result.data.data) { - console.log(result.data.data); setComments(result.data.data); setIsReadyComments(true); } @@ -284,10 +371,19 @@ const DashboardProject = () => { }); setMymap(mymap); - L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '© OpenStreetMap contributors'}).addTo(mymap); } + useEffect(() => { + if (mymap) { + if (reportDistribution.length > 0) { + reportDistribution.map((item, idx) => { + L.marker([item.lat, item.lon]).addTo(mymap).bindPopup(PopupContent(item)); + }); + } + } + }, [mymap, reportDistribution]) + const RenderGantt = useMemo(() => ( ), [activeTabIdx]) - const SingleTextLoader = ({width, height}) => ( - - - - ) - - const ListLoader = () => ( - //
Loading overdue activities...
-
- -
- -
- -
- -
- -
- ) - - const Comment = ({name, comment, created_at}) => ( -
-
{name}
-
{created_at ? moment(created_at).format('D MMMM YYYY HH:mm:ss') : '-'}
-
{comment}
-
- ) - - const BehindTaskItem = ({name, message}) => ( -
-
{name}
-
{message}
- {/*
{division}
*/} -
- ) const RenderComments = useMemo(() => { return ( @@ -578,12 +631,17 @@ const DashboardProject = () => {
Progress
-
-
Planning : {planningProgress}%
-
-
-
Actual : {actualProgress}%
-
+ {isReadySCurve ? + + : + + } +
+ {isReadySCurve ? + + : + + }
@@ -591,17 +649,13 @@ const DashboardProject = () => {
Health By Budget
-
-
{healthByBudget}
-
+ {isReadyOverdueActivities ? : }
Health By Schedule
-
-
{healthBySchedule}
-
+ {isReadySCurve ? : }
@@ -614,18 +668,33 @@ const DashboardProject = () => { */} Total Invoice - {totalInvoice ? renderFormatRupiah(totalInvoice, 'Rp.') : '-' } + + {isReadyIntegrationInvoice ? + totalInvoice ? renderFormatRupiah(totalInvoice, 'Rp.') : '-' + : + } + Cash In - {cashIn ? renderFormatRupiah(cashIn, 'Rp.') : '-' } + + {isReadyIntegrationInvoice ? + cashIn ? renderFormatRupiah(cashIn, 'Rp.') : '-' + : + } +
Outstanding Balance - {outstandingBalance ? renderFormatRupiah(outstandingBalance, 'Rp.') : '-' } + + {isReadyIntegrationInvoice ? + outstandingBalance ? renderFormatRupiah(outstandingBalance, 'Rp.') : '-' + : + } +
Activity:${item.activity_name}
Reported at:${item.report_date ? moment(item.report_date).format('D MMMM YYYY HH:mm:ss') : '-'}
Reported by:${item.name}

Material:${item.material_name}
QTY Plan:${item.qty_planning} (${item.material_unit})
QTY Real:${item.qty_real} (${item.material_unit})

Notes:${item.report_notes}