Merge pull request 'update code' (#8) from feature/login-role into dev
Reviewed-on: huyt/fsi_project#8
This commit is contained in:
commit
37e162c802
BIN
app/public/img/logo.png
Normal file
BIN
app/public/img/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 458 B |
|
@ -34,7 +34,7 @@
|
|||
<!--RTL version:<link href="assets/vendors/base/vendors.bundle.rtl.css" rel="stylesheet" type="text/css" />-->
|
||||
<link href="%PUBLIC_URL%/assets/demo/demo9/base/style.bundle.css" rel="stylesheet" type="text/css" />
|
||||
<link rel="stylesheet" href="%PUBLIC_URL%/css/core.css">
|
||||
<title>FSI</title>
|
||||
<title>REVA - AI xử lý ảnh</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
|
|
@ -472,4 +472,41 @@ button.close:hover {
|
|||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-family: inherit !important;
|
||||
}
|
||||
|
||||
/* Scrollbar Modal DashBoard styles */
|
||||
.scroll::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 0px;
|
||||
}
|
||||
.scroll::-webkit-scrollbar-track {
|
||||
box-shadow: inset 0 0 10px #bdc3d4;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.scroll::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #9699a2c7;
|
||||
box-shadow: inset 0 0 6px #00000020;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.scroll_customer_daily {
|
||||
max-height: 700px;
|
||||
overflow-y: scroll;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.scroll_customer_daily:hover {
|
||||
overflow: overlay;
|
||||
}
|
||||
.scroll_customer_vip {
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.scroll_customer_vip:hover {
|
||||
overflow: overlay;
|
||||
}
|
||||
.scroll_staff {
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
padding-right: 8px;
|
||||
}
|
|
@ -3,11 +3,13 @@ import ListItem from './components/List/ListItem';
|
|||
import Login from './components/Login/Login';
|
||||
import LabelImage from './components/LabelImg/LabelImage';
|
||||
import SearchImage from './components/SearchImg/SearchImage';
|
||||
import Role from './components/Role/Role';
|
||||
import User from './components/User/User';
|
||||
import ImportImage from './components/ImportImg/ImportImage';
|
||||
import Test from './components/Test/Test';
|
||||
import MenuBar from './components/layouts/MenuBar'
|
||||
import Header from './components/layouts/Header'
|
||||
import Footer from './components/layouts/Footer'
|
||||
import 'antd/dist/antd.css';
|
||||
import "./App.css";
|
||||
import { Provider } from 'react-redux';
|
||||
|
@ -28,14 +30,15 @@ function App() {
|
|||
<Route exact path='/' component={SearchImage} />
|
||||
<Route path='/import-image' component={ImportImage} />
|
||||
<Route path='/user' component={User} />
|
||||
<Route path='/role' component={Role} />
|
||||
<Route path='/search-image' component={SearchImage} />
|
||||
<Route path='/label-image' component={LabelImage} />
|
||||
<Route path='/test' component={Test} />
|
||||
<Route path="/list-famous" component={ListItem} />
|
||||
</div>
|
||||
{/* <Footer/> */}
|
||||
</div>
|
||||
</Switch>
|
||||
|
||||
</Router>
|
||||
</Provider>
|
||||
);
|
||||
|
|
9
app/src/actions/boxai/index.js
Normal file
9
app/src/actions/boxai/index.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
export const SETBOX = 'SETBOX';
|
||||
export function setbox(id_company){
|
||||
return {
|
||||
type: SETBOX,
|
||||
payload:{
|
||||
id_company: id_company,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import { PulseLoader } from 'react-spinners';
|
|||
import { HOST } from '../../config/index';
|
||||
import swal from 'sweetalert';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const initialDataPost = {
|
||||
index: 1,
|
||||
|
@ -25,13 +26,18 @@ export default function LabelImage() {
|
|||
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const token = useSelector(state => state.isLogin.access_token);
|
||||
const role = useSelector(state => state.role);
|
||||
const idCompany = useSelector(state => state.boxai);
|
||||
|
||||
console.log(token)
|
||||
|
||||
const [activePage, setActivePage] = useState(1)
|
||||
const [totalItems, setTotalItems] = useState(0)
|
||||
|
||||
const [dataPost, setDataPost] = useState(initialDataPost)
|
||||
const itemsPerPage = 5
|
||||
|
||||
const [token, setToken] = useState('');
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
|
@ -43,8 +49,6 @@ export default function LabelImage() {
|
|||
let arr = value.split('=');
|
||||
obj[arr[0]] = arr[1]
|
||||
})
|
||||
setToken(decodeURIComponent(obj.token))
|
||||
setToken((obj.token))
|
||||
}
|
||||
}, [location])
|
||||
|
||||
|
@ -218,8 +222,10 @@ export default function LabelImage() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
{showModal && <ModalEditLabel data={dataEdit} onHide={onCloseModal} show={showModal} />}
|
||||
<div className="m-grid__item m-grid__item--fluid m-wrapper p-2" id="capture_form">
|
||||
<div className="m-content p-2">
|
||||
<div className="m-portlet m-portlet--mobile pb-3">
|
||||
<div className="m-portlet__head">
|
||||
<div className="m-portlet__head-caption">
|
||||
|
@ -329,6 +335,8 @@ export default function LabelImage() {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import { PulseLoader } from 'react-spinners';
|
|||
import { HOST } from '../../config/index';
|
||||
import swal from 'sweetalert';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const initialDataPost = {
|
||||
index: 1,
|
||||
|
@ -28,10 +29,11 @@ export default function ListItem() {
|
|||
const [activePage, setActivePage] = useState(1)
|
||||
const [totalItems, setTotalItems] = useState(0)
|
||||
|
||||
const token = useSelector(state => state.isLogin.access_token);
|
||||
|
||||
const [dataPost, setDataPost] = useState(initialDataPost)
|
||||
const itemsPerPage = 5
|
||||
|
||||
const [token, setToken] = useState('');
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
|
@ -43,8 +45,6 @@ export default function ListItem() {
|
|||
let arr = value.split('=');
|
||||
obj[arr[0]] = arr[1]
|
||||
})
|
||||
setToken(decodeURIComponent(obj.token))
|
||||
setToken((obj.token))
|
||||
}
|
||||
}, [location])
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ import $ from 'jquery';
|
|||
import { HOST } from '../../config';
|
||||
import Store from '../../store';
|
||||
import { login } from '../../actions/isLogin';
|
||||
|
||||
import { role } from '../../actions/role';
|
||||
import { setbox } from '../../actions/boxai';
|
||||
class Login extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -13,7 +14,7 @@ class Login extends Component {
|
|||
error: 0,
|
||||
loadingbtn: false,
|
||||
datalogin: {
|
||||
email: "",
|
||||
username: "",
|
||||
password: "",
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +39,7 @@ class Login extends Component {
|
|||
loadingbtn: false
|
||||
})
|
||||
} else {
|
||||
fetch(`${HOST}/api/login`, {
|
||||
fetch(`${HOST}/api/users/login`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
|
@ -57,14 +58,19 @@ class Login extends Component {
|
|||
return response.json()
|
||||
}).then((data) => {
|
||||
if (data.status === 10000) {
|
||||
console.log(data)
|
||||
console.log(data.data.roles)
|
||||
this.setState({
|
||||
error: 0,
|
||||
loadingbtn: false
|
||||
}, () => {
|
||||
Store.dispatch(role(data.data.roles));
|
||||
})
|
||||
localStorage.setItem("access_token", "Bearer " + data.access_token);
|
||||
Store.dispatch(login("Bearer " + data.access_token));
|
||||
localStorage.setItem("api_url", data.api_url);
|
||||
localStorage.setItem("api2_url", data.api2_url);
|
||||
Store.dispatch(setbox(data.data.company_id));
|
||||
localStorage.setItem("username", data.data.username);
|
||||
localStorage.setItem("obj_id", data.data._id);
|
||||
window.location.href = "/";
|
||||
// return;
|
||||
} else if (data.status === 10003) {
|
||||
|
@ -125,11 +131,11 @@ class Login extends Component {
|
|||
</div>
|
||||
<div className="login-form" id="formLogin">
|
||||
<label id="label_check" className={"form-check-label pb-2" + (this.state.error === 1 ? "" : " d-none")}>
|
||||
<div className="text-danger">* Sai email hoặc mật khẩu</div>
|
||||
<div className="text-danger">* Sai tên đăng nhập hoặc mật khẩu</div>
|
||||
</label>
|
||||
< div className="form-group">
|
||||
<label htmlFor="exampleInputEmail1" className="text-uppercase">Email</label>
|
||||
<input type="text" name="email" id="exampleInputEmail1" className="form-control" value={this.state.datalogin.email} placeholder="Nhập email..." required onKeyDown={this.onEnterPress} onChange={(e) => {
|
||||
<label htmlFor="exampleInputEmail1" className="text-uppercase">Tên đăng nhập</label>
|
||||
<input type="text" name="username" id="exampleInputEmail1" className="form-control" value={this.state.datalogin.username} placeholder="Nhập tên đăng nhập..." required onKeyDown={this.onEnterPress} onChange={(e) => {
|
||||
this.HandleLogin(e)
|
||||
}} />
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button, Modal } from 'react-bootstrap';
|
||||
import Switch from "react-switch";
|
||||
import swal from 'sweetalert';
|
||||
import $ from 'jquery';
|
||||
import Select from "react-select";
|
||||
import { HOST } from '../../config/index';
|
||||
class ModalRole extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
listStaff: [],
|
||||
listStaffDefault: [],
|
||||
listLicense: [],
|
||||
listCheckOperation: [],
|
||||
listRoleTemplate: [],
|
||||
crrRole: {
|
||||
name: "",
|
||||
active: 1,
|
||||
roles: [],
|
||||
id_company: "",
|
||||
is_default: 0,
|
||||
},
|
||||
isChecked: true,
|
||||
valueRoleTemplate: null,
|
||||
access_token_cloud: '',
|
||||
}
|
||||
}
|
||||
|
||||
// componentWillMount() {
|
||||
// var access_token_cloud = localStorage.getItem("access_token_cloud")
|
||||
// this.setState({
|
||||
// access_token_cloud: access_token_cloud,
|
||||
// })
|
||||
// }
|
||||
|
||||
updateRole = async (dataRole, event) => {
|
||||
console.log(dataRole)
|
||||
let dataPost = {
|
||||
is_default: 0,
|
||||
name: dataRole.name,
|
||||
roles: dataRole.roles,
|
||||
obj_id: this.state.crrRole.id ? this.state.crrRole.id : ""
|
||||
}
|
||||
dataRole.name.trim()
|
||||
var form = $("#formAddRole")
|
||||
if (form[0].checkValidity() === false) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
form.addClass('was-validated')
|
||||
} else {
|
||||
//Insert
|
||||
if (dataRole.roles.length > 0) {
|
||||
$('#button_addRole').addClass('m-loader');
|
||||
$('#button_addRole').attr('disabled', true);
|
||||
if (dataRole.id === undefined) {
|
||||
await fetch(`${HOST}/api/levels/insert_or_update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
body: JSON.stringify(dataPost)
|
||||
}).then((response) => {
|
||||
return response.json()
|
||||
}).then((data) => {
|
||||
if (data.status === 10000) {
|
||||
swal("Thành công", "Tạo mới thành công!", "success", {
|
||||
buttons: false,
|
||||
timer: 1500,
|
||||
});
|
||||
return this.props.onHide();
|
||||
} else if (data.status === 10001) {
|
||||
$('#button_addRole').removeClass('m-loader');
|
||||
$('#button_addRole').removeAttr('disabled', true);
|
||||
swal("Cảnh báo", "Tên quyền đã tồn tại", "warning");
|
||||
} else {
|
||||
$('#button_addRole').removeClass('m-loader');
|
||||
$('#button_addRole').removeAttr('disabled', true);
|
||||
swal("Lỗi", "Tạo mới thất bại!", "error");
|
||||
}
|
||||
}).catch((error) => {
|
||||
if (error) {
|
||||
$('#button_addRole').removeClass('m-loader');
|
||||
$('#button_addRole').removeAttr('disabled', true);
|
||||
swal("Lỗi", "Tạo mới thất bại!", "error");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//Update
|
||||
$('#button_addRole').addClass('m-loader');
|
||||
$('#button_addRole').attr('disabled', true);
|
||||
await fetch(`${HOST}/api/levels/insert_or_update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
body: JSON.stringify(dataPost)
|
||||
}).then((response) => {
|
||||
return response.json()
|
||||
}).then((data) => {
|
||||
if (data.status === 10000) {
|
||||
swal("Thành công", "Bạn đã sửa thành công!", "success", {
|
||||
buttons: false,
|
||||
timer: 1500,
|
||||
});
|
||||
return this.props.onHide();
|
||||
} else if (data.status === 10001) {
|
||||
$('#button_addRole').removeClass('m-loader');
|
||||
$('#button_addRole').removeAttr('disabled', true);
|
||||
swal("Cảnh báo", "Tên quyền đã tồn tại", "warning");
|
||||
} else {
|
||||
$('#button_addRole').removeClass('m-loader');
|
||||
$('#button_addRole').removeAttr('disabled', true);
|
||||
swal("Lỗi", "Sửa thất bại!", "error");
|
||||
}
|
||||
}).catch((error) => {
|
||||
if (error) {
|
||||
$('#button_addRole').removeClass('m-loader');
|
||||
$('#button_addRole').removeAttr('disabled', true);
|
||||
swal("Lỗi", "Sửa thất bại!", "error");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
} else {
|
||||
swal("Cảnh báo", "Bạn chưa chọn quyền", "warning");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RoleHandle(e) {
|
||||
var dataRole = this.state.crrRole;
|
||||
dataRole[e.target.name] = e.target.value;
|
||||
this.setState({ crrRole: dataRole });
|
||||
}
|
||||
|
||||
// handleChangeIsDefault(event) {
|
||||
// var dataRole = this.state.crrRole;
|
||||
// if (event.target.value == 0) {
|
||||
// dataRole['is_default'] = 1
|
||||
// } else {
|
||||
// dataRole['is_default'] = 0
|
||||
// }
|
||||
// this.setState({
|
||||
// crrRole: dataRole
|
||||
// })
|
||||
// }
|
||||
|
||||
// handleChangeRoleTemplate(value) {
|
||||
// var listCheckOperation = []
|
||||
// if (value.roles.length > 0) {
|
||||
// for (let index = 0; index < value.roles.length; index++) {
|
||||
// listCheckOperation.push(value.roles[index].code_operation)
|
||||
// }
|
||||
// }
|
||||
// var roles = this.state.crrRole;
|
||||
// roles['roles'] = listCheckOperation;
|
||||
// roles['name'] = value.label;
|
||||
// this.setState({
|
||||
// valueRoleTemplate: value,
|
||||
// crrRole: roles,
|
||||
// listCheckOperation: listCheckOperation,
|
||||
// listLicense: []
|
||||
// }, () => {
|
||||
// this.getLicense()
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
|
||||
getLicense = () => {
|
||||
fetch(`${HOST}/api/roles/company/1`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
}).then((response) => {
|
||||
return response.json()
|
||||
}).then((data) => {
|
||||
if (data.status === 10000) {
|
||||
this.setState({
|
||||
listLicense: data.data
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getRoleTemplate = (HOST) => {
|
||||
fetch(`${HOST}/api/roles/company/1`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
}).then((response) => {
|
||||
return response.json()
|
||||
}).then((data) => {
|
||||
if (data.status === 10000) {
|
||||
var optionRoleTemplate = [];
|
||||
if (data.data.length > 0) {
|
||||
for (let index = 0; index < data.data.length; index++) {
|
||||
optionRoleTemplate.push({ 'value': data.data[index].id, 'label': data.data[index].name, 'roles': data.data[index].roles })
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
optionRoleTemplate: optionRoleTemplate
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.show === true) {
|
||||
console.log(nextProps)
|
||||
//Staff
|
||||
var listCheckOperation = []
|
||||
console.log(nextProps.data)
|
||||
if (nextProps.data.roles.length > 0) {
|
||||
for (let index = 0; index < nextProps.data.roles.length; index++) {
|
||||
listCheckOperation.push(nextProps.data.roles[index])
|
||||
}
|
||||
}
|
||||
var crrRole = nextProps.data
|
||||
crrRole.roles = listCheckOperation
|
||||
|
||||
this.setState({
|
||||
crrRole: crrRole,
|
||||
listCheckOperation: listCheckOperation,
|
||||
valueRoleTemplate: null,
|
||||
}, () => {
|
||||
this.getLicense()
|
||||
// this.getRoleTemplate(nextProps.data.HOST)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleEnter = (event) => {
|
||||
if (event.keyCode === 13) {
|
||||
const form = event.target.form;
|
||||
const index = Array.prototype.indexOf.call(form, event.target);
|
||||
form.elements[index + 1].focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
handleCheckOperation = (event) => {
|
||||
const checkedArr = [];
|
||||
let value;
|
||||
if (event.target.type !== 'checkbox') {
|
||||
value = event.target.value;
|
||||
} else {
|
||||
const checkeds = document.getElementsByName('operation');
|
||||
for (let i = 0; i < checkeds.length; i++) {
|
||||
if (checkeds[i].checked) {
|
||||
checkedArr.push(checkeds[i].value);
|
||||
}
|
||||
}
|
||||
value = checkedArr;
|
||||
}
|
||||
var roles = this.state.crrRole;
|
||||
console.log(value)
|
||||
roles['roles'] = value;
|
||||
this.setState({
|
||||
crrRole: roles
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let click_handle = (event) => {
|
||||
this.updateRole(this.state.crrRole, event);
|
||||
}
|
||||
|
||||
const dataModule = this.state.listLicense.map((value, index) => {
|
||||
var lengthChecked = 0
|
||||
console.log(this.state.listCheckOperation)
|
||||
if (value !== null) {
|
||||
var checkboxOperation = value.operations.map((val, i) => {
|
||||
let codeOperation = val.split(':')
|
||||
if (this.state.listCheckOperation.indexOf(val) !== -1) {
|
||||
lengthChecked++
|
||||
}
|
||||
return (
|
||||
<label className="m-checkbox m-checkbox-day col-md-3 text_white_space pr-0" key={val}>
|
||||
<input type="checkbox" name="operation" defaultValue={val} onChange={e => this.handleCheckOperation(e)} defaultChecked={this.state.listCheckOperation.indexOf(val) === -1 ? false : true} /> {codeOperation[1]}
|
||||
<span />
|
||||
</label>
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="m-accordion__item" key={index}>
|
||||
<div className="m-accordion__item-head">
|
||||
<span className="m-accordion__item-title">{value.name}</span>
|
||||
{/* <span className="m-accordion__item-title">{value.module.code} --- {lengthChecked} / {value.module.operation.length}</span> */}
|
||||
{/* <span className="m-accordion__item-mode" /> */}
|
||||
</div>
|
||||
<div className="m-accordion__item-body collapse show">
|
||||
<div className="m-accordion__item-content">
|
||||
<div className="m-form__group form-group">
|
||||
<div className="m-checkbox-inline row m-0">
|
||||
{checkboxOperation}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
if (this.state.crrRole.active === 1) {
|
||||
this.state.isChecked = true
|
||||
} else {
|
||||
this.state.isChecked = false
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
{...this.props}
|
||||
size="lg"
|
||||
aria-labelledby="contained-modal-title-vcenter"
|
||||
>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title id="contained-modal-title-vcenter">
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<form id="formAddRole">
|
||||
<div className="col-xl-12">
|
||||
<div className="m-widget14">
|
||||
<div className="form-group m-form__group">
|
||||
<label htmlFor="Name">Tên <span className="text-danger"> *</span></label>
|
||||
<input className="form-control m-input" id="Name" name='name' value={this.state.crrRole.name === '' ? '' : this.state.crrRole.name} onKeyDown={(event) => this.handleEnter(event)} onChange={e => this.RoleHandle(e)} placeholder="Tên" required />
|
||||
</div>
|
||||
{/* <div className="form-group m-form__group ">
|
||||
<label>Trạng thái</label>
|
||||
<div className="pt-2 pb-2">
|
||||
<Switch
|
||||
onChange={() => {
|
||||
var active;
|
||||
if (!this.state.isChecked == true) {
|
||||
active = 1
|
||||
} else {
|
||||
active = 0
|
||||
}
|
||||
var crrRole = this.state.crrRole;
|
||||
crrRole['active'] = active;
|
||||
this.setState({
|
||||
crrRole: crrRole,
|
||||
isChecked: !this.state.isChecked
|
||||
});
|
||||
}}
|
||||
checked={this.state.isChecked}
|
||||
handleDiameter={17}
|
||||
offColor="#969696"
|
||||
onColor="#00c5dc"
|
||||
offHandleColor="#ffffff"
|
||||
onHandleColor="#08f"
|
||||
height={25}
|
||||
width={55}
|
||||
className="react-switch"
|
||||
id="small-radius-switch"
|
||||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="form-group m-form__group col-md-12 p-0 m-scrollable scroll scroll_customer_daily" style={{ 'height': '450px' }}>
|
||||
<div className="m-accordion m-accordion--bordered" id="m_accordion_2" role="tablist">
|
||||
{dataModule}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant="accent" id="button_addRole" className="m-loader--light m-loader--right" onClick={click_handle}>Lưu</Button>
|
||||
<Button variant="secondary" onClick={this.props.onHide}>Đóng</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ModalRole.propTypes = {
|
||||
data: PropTypes.object,
|
||||
liststaff: PropTypes.array,
|
||||
onHide: PropTypes.func.isRequired,
|
||||
show: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default ModalRole;
|
|
@ -19,6 +19,9 @@ const ModalUser = (props) => {
|
|||
|
||||
const [form] = Form.useForm()
|
||||
|
||||
const [listOptions, setListOption] = useState([])
|
||||
|
||||
|
||||
|
||||
const [birthday, setBirthday] = useState(moment())
|
||||
const [crrData, setCrrData] = useState(null);
|
||||
|
@ -40,39 +43,28 @@ const ModalUser = (props) => {
|
|||
|
||||
useEffect(() => {
|
||||
setCrrData(data);
|
||||
console.log(data)
|
||||
// setCrrImages(data.sample_images)
|
||||
// setBirthday(data.birthday !== "" ? moment(data.birthday) : null)
|
||||
// setDisableBtn(data._id ? false : true)
|
||||
// setHostImg(data.image_host)
|
||||
// return () => {
|
||||
// setCrrData(null);
|
||||
// }
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
getLevel()
|
||||
}, [])
|
||||
|
||||
// const handleCheckedImg = (event, value) => {
|
||||
// let newListChecked = { ...listChecked }
|
||||
// if (newListChecked.url.indexOf(event.target.value) === -1) {
|
||||
// newListChecked.url.push(event.target.value)
|
||||
// } else {
|
||||
// var i = newListChecked.url.indexOf(event.target.value);
|
||||
// if (i !== -1) {
|
||||
// newListChecked.url.splice(i, 1);
|
||||
// }
|
||||
// }
|
||||
// setListChecked(newListChecked)
|
||||
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// if (crrImages.length > 0) {
|
||||
// let crrDateImg = crrImages[crrIdx]
|
||||
// let getDateImg = crrDateImg !== "" && crrDateImg.split("_")
|
||||
// let dataImg = getDateImg.length > 0 && getDateImg[1].slice(0,6)
|
||||
// setDateImg(dataImg)
|
||||
// }
|
||||
// },[crrImages,crrIdx])
|
||||
const getLevel = async () => {
|
||||
let result = await axios.get(`${HOST}/api/levels/company/1`)
|
||||
if (result.data.status === 10000) {
|
||||
var listOptions = []
|
||||
for (let i = 0; i < result.data.data.length; i++) {
|
||||
const element = result.data.data[i];
|
||||
console.log(element.name)
|
||||
listOptions.push(<Option key={element._id}>{element.name}</Option>);
|
||||
}
|
||||
setListOption(listOptions)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const click_handle = async () => {
|
||||
let dataPost = {
|
||||
|
@ -84,7 +76,7 @@ const ModalUser = (props) => {
|
|||
birthday: crrData.birthday,
|
||||
gender: crrData?.gender ? crrData.gender : "",
|
||||
phone_number: crrData?.phone_number ? crrData?.phone_number : "",
|
||||
role_id_list: selectedRole
|
||||
level_obj_id: selectedRole
|
||||
}
|
||||
const result = await axios({
|
||||
method: 'POST',
|
||||
|
@ -105,6 +97,7 @@ const ModalUser = (props) => {
|
|||
timer: 1500,
|
||||
buttons: false,
|
||||
})
|
||||
onHide()
|
||||
} else {
|
||||
swal({
|
||||
icon: 'success',
|
||||
|
@ -140,10 +133,7 @@ const ModalUser = (props) => {
|
|||
setCrrData({ ...crrData, birthday: moment(date).format("YYYY-MM-DD") })
|
||||
}
|
||||
|
||||
const listOptions = [];
|
||||
for (let i = 10; i < 36; i++) {
|
||||
listOptions.push(<Option key={i.toString(36) + i + "key"}>{i.toString(36) + i + "value"}</Option>);
|
||||
}
|
||||
|
||||
|
||||
const handleChangeSelect = (value) => {
|
||||
setSelectedRole(value)
|
||||
|
@ -185,7 +175,7 @@ const ModalUser = (props) => {
|
|||
full_name: crrData?.full_name,
|
||||
gender: crrData?.gender,
|
||||
username: crrData?.username,
|
||||
role_id_list: crrData?.role_id_list,
|
||||
level_obj_id: crrData?.level_obj_id,
|
||||
phone_number: crrData?.phone_number
|
||||
}}
|
||||
>
|
||||
|
@ -196,8 +186,8 @@ const ModalUser = (props) => {
|
|||
required: true,
|
||||
message: ""
|
||||
},{
|
||||
pattern: /^(?=.{5,20}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+$/,
|
||||
message: 'Tên đăng nhập có độ dài từ 5-20 ký tự,không có khoảng trắng và ký tự đặc biệt',
|
||||
pattern: /^(?=.{3,20}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+$/,
|
||||
message: 'Tên đăng nhập có độ dài từ 3-20 ký tự,không có khoảng trắng và ký tự đặc biệt',
|
||||
}
|
||||
]}
|
||||
>
|
||||
|
@ -244,7 +234,7 @@ const ModalUser = (props) => {
|
|||
defaultValue={crrData?.birthday ? moment(birthday, 'DD-MM-YYYY') : null}
|
||||
format={'DD-MM-YYYY'}
|
||||
onChange={e => onChangeBirthday(e)}
|
||||
placeholder="Ngày sinh"
|
||||
placeholder="DD-MM-YYY"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
|
@ -257,12 +247,12 @@ const ModalUser = (props) => {
|
|||
|
||||
<Form.Item
|
||||
label="Quyền"
|
||||
name="role_id_list"
|
||||
name="level_obj_id"
|
||||
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
// mode="multiple"
|
||||
// allowClear
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Chọn quyền"
|
||||
defaultValue={[]}
|
||||
|
|
295
app/src/components/Role/Role.js
Normal file
295
app/src/components/Role/Role.js
Normal file
|
@ -0,0 +1,295 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import swal from 'sweetalert';
|
||||
import ModalRole from "../Modal/ModalRole";
|
||||
import { PulseLoader } from 'react-spinners';
|
||||
import Pagination from "react-js-pagination";
|
||||
import $ from 'jquery';
|
||||
import { HOST } from '../../config/index';
|
||||
|
||||
|
||||
class Role extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
modalRole: false,
|
||||
listRole: [],
|
||||
listStaff: [],
|
||||
crrDatas: [],
|
||||
activePage: 1,
|
||||
offset: 0,
|
||||
crrRole: {
|
||||
name: "",
|
||||
description: ""
|
||||
},
|
||||
};
|
||||
this.itemsPerPage = 10;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
|
||||
getData = () => {
|
||||
this.getRole()
|
||||
}
|
||||
|
||||
getRole = () => {
|
||||
fetch(`${HOST}/api/levels/company/1`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token
|
||||
},
|
||||
}).then((response) => {
|
||||
return response.json()
|
||||
}).then((data) => {
|
||||
if (data.status === 10000) {
|
||||
this.setState({
|
||||
listRole: data.data
|
||||
});
|
||||
this.FilterRole(this.state.activePage)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
FilterRole(activePage) {
|
||||
const { listRole } = this.state;
|
||||
const offset = (activePage - 1) * this.itemsPerPage;
|
||||
const crrDatas = listRole.slice(offset, offset + this.itemsPerPage);
|
||||
console.log(crrDatas)
|
||||
this.setState({
|
||||
crrDatas,
|
||||
offset: offset
|
||||
})
|
||||
}
|
||||
|
||||
handlePageChange = (pageNumber) => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
activePage: pageNumber
|
||||
})
|
||||
this.FilterRole(pageNumber);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
DeleteRole = async (Role) => {
|
||||
if (Role.is_default === 1) {
|
||||
swal("Cảnh báo", "Bạn không được xóa quyền mặc định", "warning");
|
||||
return;
|
||||
}
|
||||
let data = await fetch(`${HOST}/api/role/delete`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
// 'Authorization': token,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
'id': Role.id
|
||||
})
|
||||
}).then((response) => {
|
||||
return response.json()
|
||||
});
|
||||
if (data.status === 10000) {
|
||||
swal("Thành công", "Bạn đã xóa thành công!", "success", {
|
||||
buttons: false,
|
||||
timer: 1500,
|
||||
});
|
||||
this.getRole();
|
||||
}
|
||||
else {
|
||||
swal("Lỗi", "Xóa thất bại!", "error");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
modalClose = () => {
|
||||
this.setState({
|
||||
modalRole: false,
|
||||
});
|
||||
this.getRole();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.isLogin === false) {
|
||||
return (
|
||||
<Redirect to={'/login'} />
|
||||
)
|
||||
}
|
||||
|
||||
let bulletedRole = this.state.crrDatas.map((e, i) => {
|
||||
console.log(e)
|
||||
var is_default = ""
|
||||
if (e.is_default === 1) {
|
||||
is_default = " (Default)"
|
||||
}
|
||||
return (
|
||||
<tr key={(i + 1)}>
|
||||
<td>{(i + this.state.offset + 1)}</td>
|
||||
<td>{e.name}</td>
|
||||
<td>
|
||||
{
|
||||
e.active === 0
|
||||
?
|
||||
<span className="m-badge m-badge--secondary m-badge--wide">Inactive {is_default}</span>
|
||||
:
|
||||
<span className="m-badge m-badge--accent m-badge--wide">Active {is_default}</span>
|
||||
}
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<button onClick={(e) => {
|
||||
var data = this.state.crrDatas
|
||||
var dataRole = {
|
||||
id: data[i]._id,
|
||||
name: data[i].name,
|
||||
roles: data[i].roles,
|
||||
is_default: data[i].is_default,
|
||||
};
|
||||
this.setState({
|
||||
crrRole: dataRole,
|
||||
modalRole: true,
|
||||
});
|
||||
|
||||
|
||||
}} className="m-portlet__nav-link btn m-btn m-btn--hover-warning m-btn--icon m-btn--icon-only m-btn--pill" data-tip data-for='Edit'>
|
||||
<i className="la la-edit" />
|
||||
</button>
|
||||
{/* <ReactTooltip id='Edit' type='dark' effect='solid'>
|
||||
<span>{language[this.props.indexLanguage].tooltip.open_edit}</span>
|
||||
</ReactTooltip> */}
|
||||
|
||||
|
||||
<button className="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill" data-tip data-for='Delete'
|
||||
onClick={v => {
|
||||
v.preventDefault();
|
||||
swal({
|
||||
title: "Bạn có chắc chắn?",
|
||||
text: "Bạn có chắc chắn muốn xóa quyền" + e.name,
|
||||
icon: "warning",
|
||||
buttons: true,
|
||||
dangerMode: true,
|
||||
})
|
||||
.then(willDelete => {
|
||||
if (willDelete) {
|
||||
this.DeleteRole(e);
|
||||
}
|
||||
});
|
||||
|
||||
}}
|
||||
><i className="la la-trash"></i></button>
|
||||
{/* <ReactTooltip id='Delete' type='dark' effect='solid'>
|
||||
<span>{language[this.props.indexLanguage].tooltip.open_delete}</span>
|
||||
</ReactTooltip> */}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
});
|
||||
|
||||
var pageRangeDisplayed = 1;
|
||||
if ($(window).width() < 768) {
|
||||
pageRangeDisplayed = 3
|
||||
} else {
|
||||
pageRangeDisplayed = 5
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="m-grid__item m-grid__item--fluid m-wrapper">
|
||||
<div className="m-content p-2">
|
||||
<div className="m-portlet m-portlet--tab mb-0">
|
||||
<div className="m-portlet__head p-3">
|
||||
<div className="m-portlet__head-caption pl-3">
|
||||
<div className="m-portlet__head-title">
|
||||
<h3 className="m-portlet__head-text">
|
||||
Quyền
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-portlet__head-tools pr-3">
|
||||
<ul className="m-portlet__nav">
|
||||
<li className="m-portlet__nav-item">
|
||||
<button onClick={(e) => {
|
||||
this.setState({
|
||||
crrRole: {
|
||||
name: "",
|
||||
active: 1,
|
||||
// id_company: this.state.box_engine_cf.idCompany,
|
||||
roles: [],
|
||||
is_default: 0,
|
||||
HOST: this.state.crrApi2
|
||||
},
|
||||
modalRole: true,
|
||||
});
|
||||
}} className="btn btn-accent m-btn m-btn--custom m-btn--icon m-btn--pill m-btn--air">
|
||||
<span>
|
||||
<i className="la la-plus" />
|
||||
<span>Thêm mới</span>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-portlet__body m-portlet__body--no-padding">
|
||||
<div className="row m-row--no-padding m-row--col-separator-xl">
|
||||
<div className="col-xl-12">
|
||||
<div className="m-widget1 col-xl-8 mx-auto">
|
||||
<div className="table-responsive text-nowrap">
|
||||
<table className="table table-bordered table-hover table-checkable dataTable no-footer dtr-inline collapsed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ 'verticalAlign': 'middle', 'width': '100px' }}>STT</th>
|
||||
<th style={{ 'verticalAlign': 'middle' }}>Tên</th>
|
||||
<th style={{ 'verticalAlign': 'middle', 'width': '200px' }}>Trạng thái</th>
|
||||
<th style={{ 'verticalAlign': 'middle', 'width': '150px' }}>Thao tác</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{bulletedRole}
|
||||
</tbody>
|
||||
</table>
|
||||
{/* <PulseLoader
|
||||
css={override}
|
||||
sizeUnit={"px"}
|
||||
size={12}
|
||||
margin={'2px'}
|
||||
color={'#36D7B7'}
|
||||
loading={this.state.loading}
|
||||
/> */}
|
||||
|
||||
<ModalRole
|
||||
data={this.state.crrRole}
|
||||
show={this.state.modalRole}
|
||||
onHide={this.modalClose}
|
||||
/>
|
||||
</div>
|
||||
{/* <span>
|
||||
Showing {this.state.showFirst} to {this.state.showLast} of {this.state.totalLength} entries
|
||||
</span> */}
|
||||
<Pagination
|
||||
prevPageText='Trang trước'
|
||||
nextPageText='Trang sau'
|
||||
firstPageText='Trang đầu'
|
||||
lastPageText='Trang cuối'
|
||||
activePage={this.state.activePage}
|
||||
itemsCountPerPage={this.itemsPerPage}
|
||||
totalItemsCount={this.state.listRole.length}
|
||||
pageRangeDisplayed={pageRangeDisplayed}
|
||||
onChange={this.handlePageChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Role;
|
|
@ -9,6 +9,7 @@ import { PulseLoader } from 'react-spinners';
|
|||
import { HOST } from '../../config/index';
|
||||
import swal from 'sweetalert';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
|
||||
export default function Test() {
|
||||
|
@ -16,6 +17,9 @@ export default function Test() {
|
|||
const [text, setText] = useState("")
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const token = useSelector(state => state.isLogin.access_token);
|
||||
|
||||
|
||||
|
||||
const test = () => {
|
||||
setLoading(true)
|
||||
|
|
|
@ -12,6 +12,7 @@ import swal from 'sweetalert';
|
|||
import { useLocation } from 'react-router-dom';
|
||||
import Switch from "react-switch";
|
||||
import Select from "react-select";
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const initialDataPost = {
|
||||
index: 1,
|
||||
|
@ -27,6 +28,9 @@ export default function User() {
|
|||
const [showModalPassword, setShowModalPassword] = useState(false)
|
||||
const [dataEdit, setDataEdit] = useState(null)
|
||||
|
||||
const token = useSelector(state => state.isLogin.access_token);
|
||||
|
||||
|
||||
|
||||
const [optionSelect, setOptionSelect] = useState([
|
||||
{value: -1, label: "Tất cả"},
|
||||
|
@ -46,7 +50,6 @@ export default function User() {
|
|||
const [dataPost, setDataPost] = useState(initialDataPost)
|
||||
const itemsPerPage = 5
|
||||
|
||||
const [token, setToken] = useState('');
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
|
@ -58,8 +61,6 @@ export default function User() {
|
|||
let arr = value.split('=');
|
||||
obj[arr[0]] = arr[1]
|
||||
})
|
||||
setToken(decodeURIComponent(obj.token))
|
||||
setToken((obj.token))
|
||||
}
|
||||
}, [location])
|
||||
|
||||
|
@ -298,7 +299,7 @@ export default function User() {
|
|||
gender: "1",
|
||||
is_deleted: 0,
|
||||
phone_number: "",
|
||||
role_id_list: [],
|
||||
level_obj_id: [],
|
||||
username: ""
|
||||
}
|
||||
setDataEdit(defaultData)
|
||||
|
@ -331,7 +332,7 @@ export default function User() {
|
|||
value={dataPost.search_data}
|
||||
id="inputSearch"
|
||||
className="form-control m-input"
|
||||
placeholder="Tên đăng nhập..."
|
||||
placeholder="Tên đăng nhập/Họ tên..."
|
||||
data-col-index={0} />
|
||||
</div>
|
||||
<div className="form-group m-form__group col-xl-2">
|
||||
|
|
45
app/src/components/layouts/Footer.js
Normal file
45
app/src/components/layouts/Footer.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
import React, { Component } from 'react';
|
||||
import Store from '../../store';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
class Footer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
render() {
|
||||
|
||||
return (
|
||||
<footer className="m-grid__ite m-footer">
|
||||
<div className="m-container m-container--fluid m-container--full-height m-page__container">
|
||||
<div className="m-stack m-stack--flex-tablet-and-mobile m-stack--ver m-stack--desktop">
|
||||
<div className="m-stack__item m-stack__item--left m-stack__item--middle m-stack__item--last">
|
||||
<span className="m-footer__copyright">
|
||||
2019 © BeetInnovators
|
||||
</span>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--right m-stack__item--middle m-stack__item--first">
|
||||
<ul className="m-footer__nav m-nav m-nav--inline m--pull-right">
|
||||
<li className="m-nav__item">
|
||||
<a href="http://reva.com.vn" target="blank" className="m-nav__link">
|
||||
<span className="m-nav__link-text">Giới thiệu</span>
|
||||
</a>
|
||||
</li>
|
||||
<li className="m-nav__item">
|
||||
<a href="http://reva.com.vn#contact" target="blank" className="m-nav__link">
|
||||
<span className="m-nav__link-text">Trung tâm hỗ trợ</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(Footer);
|
|
@ -1,17 +1,45 @@
|
|||
import $ from 'jquery';
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
import Store from '../../store';
|
||||
import { HOST } from '../../config';
|
||||
class Header extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
username : localStorage.getItem('username'),
|
||||
obj_id : localStorage.getItem('obj_id'),
|
||||
isLogin: Store.getState().isLogin.isLogin,
|
||||
access_token: Store.getState().isLogin.access_token,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
this.getUser()
|
||||
}
|
||||
|
||||
getUser = () => {
|
||||
fetch(`${HOST}/api/users/${this.state.obj_id}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
return response.json()
|
||||
}).then(data => {
|
||||
if (data.status === 10000) {
|
||||
// Store.dispatch(setbox(data.data.company_id));
|
||||
console.log(data)
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onClickOpen = () => {
|
||||
$('#m_aside_left').addClass('m-aside-left--on')
|
||||
$('#body_form').addClass('m-aside-left--on')
|
||||
|
@ -42,9 +70,9 @@ class Header extends Component {
|
|||
<div className="m-stack__item m-brand m-brand--mobile">
|
||||
<div className="m-stack m-stack--ver m-stack--general">
|
||||
<div className="m-stack__item m-stack__item--middle m-brand__logo">
|
||||
{/* <a href="/dashboard" className="m-brand__logo-wrapper">
|
||||
<img alt="" src={this.state.logo_link} style={{ 'width': '160px' }} />
|
||||
</a> */}
|
||||
<a href="/" className="m-brand__logo-wrapper">
|
||||
<img src="/img/logo.png" alt="imglogo" className="col-xl-12 pl-0" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--middle m-brand__tools">
|
||||
{/* BEGIN: Responsive Aside Left Menu Toggler */}
|
||||
|
@ -61,77 +89,77 @@ class Header extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--left m-header-head" id="m_header_nav">
|
||||
<div className="m-stack m-stack--ver m-stack--desktop">
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--fit">
|
||||
<a className="m-aside-left-toggler m-aside-left-toggler--left m_aside_left_toggler" onClick={() => this.onClickOpen()}>
|
||||
<span />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--center" style={{ 'width': '160px' }}>
|
||||
<a href="/" className="m-brand m-brand--desktop">
|
||||
{/* <img alt="" src="/img/BI_Logo.png" className="logo_img" /> */}
|
||||
</a>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--right">
|
||||
<div id="m_header_topbar" className="m-topbar m-stack m-stack--ver m-stack--general width-100">
|
||||
<div className="m-stack__item m-topbar__nav-wrapper">
|
||||
<div className="m-stack m-stack--ver m-stack--desktop">
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--fit">
|
||||
<a className="m-aside-left-toggler m-aside-left-toggler--left m_aside_left_toggler" onClick={() => this.onClickOpen()}>
|
||||
<span />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--middle m-stack__item--center" style={{ 'width': '160px' }}>
|
||||
<a href="/" className="m-brand m-brand--desktop">
|
||||
<img alt="" src="/img/logo.png" className="logo_img" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="m-stack__item m-stack__item--right">
|
||||
<div id="m_header_topbar" className="m-topbar m-stack m-stack--ver m-stack--general width-100">
|
||||
<div className="m-stack__item m-topbar__nav-wrapper">
|
||||
|
||||
<ul className="m-topbar__nav m-nav m-nav--inline width-100 ml-0">
|
||||
<li className="m-nav__item m-topbar__user-profile m-topbar__user-profile--img">
|
||||
<div className="m-nav__link m-dropdown__toggle">
|
||||
<div className="row">
|
||||
{/* <div className="m-topbar__welcome" style={{ 'lineHeight': '50px','color':'#b1b1b5' }}>Company: </div> */}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="m-nav__item m-dropdown m-dropdown--medium m-dropdown--arrow m-dropdown--align-right m-dropdown--mobile-full-width m-dropdown--skin-light icon_logout" m-dropdown-toggle="click">
|
||||
<a href="#" className="m-nav__link m-dropdown__toggle">
|
||||
<span className="m-topbar__userpic">
|
||||
<img src="/img/photo-placeholder.png" className="m--img-rounded m--marginless m--img-centered" alt="" />
|
||||
</span>
|
||||
<span className="m-nav__link-icon m-topbar__usericon m--hide">
|
||||
<span className="m-nav__link-icon-wrapper"><i className="flaticon-user-ok" /></span>
|
||||
</span>
|
||||
</a>
|
||||
<div className="m-dropdown__wrapper">
|
||||
<span className="m-dropdown__arrow m-dropdown__arrow--right m-dropdown__arrow--adjust" />
|
||||
<div className="m-dropdown__inner">
|
||||
<div className="m-dropdown__header m--align-center">
|
||||
<div className="m-card-user m-card-user--skin-light">
|
||||
<div className="m-card-user__pic">
|
||||
<img src="/img/photo-placeholder.png" className="m--img-rounded m--marginless" alt="" />
|
||||
</div>
|
||||
{/* <div class="m-card-user__details">
|
||||
<span class="m-card-user__name m--font-weight-500">{this.state.user !== null && this.state.user.first_name + ' ' + this.state.user.last_name}</span>
|
||||
<a href="#/" class="m-card-user__email m--font-weight-300 m-link">{this.state.user !== null && this.state.user.email}</a>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-dropdown__body">
|
||||
<div className="m-dropdown__content">
|
||||
<ul className="m-nav m-nav--skin-light">
|
||||
<li className="m-nav__separator m-nav__separator--fit">
|
||||
</li>
|
||||
<li className="m-nav__item">
|
||||
<a className="btn m-btn--pill btn-secondary m-btn m-btn--custom m-btn--label-brand m-btn--bolder"
|
||||
// onClick={() => {
|
||||
// localStorage.removeItem("access_token");
|
||||
// window.location.href = "/login";
|
||||
// }}
|
||||
>Đăng Xuất</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="m-topbar__nav m-nav m-nav--inline width-100 ml-0">
|
||||
<li className="m-nav__item m-topbar__user-profile m-topbar__user-profile--img">
|
||||
<div className="m-nav__link m-dropdown__toggle">
|
||||
<div className="row">
|
||||
{/* <div className="m-topbar__welcome" style={{ 'lineHeight': '50px','color':'#b1b1b5' }}>Company: </div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className="m-nav__item m-dropdown m-dropdown--medium m-dropdown--arrow m-dropdown--align-right m-dropdown--mobile-full-width m-dropdown--skin-light icon_logout" m-dropdown-toggle="click">
|
||||
<a href="#" className="m-nav__link m-dropdown__toggle">
|
||||
<span className="m-topbar__userpic">
|
||||
<img src="/img/photo-placeholder.png" className="m--img-rounded m--marginless m--img-centered" alt="" />
|
||||
</span>
|
||||
<span className="m-nav__link-icon m-topbar__usericon m--hide">
|
||||
<span className="m-nav__link-icon-wrapper"><i className="flaticon-user-ok" /></span>
|
||||
</span>
|
||||
</a>
|
||||
<div className="m-dropdown__wrapper">
|
||||
<span className="m-dropdown__arrow m-dropdown__arrow--right m-dropdown__arrow--adjust" />
|
||||
<div className="m-dropdown__inner">
|
||||
<div className="m-dropdown__header m--align-center">
|
||||
<div className="m-card-user m-card-user--skin-light">
|
||||
<div className="m-card-user__pic">
|
||||
<img src="/img/photo-placeholder.png" className="m--img-rounded m--marginless" alt="" />
|
||||
</div>
|
||||
<div className="m-card-user__details">
|
||||
<span className="m-card-user__name m--font-weight-500">{this.state.username}</span>
|
||||
<div href="#/" className="m-card-user__email m--font-weight-300 m-link">{this.state.full_name}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-dropdown__body">
|
||||
<div className="m-dropdown__content">
|
||||
<ul className="m-nav m-nav--skin-light">
|
||||
<li className="m-nav__separator m-nav__separator--fit">
|
||||
</li>
|
||||
<li className="m-nav__item">
|
||||
<a className="btn m-btn--pill btn-secondary m-btn m-btn--custom m-btn--label-brand m-btn--bolder"
|
||||
onClick={() => {
|
||||
localStorage.removeItem("access_token");
|
||||
window.location.href = "/login";
|
||||
}}
|
||||
>Đăng Xuất</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
import React, { Component } from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import $ from 'jquery';
|
||||
|
||||
import Store from '../../store';
|
||||
|
||||
class MenuBar extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
type: '',
|
||||
dataRole: Store.getState().role,
|
||||
|
||||
}
|
||||
Store.subscribe(() => {
|
||||
this.setState({
|
||||
isLogin: Store.getState().isLogin.isLogin,
|
||||
dataRole: Store.getState().role,
|
||||
}, () => {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,7 +33,8 @@ class MenuBar extends Component {
|
|||
|
||||
render() {
|
||||
var active = '';
|
||||
|
||||
|
||||
console.log(this.state.dataRole)
|
||||
|
||||
return (
|
||||
<div id="m_aside_left" className="m-aside-left m-aside-left--skin-dark">
|
||||
|
|
15
app/src/reducers/boxai/index.js
Normal file
15
app/src/reducers/boxai/index.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { SETBOX } from '../../actions/boxai';
|
||||
|
||||
const initialState = {
|
||||
id_company: null,
|
||||
};
|
||||
export default function boxai(state = initialState, action) {
|
||||
switch(action.type){
|
||||
case SETBOX:
|
||||
return{
|
||||
id_company: action.payload.id_company,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import {combineReducers} from 'redux';
|
||||
import role from './role'
|
||||
import isLogin from './isLogin';
|
||||
import boxai from './boxai';
|
||||
export default combineReducers({
|
||||
role,
|
||||
isLogin
|
||||
isLogin,
|
||||
boxai,
|
||||
});
|
Loading…
Reference in New Issue
Block a user