import React, { Component } from 'react'; import { TextField, Divider, Typography, Checkbox, withStyles, Collapse, Snackbar } from '@material-ui/core'; import api from '../../../api'; import { titleCase } from '../../../library/Utils'; import Autocomplete from '@material-ui/lab/Autocomplete'; import { DatePicker } from '@material-ui/pickers'; import format from "date-fns/format"; import RemoveIcon from '@material-ui/icons/Remove'; import AddIcon from '@material-ui/icons/Add'; import * as R from 'ramda' import Images from '../../../assets/Images'; import MuiAlert from '@material-ui/lab/Alert'; const CustomCheckbox = withStyles({ root: { color: '#51c6ea', '&$checked': { color: '#51c6ea', }, }, checked: {}, })((props) => <Checkbox color="default" {...props} />); const CustomCheckboxDisabled = withStyles({ root: { color: '#d5d5d5', '&$checked': { color: '#d5d5d5', }, }, checked: {}, })((props) => <Checkbox color="default" {...props} />); const Alert = withStyles({ })((props) => <MuiAlert elevation={6} variant="filled" {...props} />); export default class EditUser extends Component { constructor(props) { super(props) this.state = { paramsId: this.props.data, tempData: null, menuData: null, checked: false, listRole: null, role: null, company: [], listCompany: [], selectedIndex: 0, errorFullname: false, errorEmail: false, errorRoleName: false, errorStartDate: false, errorEndDate: false, msgErrorFN: '', msgErrorEM: '', msgErrorRN: '', msgErrorSD: '', msgErrorED: '', alert: false, tipeAlert: '', messageAlert: '' } } handleChecked() { this.setState({ checked: !this.state.checked }) } componentDidMount() { this.getDetailUser() this.getPerusahaan() } handleChange(e, type) { let data = this.state let isDate = type !== '' ? true : false if (isDate && type === 'start_date') { this.setState({ ...data, tempData: { ...this.state.tempData, start_date: format(e, 'yyyy-MM-dd'), end_date: null }, errorFullname: false, errorEmail: false, errorRoleName: false, errorStartDate: false, errorEndDate: false, msgErrorFN: '', msgErrorEM: '', msgErrorRN: '', msgErrorSD: '', msgErrorED: '', }) } else if (isDate && type === 'end_date') { this.setState({ ...data, tempData: { ...this.state.tempData, end_date: format(e, 'yyyy-MM-dd') }, errorFullname: false, errorEmail: false, errorRoleName: false, errorStartDate: false, errorEndDate: false, msgErrorFN: '', msgErrorEM: '', msgErrorRN: '', msgErrorSD: '', msgErrorED: '', }) } else { this.setState({ ...data, tempData: { ...this.state.tempData, [e.target.name]: e.target.value }, errorFullname: false, errorEmail: false, errorRoleName: false, errorStartDate: false, errorEndDate: false, msgErrorFN: '', msgErrorEM: '', msgErrorRN: '', msgErrorSD: '', msgErrorED: '', }) } } clearError() { this.setState({ errorFullname: false, errorEmail: false, errorRoleName: false, errorStartDate: false, errorEndDate: false, msgErrorFN: '', msgErrorEM: '', msgErrorRN: '', msgErrorSD: '', msgErrorED: '', }) } getDetailUser() { api.create().getDetailUser(this.state.paramsId).then((response) => { this.getRole() if (response.data) { if (response.ok) { if (response.data.status === 'success') { this.setState({ tempData: response.data.data, company: response.data.data.company }) console.log(response.data.data) } else { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'warning' }) } } else { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'error' }) } } else { this.setState({ alert: true, messageAlert: response.problem, tipeAlert: 'error' }) } }) } isEmail(email) { const re = /^(([^<>()\[\]\\.,;:\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,}))$/; return re.test(String(email).toLowerCase()); } validasi() { var isEmail = this.isEmail(this.state.tempData.email) // console.log(this.state.tempData) if (R.isEmpty(this.state.tempData.fullname)) { this.setState({ errorFullname: true, msgErrorFN: 'Full Name Cannot be Empty' }) } else if (R.isEmpty(this.state.tempData.email)) { this.setState({ errorEmail: true, msgErrorEM: 'Email Cannot be Empty' }) } else if (!isEmail) { this.setState({ errorEmail: true, msgErrorEM: 'Email format not recognized!' }) } else if (R.isNil(this.state.role)) { this.setState({ errorRoleName: true, msgErrorRN: 'Role Name Cannot be Empty' }) } else if (R.isNil(this.state.tempData.start_date)) { this.setState({ errorStartDate: true, msgErrorSD: 'Start Date Cannot be Empty' }) } else if (R.isNil(this.state.tempData.end_date)) { this.setState({ errorEndDate: true, msgErrorED: 'End Date Cannot be Empty' }) } // else if (this.state.privileges.length < 1) { // alert('Hak Akses belum di pilih !!') // } else { this.updateUser() } } updateUser(){ let payload = { "user_id": this.state.tempData.user_id, "role_id": this.state.role.role_id, "email": this.state.tempData.email, "fullname": this.state.tempData.fullname, "company": this.state.company, "start_date": this.state.tempData.start_date, "end_date": this.state.tempData.end_date } this.props.updateUser(payload) } getRole() { api.create().getRoleActive().then((response) => { if (response.data) { if (response.ok) { if (response.data.status === 'success') { let data = response.data.data let roleData = data.map((item) => { return { role_id: item.role_id, role_name: item.role_name } }) let defaultProps = { options: roleData, getOptionLabel: (option) => titleCase(option.role_name), }; let index = roleData.findIndex((val) => val.role_id === this.state.tempData.role_id) this.setState({ listRole: defaultProps, role: index === -1 ? roleData[0] : roleData[index] }) } else { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'warning' }) } } else { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'error' }) } } else { this.setState({ alert: true, messageAlert: response.problem, tipeAlert: 'error' }) } }) } getPerusahaan() { api.create().getPerusahaanHierarki().then((response) => { if (response.data) { if (response.ok) { if (response.data.status === 'success') { this.setState({ listCompany: response.data.data }) } else { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'warning' }) } } else { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'error' }) } } else { this.setState({ alert: true, messageAlert: response.problem, tipeAlert: 'error' }) } }) } handleItemChecked(item) { let indexID = this.state.company.findIndex((val) => val === item.id) return indexID === -1 ? false : true } handleItemClick(item) { let indexID = this.state.company.findIndex((val) => val === item.id) let company = this.state.company if (indexID === -1) { company.push(item.id) if (item.parent !== null) { let indexIDs = this.state.company.findIndex((val) => val === item.parent) if (indexIDs === -1) { company.push(item.parent) } } if (item.children !== null) { if (item.children.length > 0) { item.children.map((items,indexs) => { this.handleItemClick(items) }) } } } else { company.splice(indexID, 1) if (item.parent !== null) { let indexIDs = this.state.company.findIndex((val) => val === item.parent) if (indexIDs !== -1) { company.splice(indexIDs, 1) } } if (item.children !== null) { if (item.children.length > 0) { item.children.map((items,indexs) => { this.handleItemClick(items) }) } } } this.setState({ company }) } renderChildren = (item, pad) => { let padding = null if (pad !== undefined) { padding = pad } else { padding = 30 } return ( <div> {item.children.length > 0 && ( <ul> {item.children.map((data, index) => { return ( // <li> <Collapse key={index} timeout="auto" unmountOnExit in={item.collapse}> <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', paddingLeft: !R.isNil(data.children)? (data.children.length > 0? padding : padding + 30) : padding + 30}}> {R.isNil(data.children) ? null : data.children.length < 1 ? null : <span onClick={() => this.handleCollapse(data)} style={{ marginLeft: 7, marginRight: 2 }}> {data.collapse ? <RemoveIcon color={'action'} fontSize={'small'} /> : <AddIcon color={'action'} fontSize={'small'} />} </span> } <span> {this.state.role ? this.state.role.role_id === 1 ? <CustomCheckboxDisabled disabled={true} checked={true} // onChange={() => this.handleItemClick(item)} /> : <CustomCheckbox checked={this.handleItemChecked(data)} onChange={() => this.handleItemClick(data)} /> : <CustomCheckbox checked={this.handleItemChecked(data)} onChange={() => this.handleItemClick(data)} /> } </span> <Typography style={{ fontSize: 12 }}>{titleCase(data.company_name)}</Typography> </div> {!R.isNil(data.children) && this.renderChildren(data, padding + 30)} </Collapse> // </li> ) })} </ul> )} </div> ) } handleCollapse(item) { let path = this.searchIt({ children: this.state.listCompany }, item.id) let listCompany = this.state.listCompany let arrayPath = [] if (path.length > 1) { arrayPath = path.split('-'); arrayPath = arrayPath.map((item) => { return item }) } else { arrayPath.push(path) } let pathSelect = null if (arrayPath.length == 1) { pathSelect = listCompany[arrayPath[0]] } else if (arrayPath.length == 2) { pathSelect = listCompany[arrayPath[0]].children[arrayPath[1]] } else if (arrayPath.length == 3) { pathSelect = listCompany[arrayPath[0]].children[arrayPath[1]].children[arrayPath[2]] } else if (arrayPath.length == 4) { pathSelect = listCompany[arrayPath[0]].children[arrayPath[1]].children[arrayPath[2]].children[arrayPath[3]] } else if (arrayPath.length == 5) { pathSelect = listCompany[arrayPath[0]].children[arrayPath[1]].children[arrayPath[2]].children[arrayPath[3]].children[arrayPath[4]] } else if (arrayPath.length == 6) { pathSelect = listCompany[arrayPath[0]].children[arrayPath[1]].children[arrayPath[2]].children[arrayPath[3]].children[arrayPath[4]].children[arrayPath[5]] } else if (arrayPath.length == 7) { pathSelect = listCompany[arrayPath[0]].children[arrayPath[1]].children[arrayPath[2]].children[arrayPath[3]].children[arrayPath[4]].children[arrayPath[5]].children[arrayPath[6]] } pathSelect.collapse = !pathSelect.collapse // console.log(pathSelect.collapse) this.setState({ listCompany }, () => console.log(pathSelect)) } searchIt = (node, search, path = '', position = 0) => { if (node.id && node.id === search) { return path !== '' ? `${path}-${position}` : position; } if (!node.children) { return false } const index = node.children.findIndex((x) => x.id && x.id === search); if (index >= 0) { return path !== '' ? `${path}-${index}` : index; } for (let i = 0; i < node.children.length; i++) { const result = this.searchIt(node.children[i], search, path !== '' ? `${path}-${i}` : i, i); if (result) { return result; } } return false; }; closeAlert() { this.setState({ alert: false }) } render() { return ( <div className="test app-popup-show"> <Snackbar open={this.state.alert} autoHideDuration={6000} onClose={() => this.closeAlert()}> <Alert onClose={() => this.closeAlert()} severity={this.state.tipeAlert}> {this.state.messageAlert} </Alert> </Snackbar> <div className="popup-content background-white border-radius" style={{ borderRadius: 8 }}> <div className="popup-panel grid grid-2x main-color" style={{ height: 64, borderTopRightRadius: 8, borderTopLeftRadius: 8 }}> <div className="col-1" style={{ maxWidth: "inherit", display: 'flex', alignItems: 'center' }}> <div className="popup-title"> <span style={{ color: '#fff', fontSize: 16, fontWeight: 'bold' }}>Edit Data</span> </div> </div> <div className="col-2 content-right" style={{ maxWidth: "inherit", alignSelf: 'center' }}> <button type="button" className="btn btn-circle btn-white" onClick={() => this.props.onClickClose()} > <img src={Images.close} /> </button> </div> </div> <div className="grid grid-2x grid-mobile-none gap-15px" style={{ padding: 20 }}> <div className="column-1"> <div className=""> <TextField style={{ width: '100%' }} id="id" label="ID" disabled // id="outlined-read-only-input" variant="filled" value={this.state.tempData === null ? '' : this.state.tempData.user_id} onChange={(e) => null} inputProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', } }} InputLabelProps={{ style: { fontSize: 11, color: '#7e8085', fontFamily: 'Nunito Sans, sans-serif', } }} > {/* {periode.map((option) => ( <MenuItem key={option.value} value={option.value}> {option.label} </MenuItem> ))} */} </TextField> </div> </div> <div className="column-2"> <div className=""> <TextField style={{ width: '100%', marginTop: 7 }} id="fullname" name="fullname" label="Full Name" value={this.state.tempData === null ? '' : this.state.tempData.fullname} onChange={(e) => this.handleChange(e, '')} // defaultValue="Default Value" error={this.state.errorFullname} helperText={this.state.msgErrorFN} inputProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', } }} InputLabelProps={{ style: { fontSize: 11, color: '#7e8085', fontFamily: 'Nunito Sans, sans-serif', } }} /> </div> </div> </div> <div className="grid grid-2x grid-mobile-none gap-15px" style={{ paddingLeft: 20, paddingRight: 20 }}> <div className="column-1"> <div className="margin-bottom-20px"> <TextField style={{ width: '100%', marginTop: 7 }} id="email" name="email" label="Email" value={this.state.tempData === null ? '' : this.state.tempData.email} onChange={(e) => this.handleChange(e, '')} error={this.state.errorEmail} helperText={this.state.msgErrorEM} inputProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', } }} InputLabelProps={{ style: { fontSize: 11, color: '#7e8085', fontFamily: 'Nunito Sans, sans-serif', } }} /> </div> </div> <div className="column-2"> <div className="margin-bottom-20px"> <Autocomplete {...this.state.listRole} id="role" onChange={(event, newInputValue) => this.setState({ role: newInputValue }, ()=> this.clearError())} debug renderInput={(params) => <TextField {...params} label="Role" margin="normal" style={{ marginTop: 7 }} onChange={(e) => this.handleChange(e, '')} error={this.state.errorRoleName} helperText={this.state.msgErrorRN} InputLabelProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', color: '#7e8085' } }} InputProps={{ ...params.InputProps, style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif' } }} />} value={this.state.role} /> </div> </div> </div> <div className="grid grid-2x grid-mobile-none gap-15px" style={{ paddingLeft: 20, paddingRight: 20 }}> <div className="column-1"> <div className="margin-bottom-20px"> <DatePicker margin="normal" id="startDate" label="Start Date" format="dd MMMM yyyy" value={this.state.tempData === null ? null : this.state.tempData.start_date} error={this.state.errorStartDate} helperText={this.state.msgErrorSD} onChange={(e) => this.handleChange(e, 'start_date')} KeyboardButtonProps={{ 'aria-label': 'change date', }} inputProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', } }} InputLabelProps={{ style: { fontSize: 11, color: '#7e8085', fontFamily: 'Nunito Sans, sans-serif', } }} style={{ padding: 0, margin: 0, width: '100%' }} /> </div> </div> <div className="column-2"> <div className="margin-bottom-20px"> <DatePicker margin="normal" id="endDate" label="End Date" format="dd MMMM yyyy" value={this.state.tempData === null ? null : this.state.tempData.end_date} error={this.state.errorEndDate} helperText={this.state.msgErrorED} minDate={this.state.tempData === null ? null : this.state.tempData.start_date} onChange={(e) => this.handleChange(e, 'end_date')} KeyboardButtonProps={{ 'aria-label': 'change date', }} inputProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', } }} InputLabelProps={{ style: { fontSize: 11, color: '#7e8085', fontFamily: 'Nunito Sans, sans-serif', } }} style={{ padding: 0, margin: 0, width: '100%' }} /> </div> </div> </div> <div className="grid grid-2x grid-mobile-none gap-15px" style={{ paddingLeft: 20, paddingRight: 20 }}> <div className="column-1"> <div className="margin-bottom-20px"> <TextField style={{ width: '100%' }} id="status" label="Status" disabled // id="outlined-read-only-input" variant="filled" value={this.state.tempData === null ? '' : this.state.tempData.status} inputProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', } }} InputLabelProps={{ style: { fontSize: 11, color: '#7e8085', fontFamily: 'Nunito Sans, sans-serif', } }} > {/* {periode.map((option) => ( <MenuItem key={option.value} value={option.value}> {option.label} </MenuItem> ))} */} </TextField> </div> </div> <div className="column-2"> <div className="margin-bottom-20px"> <TextField style={{ width: '100%' }} id="is_expired" name="is_expired" label="Expired" disabled // id="outlined-read-only-input" variant="filled" value={this.state.tempData === null ? '' : this.state.tempData.is_expired} inputProps={{ style: { fontSize: 11, fontFamily: 'Nunito Sans, sans-serif', } }} InputLabelProps={{ style: { fontSize: 11, color: '#7e8085', fontFamily: 'Nunito Sans, sans-serif', } }} > {/* {periode.map((option) => ( <MenuItem key={option.value} value={option.value}> {option.label} </MenuItem> ))} */} </TextField> </div> </div> </div> <div style={{ flexDirection: 'column', display: 'flex', paddingLeft: 20, paddingRight: 20 }}> <Typography style={{ fontSize: 11 }}>{`Created By : ${this.state.tempData === null ? '' : this.state.tempData.created}`}</Typography> <Typography style={{ fontSize: 11 }}>{`Updated By : ${this.state.tempData === null ? '' : this.state.tempData.updated}`}</Typography> </div> <Divider style={{ margin: 20 }} /> <div style={{ paddingLeft: 20, paddingRight: 20 }}> <h5>Authorization Company</h5> <div style={{ paddingLeft: 10, overflow: 'scroll', height: '25vh' }}> {this.state.listCompany.map((item, index) => { return ( <div> {/* <ul> <li> */} <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start' }}> {item.children.length > 0 && <span onClick={() => this.handleCollapse(item)} style={{ marginLeft: 7, marginRight: 2 }}> {item.collapse ? <RemoveIcon color={'action'} fontSize={'small'} /> : <AddIcon color={'action'} fontSize={'small'} />} </span>} <span> {this.state.role ? this.state.role.role_id === 1 ? <CustomCheckboxDisabled disabled={true} checked={true} // onChange={() => this.handleItemClick(item)} /> : <CustomCheckbox checked={this.handleItemChecked(item)} onChange={() => this.handleItemClick(item)} /> : <CustomCheckbox checked={this.handleItemChecked(item)} onChange={() => this.handleItemClick(item)} /> } </span> <Typography style={{ fontSize: 12 }}>{titleCase(item.company_name)}</Typography> </div> {!R.isNil(item.children) && this.renderChildren(item)} {/* </li> </ul> */} </div> ) })} </div> </div> <div className="border-top grid grid-2x" style={{ height: 56, backgroundColor: '#f5f5f5', paddingLeft: 20, paddingRight: 20 }}> <div className="column-1" style={{ alignSelf: 'center' }}> <button onClick={() => this.props.onClickClose()}> <div style={{ width: 102, height: 30, border: 'solid 1px #354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center' }}> <span style={{ color: '#354960', fontSize: 11 }}>Cancel</span> </div> </button> </div> <div className="column-2" style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}> <button onClick={() => this.validasi()}> <div style={{ width: 102, height: 30, backgroundColor: '#354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center' }}> <span style={{ color: '#fff', fontSize: 11 }}>Save</span> </div> </button> </div> </div> </div> </div> ); } }