Yusuf
2 years ago
5 changed files with 423 additions and 98 deletions
@ -0,0 +1,128 @@
|
||||
.number-asset { |
||||
font-size: 50px; |
||||
font-weight: bold; |
||||
text-align: center; |
||||
} |
||||
|
||||
.text-bold { |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.view-rectangle { |
||||
display: flex; |
||||
flex-direction: row; |
||||
width: 100%; |
||||
justify-content: space-between; |
||||
} |
||||
|
||||
.view1 { |
||||
width: 220px; |
||||
height: 100px; |
||||
padding: 10px; |
||||
margin-bottom: -20px; |
||||
|
||||
justify-content: center; |
||||
align-items: center; |
||||
text-align: center; |
||||
background-color: #008B8B; |
||||
} |
||||
|
||||
.view2 { |
||||
width: 220px; |
||||
height: 100px; |
||||
padding: 10px; |
||||
|
||||
justify-content: center; |
||||
align-items: center; |
||||
text-align: center; |
||||
background-color: #8B008B; |
||||
} |
||||
|
||||
.view3 { |
||||
width: 220px; |
||||
height: 100px; |
||||
padding: 10px; |
||||
|
||||
justify-content: center; |
||||
align-items: center; |
||||
text-align: center; |
||||
background-color: #7CFC00; |
||||
} |
||||
|
||||
.view4 { |
||||
width: 220px; |
||||
height: 100px; |
||||
padding: 10px; |
||||
|
||||
justify-content: center; |
||||
align-items: center; |
||||
text-align: center; |
||||
background-color: #FF0000; |
||||
} |
||||
|
||||
.view5 { |
||||
width: 220px; |
||||
height: 100px; |
||||
padding: 10px; |
||||
|
||||
justify-content: center; |
||||
align-items: center; |
||||
text-align: center; |
||||
background-color: #4682B4; |
||||
} |
||||
|
||||
.number-style { |
||||
font-size: 30px; |
||||
color: black; |
||||
font-weight: bold; |
||||
margin-bottom:15px; |
||||
} |
||||
|
||||
.number-style1 { |
||||
font-size: 30px; |
||||
color: #FFFFFF; |
||||
font-weight: bold; |
||||
margin-bottom:15px; |
||||
} |
||||
|
||||
.daily-info-card { |
||||
min-width: 130px; |
||||
width: 220px; |
||||
height: 100px; |
||||
padding: 10px; |
||||
justify-content: center; |
||||
align-items: center; |
||||
text-align: center; |
||||
margin: 4px; |
||||
border-radius: 8px; |
||||
} |
||||
|
||||
|
||||
.dashboard-container { |
||||
overflow-x: auto; |
||||
} |
||||
|
||||
.maptable-window-button-container { |
||||
float: right; |
||||
right: 0px; |
||||
} |
||||
|
||||
.maptable-close, .maptable-maximize, .maptable-minimize { |
||||
cursor: pointer; |
||||
padding: 4px; |
||||
} |
||||
|
||||
.maptable-header { |
||||
margin-bottom: -10px; |
||||
} |
||||
|
||||
.maptable-title { |
||||
font-size: 24px; |
||||
font-weight: 700; |
||||
text-align: left; |
||||
margin-left: 20px; |
||||
} |
||||
|
||||
.maptable-close:hover, .maptable-maximize:hover, .maptable-minimize:hover { |
||||
color: #20a8d8; |
||||
} |
@ -0,0 +1,41 @@
|
||||
import React, { useState, useEffect } from 'react'; |
||||
import ReactDOM from 'react-dom'; |
||||
import { Pie } from '@ant-design/plots'; |
||||
|
||||
const PieChart = () => { |
||||
const data = [ |
||||
{ |
||||
type: 'FTTH', |
||||
value: 27, |
||||
}, |
||||
{ |
||||
type: 'Konstruksi', |
||||
value: 25, |
||||
}, |
||||
]; |
||||
const config = { |
||||
appendPadding: 10, |
||||
data, |
||||
angleField: 'value', |
||||
colorField: 'type', |
||||
radius: 0.9, |
||||
label: { |
||||
type: 'inner', |
||||
offset: '-30%', |
||||
content: ({ percent }) => `${(percent * 100).toFixed(0)}%`, |
||||
style: { |
||||
fontSize: 14, |
||||
textAlign: 'center', |
||||
}, |
||||
}, |
||||
interactions: [ |
||||
{ |
||||
type: 'element-active', |
||||
}, |
||||
], |
||||
}; |
||||
|
||||
return <Pie {...config} />; |
||||
}; |
||||
|
||||
export default PieChart; |
@ -0,0 +1,152 @@
|
||||
import '../../../node_modules/react-grid-layout/css/styles.css'; |
||||
import '../../../node_modules/react-resizable/css/styles.css'; |
||||
import './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 { formatRupiah, DATE_TIME_FORMAT } from '../../const/CustomFunc.js'; |
||||
|
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}`, |
||||
"Access-Control-Allow-Origin": "*" |
||||
} |
||||
} |
||||
|
||||
const Dashboard = () => { |
||||
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) |
||||
// const arr = result.data.data.map((res) => {
|
||||
// console.log("insd", res)
|
||||
// return res
|
||||
// });
|
||||
setDataTable(result.data.data); |
||||
} |
||||
|
||||
const columns = [ |
||||
{ |
||||
title: 'Project', |
||||
dataIndex: 'nama', |
||||
key: 'nama', |
||||
render: (text) => <a>{text}</a>, |
||||
}, |
||||
{ |
||||
title: 'Planned Interval', |
||||
dataIndex: 'plannedInterval', |
||||
key: 'plannedInterval', |
||||
}, |
||||
{ |
||||
title: 'Planned Cost', |
||||
dataIndex: 'plannedCost', |
||||
key: 'plannedCost', |
||||
}, |
||||
{ |
||||
title: 'Actual Cost', |
||||
dataIndex: 'actualCost', |
||||
key: 'actualCost', |
||||
}, |
||||
{ |
||||
title: 'Cost Variance', |
||||
dataIndex: 'costVariance', |
||||
key: 'costVariance', |
||||
}, |
||||
{ |
||||
title: 'Cost Health', |
||||
dataIndex: 'costHealth', |
||||
key: 'costHealth', |
||||
}, |
||||
|
||||
{ |
||||
title: 'Schedule Health', |
||||
dataIndex: 'scheduleHealth', |
||||
key: 'scheduleHealth', |
||||
}, |
||||
{ |
||||
title: 'Progress', |
||||
dataIndex: 'progress', |
||||
key: 'progress', |
||||
}, |
||||
]; |
||||
|
||||
useEffect(() => { |
||||
getProjects(); |
||||
}, []) |
||||
|
||||
|
||||
return ( |
||||
<> |
||||
<Row gutter={[16, 16]}> |
||||
<Col span={6} > |
||||
<Card |
||||
size="small" |
||||
title="Total Project" |
||||
align="center" |
||||
style={{ |
||||
width: 300, |
||||
}} |
||||
> |
||||
<p align="center">5</p> |
||||
</Card> |
||||
</Col> |
||||
<Col span={6} > |
||||
<Card |
||||
size="small" |
||||
title="Total Project Cost" |
||||
align="center" |
||||
style={{ |
||||
width: 300, |
||||
}} |
||||
> |
||||
<p align="center">5</p> |
||||
</Card> |
||||
</Col> |
||||
<Col span={6} > |
||||
<Card |
||||
size="small" |
||||
title="Cost Variance" |
||||
align="center" |
||||
style={{ |
||||
width: 300, |
||||
}} |
||||
> |
||||
<p align="center">5</p> |
||||
</Card> |
||||
</Col> |
||||
<Col span={6} > |
||||
<PieChart /> |
||||
</Col> |
||||
</Row> |
||||
<Row gutter={[16, 16]}> |
||||
<Col span={24}> |
||||
<Table columns={columns} dataSource={dataTable} /> |
||||
</Col> |
||||
</Row> |
||||
</> |
||||
|
||||
); |
||||
} |
||||
|
||||
export default Dashboard; |
Loading…
Reference in new issue