wahyun
1 year ago
6 changed files with 1001 additions and 589 deletions
@ -1,234 +1,234 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Row, Col, Table } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import axios from 'axios'; |
||||
import { MENU_SEARCH } from '../../../const/ApiConst.js'; |
||||
import { withTranslation, WithTranslation } from 'react-i18next'; |
||||
const BASE_URL = "http://siopas.co.id/custom-php/api/geohr/"; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
|
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
class DialogMenuRoles extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
name: "", |
||||
description: "", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
menu: [], |
||||
stateMenu: [], |
||||
allChecked: true, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.props.showDialog(this.showDialog); |
||||
this.getAllMenu(); |
||||
} |
||||
|
||||
async componentDidUpdate() { |
||||
if (this.state.isParentClick === true) { |
||||
const { idRoles } = this.props |
||||
this.setStateMenu(true); |
||||
this.setState({ isParentClick: false, id: idRoles }); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
getAllMenu = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": "", "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
|
||||
|
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ menu: result.data.data }, () => { |
||||
this.setStateMenu(false); |
||||
}); |
||||
} else { |
||||
} |
||||
|
||||
} |
||||
|
||||
setStateMenu = edit => { |
||||
const stateMenu = []; |
||||
this.state.menu.map((val) => { |
||||
stateMenu.push(false); |
||||
}) |
||||
this.setState({ stateMenu: [] }, () => { |
||||
this.setState({ stateMenu: stateMenu }, () => { |
||||
if (edit) { |
||||
this.checkMenuRoles(); |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
checkMenuRoles = () => { |
||||
let copyStateMenu = [...this.state.stateMenu]; |
||||
this.props.menuRoles.map((val, indexMenu) => { |
||||
let index = this.getIndexDataMenu(val.menu_id); |
||||
console.log("index true", val.menu_id); |
||||
if (index >= 0) { |
||||
copyStateMenu[index] = true; |
||||
} |
||||
}) |
||||
this.setState({ stateMenu: [] }, () => { |
||||
let check = copyStateMenu.some(this.checkArray); |
||||
if (check === false) { |
||||
this.setState({ allChecked: true, stateMenu: copyStateMenu }) |
||||
} else { |
||||
this.setState({ allChecked: false, stateMenu: copyStateMenu }) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
|
||||
getIndexDataMenu = (id) => { |
||||
let index = this.state.menu.findIndex(obj => obj.id === id); |
||||
return index |
||||
} |
||||
|
||||
handleSave = () => { |
||||
const { |
||||
stateMenu, |
||||
menu, |
||||
id |
||||
} = this.state |
||||
|
||||
const arrayData = []; |
||||
|
||||
menu.map((val, index) => { |
||||
let data = { |
||||
roles_id: id, |
||||
menu_id: val.id, |
||||
checked: stateMenu[index] |
||||
} |
||||
arrayData.push(data); |
||||
}) |
||||
this.props.closeDialog('save', arrayData); |
||||
this.setState({ id: 0 }); |
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
handleChangeCheckbox = (checked, index) => { |
||||
let copyStateMenu = [...this.state.stateMenu]; |
||||
copyStateMenu[index] = checked; |
||||
console.log("cek uncek", copyStateMenu); |
||||
this.setState({ stateMenu: copyStateMenu }) |
||||
} |
||||
|
||||
renderForm = () => { |
||||
const { menu, stateMenu } = this.state |
||||
return ( |
||||
menu.map((val, index) => { |
||||
return ( |
||||
<tr key={index}> |
||||
<td>{val.name}</td> |
||||
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckbox(e.target.checked, index)} defaultChecked={stateMenu[index]} /></td> |
||||
</tr> |
||||
) |
||||
}) |
||||
) |
||||
} |
||||
|
||||
checkArray = (val) => { |
||||
return val === false; |
||||
} |
||||
|
||||
handleAllChecked = (checked) => { |
||||
this.setState({ allChecked: !this.state.allChecked }); |
||||
if (checked === true) { |
||||
console.log("test 1") |
||||
let check = this.state.stateMenu.some(this.checkArray); |
||||
|
||||
if (check) { |
||||
const stateMenu = []; |
||||
this.state.menu.map((val) => { |
||||
stateMenu.push(true); |
||||
}) |
||||
|
||||
this.setState({ stateMenu: [] }, () => { |
||||
this.setState({ stateMenu: stateMenu }); |
||||
}) |
||||
} |
||||
|
||||
|
||||
} else { |
||||
console.log("test 1 2 3 ") |
||||
const stateMenu = []; |
||||
this.state.menu.map((val) => { |
||||
stateMenu.push(false); |
||||
}) |
||||
|
||||
this.setState({ stateMenu: [] }, () => { |
||||
this.setState({ stateMenu: stateMenu }); |
||||
}) |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal scrollable={true} isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.props.closeDialog}>{this.props.t('menuRoles')}</ModalHeader> |
||||
<ModalBody> |
||||
<Form> |
||||
<Table> |
||||
<thead> |
||||
<tr> |
||||
<th>Menu</th> |
||||
<th> |
||||
T/F |
||||
</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<tr> |
||||
<td>All</td> |
||||
<td><input type="checkbox" onChange={(e) => this.handleAllChecked(e.target.checked)} checked={this.state.allChecked} /></td> |
||||
</tr> |
||||
{this.renderForm()} |
||||
</tbody> |
||||
</Table> |
||||
</Form> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.t('save')}</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>{this.props.t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogMenuRoles); |
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Row, Col, Table } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import axios from 'axios'; |
||||
import { MENU_SEARCH } from '../../../const/ApiConst.js'; |
||||
import { withTranslation, WithTranslation } from 'react-i18next'; |
||||
const BASE_URL = "http://siopas.co.id/custom-php/api/geohr/"; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
|
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
class DialogMenuRoles extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
name: "", |
||||
description: "", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
menu: [], |
||||
stateMenu: [], |
||||
allChecked: true, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.props.showDialog(this.showDialog); |
||||
this.getAllMenu(); |
||||
} |
||||
|
||||
async componentDidUpdate() { |
||||
if (this.state.isParentClick === true) { |
||||
const { idRoles } = this.props |
||||
this.setStateMenu(true); |
||||
this.setState({ isParentClick: false, id: idRoles }); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
getAllMenu = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": "", "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
|
||||
|
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ menu: result.data.data }, () => { |
||||
this.setStateMenu(false); |
||||
}); |
||||
} else { |
||||
} |
||||
|
||||
} |
||||
|
||||
setStateMenu = edit => { |
||||
const stateMenu = []; |
||||
this.state.menu.map((val) => { |
||||
stateMenu.push(false); |
||||
}) |
||||
this.setState({ stateMenu: [] }, () => { |
||||
this.setState({ stateMenu: stateMenu }, () => { |
||||
if (edit) { |
||||
this.checkMenuRoles(); |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
checkMenuRoles = () => { |
||||
let copyStateMenu = [...this.state.stateMenu]; |
||||
this.props.menuRoles.map((val, indexMenu) => { |
||||
let index = this.getIndexDataMenu(val.menu_id); |
||||
console.log("index true", val.menu_id); |
||||
if (index >= 0) { |
||||
copyStateMenu[index] = true; |
||||
} |
||||
}) |
||||
this.setState({ stateMenu: [] }, () => { |
||||
let check = copyStateMenu.some(this.checkArray); |
||||
if (check === false) { |
||||
this.setState({ allChecked: true, stateMenu: copyStateMenu }) |
||||
} else { |
||||
this.setState({ allChecked: false, stateMenu: copyStateMenu }) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
|
||||
getIndexDataMenu = (id) => { |
||||
let index = this.state.menu.findIndex(obj => obj.id === id); |
||||
return index |
||||
} |
||||
|
||||
handleSave = () => { |
||||
const { |
||||
stateMenu, |
||||
menu, |
||||
id |
||||
} = this.state |
||||
|
||||
const arrayData = []; |
||||
|
||||
menu.map((val, index) => { |
||||
let data = { |
||||
roles_id: id, |
||||
menu_id: val.id, |
||||
checked: stateMenu[index] |
||||
} |
||||
arrayData.push(data); |
||||
}) |
||||
this.props.closeDialog('save', arrayData); |
||||
this.setState({ id: 0 }); |
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
handleChangeCheckbox = (checked, index) => { |
||||
let copyStateMenu = [...this.state.stateMenu]; |
||||
copyStateMenu[index] = checked; |
||||
console.log("cek uncek", copyStateMenu); |
||||
this.setState({ stateMenu: copyStateMenu }) |
||||
} |
||||
|
||||
renderForm = () => { |
||||
const { menu, stateMenu } = this.state |
||||
return ( |
||||
menu.map((val, index) => { |
||||
return ( |
||||
<tr key={index}> |
||||
<td>{val.name}</td> |
||||
<td><input type="checkbox" onClick={(e) => this.handleChangeCheckbox(e.target.checked, index)} defaultChecked={stateMenu[index]} /></td> |
||||
</tr> |
||||
) |
||||
}) |
||||
) |
||||
} |
||||
|
||||
checkArray = (val) => { |
||||
return val === false; |
||||
} |
||||
|
||||
handleAllChecked = (checked) => { |
||||
this.setState({ allChecked: !this.state.allChecked }); |
||||
if (checked === true) { |
||||
console.log("test 1") |
||||
let check = this.state.stateMenu.some(this.checkArray); |
||||
|
||||
if (check) { |
||||
const stateMenu = []; |
||||
this.state.menu.map((val) => { |
||||
stateMenu.push(true); |
||||
}) |
||||
|
||||
this.setState({ stateMenu: [] }, () => { |
||||
this.setState({ stateMenu: stateMenu }); |
||||
}) |
||||
} |
||||
|
||||
|
||||
} else { |
||||
console.log("test 1 2 3 ") |
||||
const stateMenu = []; |
||||
this.state.menu.map((val) => { |
||||
stateMenu.push(false); |
||||
}) |
||||
|
||||
this.setState({ stateMenu: [] }, () => { |
||||
this.setState({ stateMenu: stateMenu }); |
||||
}) |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal scrollable={true} isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.props.closeDialog}>{this.props.t('menuRoles')}</ModalHeader> |
||||
<ModalBody> |
||||
<Form> |
||||
<Table> |
||||
<thead> |
||||
<tr> |
||||
<th>Menu</th> |
||||
<th> |
||||
T/F |
||||
</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<tr> |
||||
<td>All</td> |
||||
<td><input type="checkbox" onChange={(e) => this.handleAllChecked(e.target.checked)} checked={this.state.allChecked} /></td> |
||||
</tr> |
||||
{this.renderForm()} |
||||
</tbody> |
||||
</Table> |
||||
</Form> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.t('save')}</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>{this.props.t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogMenuRoles); |
||||
|
@ -1,347 +1,392 @@
|
||||
import React, { Component } from 'react'; |
||||
import { Link } from 'react-router-dom'; |
||||
import "slick-carousel/slick/slick.css"; |
||||
import "slick-carousel/slick/slick-theme.css"; |
||||
import Slider from "react-slick"; |
||||
import { Spin } from 'antd'; |
||||
import { Checkbox } from 'antd'; |
||||
import { LoadingOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; |
||||
import { |
||||
Button, |
||||
Card, |
||||
CardBody, |
||||
CardGroup, |
||||
Col, |
||||
Container, |
||||
Form, |
||||
Input, |
||||
InputGroup, |
||||
InputGroupAddon, |
||||
InputGroupText, |
||||
Row, |
||||
UncontrolledAlert, |
||||
Alert, |
||||
Carousel, |
||||
CarouselIndicators, |
||||
CarouselCaption, |
||||
CarouselItem, |
||||
CarouselControl |
||||
} from 'reactstrap'; |
||||
import { USER_LOGIN, USER_LOGIN_V2, CALERTUSER_SEARCH, MENU_MANAGEMENT, APP_MODE } from '../../../const/ApiConst.js'; |
||||
import { appConfig, reloadConstants } from '../../../const/MapConst.js'; |
||||
import { APP_NAME } from '../../../const/AppConst.js' |
||||
import moment from "moment" |
||||
import axios from 'axios'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import logo_login_adw from '../../../assets/img/logo_adyawinsa.jpg' |
||||
import logo_login_kit from '../../../assets/img/logo_kit.png' |
||||
import logo_login_nawakara from '../../../assets/img/logo_nawakara.png' |
||||
import logo_login_si from '../../../assets/img/logo-surveyor-indonesia.png' |
||||
|
||||
|
||||
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />; |
||||
|
||||
const settings = { |
||||
dots: true, |
||||
infinite: true, |
||||
speed: 500, |
||||
arrows: false, |
||||
autoplay: true, |
||||
slidesToShow: 1, |
||||
slidesToScroll: 1 |
||||
}; |
||||
|
||||
class Login extends Component { |
||||
constructor(props) { |
||||
super(props); |
||||
this.state = { |
||||
name: '', |
||||
password: '', |
||||
remember: '', |
||||
alertVisible: false, |
||||
alertMessage: '', |
||||
alertColor: 'success', |
||||
validate: { |
||||
emailState: '', |
||||
}, |
||||
loader: false, |
||||
type: 'password' |
||||
} |
||||
this.handleChange = this.handleChange.bind(this); |
||||
this.showHide = this.showHide.bind(this); |
||||
} |
||||
showHide(e) { |
||||
e.preventDefault(); |
||||
e.stopPropagation(); |
||||
this.setState({ |
||||
type: this.state.type === 'input' ? 'password' : 'input' |
||||
}) |
||||
} |
||||
validateEmail(e) { |
||||
const emailRex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; |
||||
const { validate } = this.state |
||||
if (emailRex.test(e.target.value)) { |
||||
validate.emailState = 'has-success' |
||||
} else { |
||||
validate.emailState = 'has-danger' |
||||
} |
||||
this.setState({ validate }) |
||||
} |
||||
|
||||
handleChange = async (event) => { |
||||
const { target } = event; |
||||
const value = target.type === 'checkbox' ? target.checked : target.value; |
||||
const { name } = target; |
||||
await this.setState({ |
||||
[name]: value, |
||||
}); |
||||
} |
||||
|
||||
getDataMenu = async (token, role_id) => { |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
let url = MENU_MANAGEMENT(role_id) |
||||
const result = await axios |
||||
.get(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data |
||||
window.localStorage.setItem('menu_login', JSON.stringify(resData)); |
||||
this.setState({ loader: false }) |
||||
// custom redirect home after login
|
||||
if (role_id == 28) { |
||||
this.props.history.push("/dashboard-customer/58/63"); |
||||
} |
||||
else { |
||||
this.props.history.push("/dashboard"); |
||||
} |
||||
} else { |
||||
NotificationManager.error('Login Failed', 'Failed'); |
||||
this.setState({ loader: false }) |
||||
} |
||||
} |
||||
|
||||
submitForm = (event) => { |
||||
event.preventDefault(); |
||||
this.submitFormLogin(); |
||||
} |
||||
|
||||
submitFormLogin = async () => { |
||||
this.setState({ loader: true }) |
||||
const { name, password, remember } = this.state |
||||
|
||||
if (name === '') { |
||||
NotificationManager.error('Please fill username', 'Login Failed!'); |
||||
this.setState({ loader: false }) |
||||
return false; |
||||
} |
||||
|
||||
if (password === '') { |
||||
NotificationManager.error('Please fill password', 'Login Failed!'); |
||||
this.setState({ loader: false }) |
||||
return false; |
||||
} |
||||
|
||||
let formData = { |
||||
username: name, |
||||
password, |
||||
remember, |
||||
} |
||||
|
||||
const doLogin = await axios.post(USER_LOGIN_V2, formData) |
||||
.then(response => response) |
||||
.catch(error => { |
||||
this.setState({ loader: false }); |
||||
}); |
||||
|
||||
if (doLogin && doLogin.data && doLogin.data.code === 200) { |
||||
const { access_token, data_user } = doLogin.data.data |
||||
this.getDataMenu(access_token, data_user.role_id) |
||||
window.localStorage.setItem('isLogin', true); |
||||
window.localStorage.setItem('token', access_token); |
||||
window.localStorage.setItem('user_id', data_user.id); |
||||
window.localStorage.setItem('user_name', data_user.name); |
||||
window.localStorage.setItem('role_id', data_user.role_id); |
||||
} else { |
||||
console.log("kode : ", doLogin.data.code); |
||||
// NotificationManager.error('Cek username atau password anda!', 'Gagal Login!');
|
||||
NotificationManager.error(doLogin.data.message, 'Login Failed!'); |
||||
this.setState({ loader: false }); |
||||
} |
||||
|
||||
} |
||||
|
||||
getConfigAlert = async (token, user_id) => { |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "user_id", "logic_operator": "=", "value": `${user_id}`, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CALERTUSER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data |
||||
let configAlert = [] |
||||
resData.map((val, index) => { |
||||
configAlert.push(val.config_alert_id); |
||||
}); |
||||
window.localStorage.setItem('userConfigAlert', configAlert.join()); |
||||
} |
||||
} |
||||
|
||||
onShowAlert = (alertColor, alertMessage) => { |
||||
this.setState({ alertVisible: true, alertColor: alertColor, alertMessage: alertMessage }, () => { |
||||
window.setTimeout(() => { |
||||
this.setState({ alertVisible: false }) |
||||
}, 3000) |
||||
}); |
||||
} |
||||
|
||||
getLoginLogo = () => { |
||||
return <div style={{ textAlign: 'center' }}><img style={{ width: '100%' }} src={logo_login_adw} /></div> |
||||
} |
||||
|
||||
getLoginSlider = () => { |
||||
return <Slider {...settings} > |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide1.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide2.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide3.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide4.jpg')} className="img-avatar" /> |
||||
</div> |
||||
</Slider> |
||||
} |
||||
|
||||
onChecked = (e) => { |
||||
this.setState({ remember: e.target.checked }) |
||||
}; |
||||
|
||||
render() { |
||||
const { name, password, remember } = this.state; |
||||
const u_group = window.localStorage.getItem('u_group') |
||||
if (u_group !== null) { |
||||
this.props.history.push("/dashboard"); |
||||
} |
||||
return ( |
||||
<div className="app flex-row align-items-center"> |
||||
<Container> |
||||
<NotificationContainer /> |
||||
|
||||
<Alert color={this.state.alertColor} isOpen={this.state.alertVisible} > |
||||
{this.state.alertMessage} |
||||
</Alert> |
||||
<Row className="justify-content-center"> |
||||
<Col md="7"> |
||||
{this.getLoginSlider()} |
||||
</Col> |
||||
<Col md="5"> |
||||
<div style={{ |
||||
boxShadow: '1px 1px 11px 1px rgba(221,211,211,0.75)' |
||||
}}> |
||||
<CardGroup> |
||||
<Card className="p-4"> |
||||
<CardBody> |
||||
<Form onSubmit={this.submitForm}> |
||||
{this.getLoginLogo()} |
||||
<p className="text-muted">Sign In to your account</p> |
||||
<InputGroup className="mb-3"> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText> |
||||
<i className="icon-user"></i> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type="text" |
||||
name="name" |
||||
id="exampleName" |
||||
placeholder="Username" |
||||
value={name} |
||||
onChange={(e) => { |
||||
this.setState({ name: e.target.value }) |
||||
}} |
||||
/> |
||||
</InputGroup> |
||||
<InputGroup className="mb-4"> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText> |
||||
<i className="icon-lock"></i> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type={this.state.type} |
||||
name="password" |
||||
id="examplePassword" |
||||
placeholder="********" |
||||
value={password} |
||||
onChange={(e) => this.setState({ password: e.target.value })} |
||||
/> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText |
||||
onClick={this.showHide} |
||||
> |
||||
{this.state.type === 'input' ? <EyeOutlined /> : <EyeInvisibleOutlined />} |
||||
|
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<span className="password__show" ></span> |
||||
</InputGroup> |
||||
<Row> |
||||
<Col xs="8"> |
||||
<Checkbox checked={this.state.remember} onChange={this.onChecked}>Remember me (7 days)</Checkbox> |
||||
</Col> |
||||
<Col xs="4"> |
||||
{this.state.loader ? ( |
||||
<Spin indicator={antIcon} /> |
||||
) : ( |
||||
<Button onClick={() => this.submitFormLogin()} color="primary" className="px-4" >Login</Button> |
||||
)} |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col className="text-right mt-5"> |
||||
<Button color="link" className="px-0">Forgot password?</Button> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
</CardBody> |
||||
</Card> |
||||
</CardGroup> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</Container> |
||||
</div> |
||||
); |
||||
} |
||||
} |
||||
|
||||
export default Login; |
||||
import React, { Component } from 'react'; |
||||
import { Link } from 'react-router-dom'; |
||||
import "slick-carousel/slick/slick.css"; |
||||
import "slick-carousel/slick/slick-theme.css"; |
||||
import Slider from "react-slick"; |
||||
import { Spin } from 'antd'; |
||||
import { Checkbox } from 'antd'; |
||||
import { LoadingOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; |
||||
import { |
||||
Button, |
||||
Card, |
||||
CardBody, |
||||
CardGroup, |
||||
Col, |
||||
Container, |
||||
Form, |
||||
Input, |
||||
InputGroup, |
||||
InputGroupAddon, |
||||
InputGroupText, |
||||
Row, |
||||
UncontrolledAlert, |
||||
Alert, |
||||
Carousel, |
||||
CarouselIndicators, |
||||
CarouselCaption, |
||||
CarouselItem, |
||||
CarouselControl |
||||
} from 'reactstrap'; |
||||
import { USER_LOGIN, USER_LOGIN_V2, CALERTUSER_SEARCH, MENU_MANAGEMENT, APP_MODE, ROLE_SEARCH } from '../../../const/ApiConst.js'; |
||||
import { appConfig, reloadConstants } from '../../../const/MapConst.js'; |
||||
import { APP_NAME } from '../../../const/AppConst.js' |
||||
import moment from "moment" |
||||
import axios from 'axios'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import logo_login_adw from '../../../assets/img/logo_adyawinsa.jpg' |
||||
import logo_login_kit from '../../../assets/img/logo_kit.png' |
||||
import logo_login_nawakara from '../../../assets/img/logo_nawakara.png' |
||||
import logo_login_si from '../../../assets/img/logo-surveyor-indonesia.png' |
||||
|
||||
|
||||
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />; |
||||
|
||||
const settings = { |
||||
dots: true, |
||||
infinite: true, |
||||
speed: 500, |
||||
arrows: false, |
||||
autoplay: true, |
||||
slidesToShow: 1, |
||||
slidesToScroll: 1 |
||||
}; |
||||
|
||||
class Login extends Component { |
||||
constructor(props) { |
||||
super(props); |
||||
this.state = { |
||||
name: '', |
||||
password: '', |
||||
remember: '', |
||||
alertVisible: false, |
||||
alertMessage: '', |
||||
alertColor: 'success', |
||||
validate: { |
||||
emailState: '', |
||||
}, |
||||
loader: false, |
||||
type: 'password', |
||||
defaultPage: '' |
||||
} |
||||
this.handleChange = this.handleChange.bind(this); |
||||
this.showHide = this.showHide.bind(this); |
||||
} |
||||
showHide(e) { |
||||
e.preventDefault(); |
||||
e.stopPropagation(); |
||||
this.setState({ |
||||
type: this.state.type === 'input' ? 'password' : 'input' |
||||
}) |
||||
} |
||||
validateEmail(e) { |
||||
const emailRex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; |
||||
const { validate } = this.state |
||||
if (emailRex.test(e.target.value)) { |
||||
validate.emailState = 'has-success' |
||||
} else { |
||||
validate.emailState = 'has-danger' |
||||
} |
||||
this.setState({ validate }) |
||||
} |
||||
|
||||
handleChange = async (event) => { |
||||
const { target } = event; |
||||
const value = target.type === 'checkbox' ? target.checked : target.value; |
||||
const { name } = target; |
||||
await this.setState({ |
||||
[name]: value, |
||||
}); |
||||
} |
||||
|
||||
getDataRole = async (token, role_id) => { |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "id", "logic_operator": "=", "value": `${role_id}`, "operator": "AND" } |
||||
], |
||||
"joins": [ |
||||
{ |
||||
"name": "m_menu", |
||||
"column_join": "default_page", |
||||
"column_results": ["id", "name", "url"], |
||||
}, |
||||
], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data |
||||
this.setState({defaultPage: resData[0].join_first_url}) |
||||
} |
||||
} |
||||
|
||||
getDataMenu = async (token, role_id) => { |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
let url = MENU_MANAGEMENT(role_id) |
||||
const result = await axios |
||||
.get(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data |
||||
window.localStorage.setItem('menu_login', JSON.stringify(resData)); |
||||
this.setState({ loader: false }) |
||||
// custom redirect home after login
|
||||
if (role_id == 28) { |
||||
this.props.history.push("/dashboard-customer/58/63"); |
||||
} |
||||
else { |
||||
this.props.history.push("/dashboard"); |
||||
} |
||||
if (this.state.defaultPage) { |
||||
this.props.history.push(this.state.defaultPage); |
||||
} else if (role_id == 28) { |
||||
this.props.history.push("/dashboard-customer/58/63"); |
||||
} |
||||
else { |
||||
this.props.history.push("/dashboard"); |
||||
} |
||||
} else { |
||||
NotificationManager.error('Login Failed', 'Failed'); |
||||
this.setState({ loader: false }) |
||||
} |
||||
} |
||||
|
||||
submitForm = (event) => { |
||||
event.preventDefault(); |
||||
this.submitFormLogin(); |
||||
} |
||||
|
||||
submitFormLogin = async () => { |
||||
this.setState({ loader: true }) |
||||
const { name, password, remember } = this.state |
||||
|
||||
if (name === '') { |
||||
NotificationManager.error('Please fill username', 'Login Failed!'); |
||||
this.setState({ loader: false }) |
||||
return false; |
||||
} |
||||
|
||||
if (password === '') { |
||||
NotificationManager.error('Please fill password', 'Login Failed!'); |
||||
this.setState({ loader: false }) |
||||
return false; |
||||
} |
||||
|
||||
let formData = { |
||||
username: name, |
||||
password, |
||||
remember, |
||||
} |
||||
|
||||
const doLogin = await axios.post(USER_LOGIN_V2, formData) |
||||
.then(response => response) |
||||
.catch(error => { |
||||
this.setState({ loader: false }); |
||||
}); |
||||
|
||||
if (doLogin && doLogin.data && doLogin.data.code === 200) { |
||||
const { access_token, data_user } = doLogin.data.data |
||||
this.getDataRole(access_token, data_user.role_id) |
||||
this.getDataMenu(access_token, data_user.role_id) |
||||
window.localStorage.setItem('isLogin', true); |
||||
window.localStorage.setItem('token', access_token); |
||||
window.localStorage.setItem('user_id', data_user.id); |
||||
window.localStorage.setItem('user_name', data_user.name); |
||||
window.localStorage.setItem('role_id', data_user.role_id); |
||||
} else { |
||||
console.log("kode : ", doLogin.data.code); |
||||
// NotificationManager.error('Cek username atau password anda!', 'Gagal Login!');
|
||||
NotificationManager.error(doLogin.data.message, 'Login Failed!'); |
||||
this.setState({ loader: false }); |
||||
} |
||||
|
||||
} |
||||
|
||||
getConfigAlert = async (token, user_id) => { |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "user_id", "logic_operator": "=", "value": `${user_id}`, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CALERTUSER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data |
||||
let configAlert = [] |
||||
resData.map((val, index) => { |
||||
configAlert.push(val.config_alert_id); |
||||
}); |
||||
window.localStorage.setItem('userConfigAlert', configAlert.join()); |
||||
} |
||||
} |
||||
|
||||
onShowAlert = (alertColor, alertMessage) => { |
||||
this.setState({ alertVisible: true, alertColor: alertColor, alertMessage: alertMessage }, () => { |
||||
window.setTimeout(() => { |
||||
this.setState({ alertVisible: false }) |
||||
}, 3000) |
||||
}); |
||||
} |
||||
|
||||
getLoginLogo = () => { |
||||
return <div style={{ textAlign: 'center' }}><img style={{ width: '100%' }} src={logo_login_adw} /></div> |
||||
} |
||||
|
||||
getLoginSlider = () => { |
||||
return <Slider {...settings} > |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide1.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide2.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide3.jpg')} className="img-avatar" /> |
||||
</div> |
||||
<div> |
||||
<img src={require('../../../assets/img/login/slide4.jpg')} className="img-avatar" /> |
||||
</div> |
||||
</Slider> |
||||
} |
||||
|
||||
onChecked = (e) => { |
||||
this.setState({ remember: e.target.checked }) |
||||
}; |
||||
|
||||
render() { |
||||
const { name, password, remember } = this.state; |
||||
const u_group = window.localStorage.getItem('u_group') |
||||
if (u_group !== null) { |
||||
this.props.history.push("/dashboard"); |
||||
} |
||||
return ( |
||||
<div className="app flex-row align-items-center"> |
||||
<Container> |
||||
<NotificationContainer /> |
||||
|
||||
<Alert color={this.state.alertColor} isOpen={this.state.alertVisible} > |
||||
{this.state.alertMessage} |
||||
</Alert> |
||||
<Row className="justify-content-center"> |
||||
<Col md="7"> |
||||
{this.getLoginSlider()} |
||||
</Col> |
||||
<Col md="5"> |
||||
<div style={{ |
||||
boxShadow: '1px 1px 11px 1px rgba(221,211,211,0.75)' |
||||
}}> |
||||
<CardGroup> |
||||
<Card className="p-4"> |
||||
<CardBody> |
||||
<Form onSubmit={this.submitForm}> |
||||
{this.getLoginLogo()} |
||||
<p className="text-muted">Sign In to your account</p> |
||||
<InputGroup className="mb-3"> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText> |
||||
<i className="icon-user"></i> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type="text" |
||||
name="name" |
||||
id="exampleName" |
||||
placeholder="Username" |
||||
value={name} |
||||
onChange={(e) => { |
||||
this.setState({ name: e.target.value }) |
||||
}} |
||||
/> |
||||
</InputGroup> |
||||
<InputGroup className="mb-4"> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText> |
||||
<i className="icon-lock"></i> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type={this.state.type} |
||||
name="password" |
||||
id="examplePassword" |
||||
placeholder="********" |
||||
value={password} |
||||
onChange={(e) => this.setState({ password: e.target.value })} |
||||
/> |
||||
<InputGroupAddon addonType="prepend"> |
||||
<InputGroupText |
||||
onClick={this.showHide} |
||||
> |
||||
{this.state.type === 'input' ? <EyeOutlined /> : <EyeInvisibleOutlined />} |
||||
|
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<span className="password__show" ></span> |
||||
</InputGroup> |
||||
<Row> |
||||
<Col xs="8"> |
||||
<Checkbox checked={this.state.remember} onChange={this.onChecked}>Remember me (7 days)</Checkbox> |
||||
</Col> |
||||
<Col xs="4"> |
||||
{this.state.loader ? ( |
||||
<Spin indicator={antIcon} /> |
||||
) : ( |
||||
<Button onClick={() => this.submitFormLogin()} color="primary" className="px-4" >Login</Button> |
||||
)} |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col className="text-right mt-5"> |
||||
<Button color="link" className="px-0">Forgot password?</Button> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
</CardBody> |
||||
</Card> |
||||
</CardGroup> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</Container> |
||||
</div> |
||||
); |
||||
} |
||||
} |
||||
|
||||
export default Login; |
||||
|
@ -0,0 +1,284 @@
|
||||
import React, {useState, useEffect} from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Card, CardHeader, CardBody } from 'reactstrap'; |
||||
import { TabContent, TabPane, Nav, NavItem, NavLink, Row, Col, Input } from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import axios from "../../../const/interceptorApi"; |
||||
import { |
||||
NotificationManager, |
||||
} from "react-notifications"; |
||||
import { BASE_SIMPRO_LUMEN } from "../../../const/ApiConst"; |
||||
import 'antd/dist/antd.css'; |
||||
import './style.css' |
||||
import { Select, Table } from 'antd'; |
||||
const { Option } = Select |
||||
|
||||
const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) => { |
||||
const token = localStorage.getItem("token"); |
||||
const [activeTab, setActiveTab] = useState('1'); |
||||
const [search, setSearch] = useState(''); |
||||
const [avgActivity, setAvgActivity] = useState(0); |
||||
const [dataTable, setDatatable] = useState([]); |
||||
const [dataTableActivityToHr, setDataTableActivityToHr] = useState([]); |
||||
const [hrList, setHrList] = useState([]); |
||||
const [selectedHr, setSelectedHr] = useState(null); |
||||
|
||||
const toggle = (tab) => { |
||||
if (activeTab !== tab) { |
||||
setActiveTab(tab); |
||||
} |
||||
}; |
||||
|
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
Authorization: `Bearer ${token}`, |
||||
}, |
||||
}; |
||||
|
||||
const columns = [ |
||||
{title: "Activity Name", dataIndex: "name", key: "name"} |
||||
] |
||||
|
||||
const columnActivityToHr = [ |
||||
{title: "Activity", dataIndex: "join_third_name", key: "join_third_name"}, |
||||
{title: "Human Resource", dataIndex: "join_second_name", key: "join_second_name"}, |
||||
{title: "Report Date", dataIndex: "report_date", key: "report_date"}, |
||||
{title: "Volume Actual", dataIndex: "qty", key: "qty"}, |
||||
{title: "Volume Planned", dataIndex: "join_first_qty_planning", key: "join_first_qty_planning"}, |
||||
{title: "Description", dataIndex: "description", key: "description"} |
||||
] |
||||
|
||||
useEffect(() => { |
||||
if (search) { |
||||
getDataActivity() |
||||
} |
||||
}, [search]); |
||||
|
||||
useEffect(() => { |
||||
if (selectedHr) { |
||||
getDataActivityToHr() |
||||
} |
||||
}, [selectedHr]); |
||||
|
||||
useEffect(() => { |
||||
getDataHr() |
||||
}, []); |
||||
|
||||
const handleSearch = (e) => { |
||||
const value = e.target.value; |
||||
setSearch(value); |
||||
}; |
||||
|
||||
const getDataHr = async () => { |
||||
const result = await axios |
||||
.get(`${BASE_SIMPRO_LUMEN}/human-resource/list`, HEADER) |
||||
.then((res) => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let dataRes = result.data.data || []; |
||||
setHrList(dataRes); |
||||
} else { |
||||
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
||||
} |
||||
} |
||||
const getDataActivityToHr = async () => { |
||||
setAvgActivity(0); |
||||
let sum = 0; |
||||
const payload = { |
||||
columns: [ |
||||
{ |
||||
name: "user_id", |
||||
logic_operator: "=", |
||||
value: selectedHr, |
||||
operator: "AND", |
||||
}, |
||||
{ |
||||
name: "proyek_id", |
||||
logic_operator: "=", |
||||
value: projectId, |
||||
table_name: "m_activity", |
||||
operator: "AND", |
||||
} |
||||
], |
||||
joins: [ |
||||
{ |
||||
name: "assign_material_to_activity", |
||||
column_join: "assign_material_id", |
||||
column_results: ["qty_planning"] |
||||
}, |
||||
{ |
||||
name: "m_users", |
||||
column_join: "user_id", |
||||
column_results: ["name"] |
||||
}, |
||||
{ |
||||
name: "m_activity", |
||||
column_join: "activity_id", |
||||
column_results: ["name", "persentase_progress"] |
||||
} |
||||
], |
||||
orders: { columns: ["id"], ascending: false }, |
||||
paging: { start: 0, length: -1 }, |
||||
}; |
||||
|
||||
const result = await axios |
||||
.post(`${BASE_SIMPRO_LUMEN}/report-activity-material/search`, payload, HEADER) |
||||
.then((res) => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let dataRes = result.data.data || []; |
||||
dataRes.forEach(element => { |
||||
element.join_third_persentase_progress ? sum += parseInt(element.join_third_persentase_progress) : sum += 0; |
||||
}); |
||||
setAvgActivity(sum / dataRes.length); |
||||
setDataTableActivityToHr(dataRes); |
||||
} else { |
||||
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
||||
} |
||||
}; |
||||
|
||||
const getDataActivity = async () => { |
||||
setAvgActivity(0); |
||||
let sum = 0; |
||||
const payload = { |
||||
columns: [ |
||||
{ |
||||
name: "name", |
||||
logic_operator: "ilike", |
||||
value: search, |
||||
operator: "AND", |
||||
}, |
||||
], |
||||
orders: { columns: ["id"], ascending: false }, |
||||
paging: { start: 0, length: -1 }, |
||||
}; |
||||
|
||||
const result = await axios |
||||
.post(`${BASE_SIMPRO_LUMEN}/activity/search`, payload, HEADER) |
||||
.then((res) => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let dataRes = result.data.data || []; |
||||
|
||||
dataRes.forEach(element => { |
||||
element.persentase_progress ? sum += parseInt(element.persentase_progress) : sum += 0; |
||||
}); |
||||
setAvgActivity(sum / dataRes.length); |
||||
setDatatable(dataRes); |
||||
} else { |
||||
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
||||
} |
||||
}; |
||||
return ( |
||||
<> |
||||
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>Project</ModalHeader> |
||||
<ModalBody> |
||||
<div> |
||||
<Nav tabs> |
||||
<NavItem> |
||||
<NavLink |
||||
className={activeTab === '1' ? "active" : null} |
||||
onClick={() => { |
||||
toggle('1'); |
||||
}} |
||||
> |
||||
Activity |
||||
</NavLink> |
||||
</NavItem> |
||||
<NavItem> |
||||
<NavLink |
||||
className={activeTab === '2' ? "active" : null} |
||||
onClick={() => { |
||||
toggle('2'); |
||||
}} |
||||
> |
||||
Human Resource |
||||
</NavLink> |
||||
</NavItem> |
||||
</Nav> |
||||
<TabContent activeTab={activeTab}> |
||||
<TabPane tabId="1"> |
||||
<Card> |
||||
<CardHeader> |
||||
<Row> |
||||
<Col> |
||||
<Input |
||||
onChange={handleSearch} |
||||
value={search} |
||||
type="text" |
||||
name="search" |
||||
id="search" |
||||
placeholder={`Search Activity Name`} |
||||
style={{ width: 200 }} |
||||
/> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<div style={{ textAlign: 'center' }}> |
||||
<h1> |
||||
{ |
||||
search && avgActivity ? `Activity ${search} adalah ${avgActivity.toFixed(2)} %` : null |
||||
} |
||||
</h1> |
||||
</div> |
||||
<Table |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTable} |
||||
pagination={false} |
||||
rowKey={"id"} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</TabPane> |
||||
<TabPane tabId="2"> |
||||
<Card> |
||||
<CardHeader> |
||||
<Row> |
||||
<Col> |
||||
<Select showSearch value={selectedHr} onChange={(val) => setSelectedHr(val)} placeholder="Select Human Resource" filterOption={(input, option) => |
||||
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 |
||||
} style={{ width: '100%' }}> |
||||
{hrList && hrList.map(res => ( |
||||
<Option key={res.id} value={res.id}>{`${res.name}`}</Option> |
||||
))} |
||||
</Select> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<div style={{ textAlign: 'center' }}> |
||||
<h1> |
||||
{ |
||||
selectedHr && avgActivity ? `Activity user ini adalah ${avgActivity.toFixed(2)} %` : null |
||||
} |
||||
</h1> |
||||
</div> |
||||
<Table |
||||
size="small" |
||||
columns={columnActivityToHr} |
||||
dataSource={dataTableActivityToHr} |
||||
pagination={false} |
||||
rowKey={"id"} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</TabPane> |
||||
</TabContent> |
||||
</div> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={closeDialog}>Close</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default ReportAnalysis; |
Loading…
Reference in new issue