From 9aebdc348391f85b35e859350b49798e6af6ef4d Mon Sep 17 00:00:00 2001 From: bnu Date: Thu, 28 Jul 2022 03:29:12 +0700 Subject: [PATCH] update route dashboard, and page dashboard PMO v1 --- src/routes.js | 3 +- src/views/DashboardPMOV1/chartDashboard.js | 106 ++++++++++ src/views/DashboardPMOV1/index.js | 198 +++++++++++++++++++ src/views/DashboardPMOV1/tableDashboard.js | 130 ++++++++++++ src/views/DashboardPMOV1/tableDashboardv1.js | 115 +++++++++++ 5 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 src/views/DashboardPMOV1/chartDashboard.js create mode 100644 src/views/DashboardPMOV1/index.js create mode 100644 src/views/DashboardPMOV1/tableDashboard.js create mode 100644 src/views/DashboardPMOV1/tableDashboardv1.js diff --git a/src/routes.js b/src/routes.js index 8bc74a4..2bbe822 100644 --- a/src/routes.js +++ b/src/routes.js @@ -43,11 +43,12 @@ const TestGantt = React.lazy(() => import('./views/testgantt')); const UserAdmin = React.lazy(() => import('./views/Master/UserAdmin')); const UserShift = React.lazy(() => import('./views/SimproV2/UserShift')); const DashboardProject = React.lazy(() => import('./views/DashboardProject')); +const DashboardPMOV1 = React.lazy(() => import('./views/DashboardPMOV1')); const routes = [ { path: '/', exact: true, name: 'Home' }, { path: '/dashboardold', name: 'Dashboard', component: DashboardSimpro }, - { path: '/dashboard', name: 'Dashboard', component: DashboardPMO }, + { path: '/dashboard', name: 'Dashboard', component: DashboardPMOV1 }, { path: '/projects', exact: true, name: 'Projects', component: CreatedProyek }, { path: '/projects/:id/:project/gantt', exact: true, name: 'Gantt', component: Gantt }, diff --git a/src/views/DashboardPMOV1/chartDashboard.js b/src/views/DashboardPMOV1/chartDashboard.js new file mode 100644 index 0000000..9d09ff7 --- /dev/null +++ b/src/views/DashboardPMOV1/chartDashboard.js @@ -0,0 +1,106 @@ +import React from 'react'; +import { Doughnut, Bar } from 'react-chartjs-2'; +import { faker } from '@faker-js/faker'; + +export const optionsDoughnut = { + title: { + display: true, + text: 'PROJECT BY TYPE' + }, +}; + +export const data = { + labels: ['Pengadaan Barang dan Jasa','Kontruksi', 'FTTH'], + datasets: [ + { + label: '# of Votes', + data: [1, 1, 2], + backgroundColor: [ + 'rgba(255, 99, 132, 0.2)', + 'rgba(54, 162, 235, 0.2)', + 'rgba(255, 206, 86, 0.2)', + 'rgba(75, 192, 192, 0.2)', + // 'rgba(153, 102, 255, 0.2)', + // 'rgba(255, 159, 64, 0.2)', + ], + borderColor: [ + 'rgba(255, 99, 132, 1)', + 'rgba(54, 162, 235, 1)', + 'rgba(255, 206, 86, 1)', + 'rgba(75, 192, 192, 1)', + 'rgba(153, 102, 255, 1)', + // 'rgba(255, 159, 64, 1)', + ], + borderWidth: 1, + }, + ], +}; + +export const DoughnutChart = () => { + return ; +} + + +export const options = { + title: { + display: true, + text: 'PROJECT BY GOVERNANCE PHASE' + }, + legend: { + position: 'right', + }, + responsive: true, + scales: { + yAxes: [{ + display: true, + + // position: 'right', + stacked: true, + }], + xAxes: [{ + display: true, + // position: 'right', + stacked: true, + }], + }, +}; + +const labels = ['']; + +export const dataBar = { + labels, + datasets: [ + { + indexAxis: 'y', + label: 'Initiation', + data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })), + backgroundColor: 'rgb(255, 99, 132)', + }, + { + indexAxis: 'y', + label: 'Execution', + data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })), + backgroundColor: 'rgb(75, 192, 192)', + }, + { + indexAxis: 'y', + label: 'Closing', + data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })), + backgroundColor: 'rgb(53, 162, 235)', + }, + // { + // indexAxis: 'y', + // label: 'Excecution', + // data: labels.map(() => faker.datatype.number({ min: 0, max: 10 })), + // backgroundColor: 'rgba(255, 159, 64, 1)', + // }, + ], +}; + +export function BarChart() { + return ; +} + + + + diff --git a/src/views/DashboardPMOV1/index.js b/src/views/DashboardPMOV1/index.js new file mode 100644 index 0000000..8fbe6f2 --- /dev/null +++ b/src/views/DashboardPMOV1/index.js @@ -0,0 +1,198 @@ +import React, {useEffect, useState} from 'react'; +import { Row, Col, Select } from 'antd'; +import TableDashboard from './tableDashboard'; +import TableDashboardV1 from './tableDashboardv1'; +import { BarChart, DoughnutChart } from './chartDashboard'; +import axios from 'axios' +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { BASE_OSPRO } from '../../const/ApiConst'; + +function BoxDashboard({ value, title, secondaryTitle, icon, bgColor }) { + return ( +
+ + +
+ {icon} +
+ + +
+
{value}
+
{title.toUpperCase()}
+
{secondaryTitle && secondaryTitle.toUpperCase()}
+
+ +
+
+ ) +} + +const { Option } = Select; + +const DashbaoardPM = () => { + const [PROJECTCOUNT, SET_PROJECTCOUNT] = useState([]) + const [PROJECTBUDGETTOTAL, SET_PROJECTBUDGETTOTAL] = useState([]) + const [PROJECTMANPOWER, SET_PROJETMANPOWER] = useState([]) + const [PROJECTACTUALCOSTTOTAL, SET_PROJECTACTUALCOSTTOTAL] = useState([]) + + const token = localStorage.getItem("token") + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } + } + + const getProjects = async () => { + const URL = `${BASE_OSPRO}/api/project/list` + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + if (result.data.code !== 200) { + NotificationManager.error('Belum ada data proyek!', 'Failed'); + } + console.log("res ", result.data.data) + // setDataTable(result.data.data); + SET_PROJECTCOUNT(result.data.totalRecord) + SET_PROJECTACTUALCOSTTOTAL(result.data.totalActualCost) + SET_PROJECTBUDGETTOTAL(result.data.totalPlannedCost) + } + + useEffect(() => { + getProjects(); + }, []) + + return ( +
+ +
PORTOFOLIO DASHBOARD
+ {/* + + + + + + + + + + + */} +
+ +
+ + + } + value={PROJECTCOUNT} + bgColor="teal" + title="Project Count" /> + {/* } + value="19 M" + bgColor="#059669" + title="Project Cost" + secondaryTitle="(dollars)" /> */} + } + value={PROJECTBUDGETTOTAL} + bgColor="#047857" + title="Budget Project Total" + secondaryTitle="(dollars)" /> + } + value="2000" + bgColor="#0284c7" + title="Project Manpower" + /> + +
+
+ ); +} + +export default DashbaoardPM; \ No newline at end of file diff --git a/src/views/DashboardPMOV1/tableDashboard.js b/src/views/DashboardPMOV1/tableDashboard.js new file mode 100644 index 0000000..64931d3 --- /dev/null +++ b/src/views/DashboardPMOV1/tableDashboard.js @@ -0,0 +1,130 @@ +import React from 'react'; +import { Table, Tag, Space } from 'antd'; + +const columns = [ + { + title: 'Project Name', + dataIndex: 'project', + key: 'project', + fixed: 'left', + width: 200, + // render: text => {text}, + }, + { + title: 'Project Owner', + dataIndex: 'owner', + key: 'owner', + }, + { + title: 'Start Date', + dataIndex: 'startDate', + key: 'startDate', + }, + { + title: 'End Date', + dataIndex: 'endDate', + key: 'endDate', + }, + { + title: 'Cost', + dataIndex: 'cost', + key: 'cost', + render: text => `Rp. ${text.toLocaleString()}`, + align: 'right' + }, + { + title: 'Cost Health', + dataIndex: 'costHealth', + key: 'costHealth', + render: text => + text === 'good' ?
: + text === 'danger' ?
: + text === 'warning' ?
:
+ , + align: 'center', + }, + { + title: 'Work Health', + dataIndex: 'workHealth', + key: 'workHealth', + render: text => + text === 'good' ?
: + text === 'danger' ?
: + text === 'warning' ?
:
, + align: 'center', + }, + { + title: 'Schedule Health', + dataIndex: 'scheduleHealth', + key: 'scheduleHealth', + render: text => + text === 'good' ?
: + text === 'danger' ?
: + text === 'warning' ?
:
, + align: 'center', + }, + { + title: '% Complete', + dataIndex: 'complete', + key: 'complete', + render: text => `${text}%`, + align: 'right' + }, + // { + // title: 'Action', + // key: 'action', + // render: (text, record) => ( + // + // Invite {record.name} + // Delete + // + // ), + // }, +]; + +const data = [ + { + key: '1', + project: 'Bay Plaza', + owner: 'John Brown', + startDate: '1/22/2022', + endDate: '1/22/2023', + complete: 20, + cost: 40000000, + costHealth: 'good', + workHealth: 'default', + scheduleHealth: 'warning' + }, + { + key: '2', + project: 'Jambi Bridge', + owner: 'Jim Green', + startDate: '4/22/2022', + endDate: '11/22/2023', + complete: 65, + cost: 20000000, + costHealth: 'good', + workHealth: 'default', + scheduleHealth: 'danger' + }, + { + key: '3', + project: 'Banten International Airport', + owner: 'Joe Black', + startDate: '1/22/2022', + endDate: '1/22/2025', + complete: 50, + cost: 200000000, + costHealth: 'default', + workHealth: 'default', + scheduleHealth: 'default' + }, +]; + +const TableDashboard = () => { + return ( + + ); +} + +export default TableDashboard; \ No newline at end of file diff --git a/src/views/DashboardPMOV1/tableDashboardv1.js b/src/views/DashboardPMOV1/tableDashboardv1.js new file mode 100644 index 0000000..beac1a0 --- /dev/null +++ b/src/views/DashboardPMOV1/tableDashboardv1.js @@ -0,0 +1,115 @@ +import '../../../node_modules/react-grid-layout/css/styles.css'; +import '../../../node_modules/react-resizable/css/styles.css'; +import './../DashboardPMO/Dashboard.css'; +// import PieChart from './PieChart'; +import { BASE_OSPRO } from '../../const/ApiConst'; +import ContentLoader from "react-content-loader" +import React, { useEffect, useState } from 'react'; +import axios from 'axios' +import moment from 'moment'; +import numeral from 'numeral'; +import { Table, Tree, Row, Col, Space, Card} from 'antd'; +import { Pie } from '@ant-design/plots'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { formatRibuanDecimal, DATE_TIME_FORMAT } from '../../const/CustomFunc.js'; +import { Badge } from 'reactstrap'; +import { Link } from "react-router-dom"; + +const token = localStorage.getItem("token") +const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}`, + "Access-Control-Allow-Origin": "*" + } +} + +const TableDashboardV1 = () => { + const token = localStorage.getItem("token") + const HEADER = { + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + } + } + + const [dataTable, setDataTable] = useState([]) + const getProjects = async () => { + const URL = `${BASE_OSPRO}/api/project/list` + const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) + if (result.data.code !== 200) { + NotificationManager.error('Belum ada data proyek!', 'Failed'); + } + // console.log("res ", result.data.data) + setDataTable(result.data.data); + } + + const columns = [ + { + title: 'Project', + dataIndex: 'nama', + key: 'nama', + render: (text, record) => {text}, + }, + { + title: 'Planned Interval', + dataIndex: 'plannedInterval', + key: 'plannedInterval', + }, + { + title: 'Budget Project', + dataIndex: 'plannedCost', + key: 'plannedCost', + render: (text) => { formatRibuanDecimal(text) }, + }, + { + title: 'Actual Cost', + dataIndex: 'actualCost', + key: 'actualCost', + render: (text) => { formatRibuanDecimal(text) }, + }, + { + title: 'Cost Variance', + dataIndex: 'costVariance', + key: 'costVariance', + render: (text) => { formatRibuanDecimal(text) }, + }, + { + title: 'Cost Health', + dataIndex: 'costHealth', + key: 'costHealth', + render: (text) => { + if(text == "on-budget") { + return On Budget + } else if(text == "warning") { + return Warning + } else { + return Danger + } + } + }, + { + title: 'Progress', + dataIndex: 'progress', + key: 'progress', + }, + ]; + + useEffect(() => { + getProjects(); + }, []) + + + return ( + <> + + +
+ + + + + ); +} + +export default TableDashboardV1;