558 lines
17 KiB
JavaScript
558 lines
17 KiB
JavaScript
import React from "react";
|
||
import Head from 'next/head';
|
||
import Image from 'next/image';
|
||
import Link from "next/link";
|
||
import cookie from 'cookie';
|
||
import { connect } from "react-redux";
|
||
import numeral from "numeral";
|
||
import pluralize from 'pluralize-ru';
|
||
import { SpinnerCircular } from 'spinners-react';
|
||
|
||
import { withRouter } from 'next/router';
|
||
import { reduxWrapper } from '../../store';
|
||
|
||
import InnerMenu from "./components/InnerMenu";
|
||
import Header from '../components/Header';
|
||
import Footer from '../components/Footer';
|
||
import Pagination from '../components/Pagination';
|
||
import Company from "../components/Company";
|
||
|
||
import { getUsers, removeUser, sendInvite, sendPhoneChangeNumber, sendPhoneChangeNumberSmsCode, setUserPhone } from '../../actions';
|
||
import AccountLayout from "../components/Layout/Account";
|
||
|
||
class Form extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
name: "",
|
||
email: "",
|
||
selection: false,
|
||
selected_companies_all: false,
|
||
selected_companies_list: [],
|
||
};
|
||
}
|
||
|
||
componentDidMount()
|
||
{
|
||
const { errors } = this.props;
|
||
|
||
if(errors.length > 0)
|
||
{
|
||
const update = { ...this.state, ...this.props.form };
|
||
this.setState(update);
|
||
}
|
||
}
|
||
|
||
_handle_onChange = (field, value) =>
|
||
{
|
||
this.setState({ [ field ]: value }, () =>
|
||
{
|
||
this.props.onForm(this.state);
|
||
});
|
||
}
|
||
|
||
_handle_onCompaniesSelection = () =>
|
||
{
|
||
this.setState({ selection: this.state.selection ? false : true }, () =>
|
||
{
|
||
this.props.onForm(this.state);
|
||
});
|
||
}
|
||
|
||
_handle_onChangeCompanies_all = () =>
|
||
{
|
||
const { companies } = this.props;
|
||
const { selected_companies_all, selected_companies_list } = this.state;
|
||
|
||
const all = selected_companies_all ? false : true;
|
||
const selected_companies = [];
|
||
|
||
if(all)
|
||
{
|
||
for(let i in companies)
|
||
{
|
||
selected_companies.push(companies[i]);
|
||
}
|
||
}
|
||
|
||
this.setState({ selected_companies_all: selected_companies_all ? false : true, selected_companies_list: selected_companies }, () =>
|
||
{
|
||
this.props.onForm(this.state);
|
||
});
|
||
}
|
||
|
||
_handle_onCompanySelect = (company) =>
|
||
{
|
||
const { companies } = this.props;
|
||
const { selected_companies_list } = this.state;
|
||
const selected_companies = [];
|
||
|
||
let add = true;
|
||
for(let i in selected_companies_list)
|
||
{
|
||
if(selected_companies_list[i].inn !== company.inn)
|
||
{
|
||
selected_companies.push(selected_companies_list[i]);
|
||
}
|
||
else
|
||
{
|
||
add = false;
|
||
}
|
||
}
|
||
if(add)
|
||
{
|
||
selected_companies.push(company);
|
||
}
|
||
|
||
let all = false;
|
||
if(companies.length === selected_companies.length)
|
||
{
|
||
all = true;
|
||
}
|
||
|
||
this.setState({ selected_companies_all: all, selected_companies_list: selected_companies }, () =>
|
||
{
|
||
this.props.onForm(this.state);
|
||
});
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { companies, errors } = this.props;
|
||
const { name, email, selection, selected_companies_all, selected_companies_list, } = this.state;
|
||
|
||
return (
|
||
<>
|
||
<div className="table_cell" data-title="ФИО пользователя">
|
||
<input type="text" placeholder="Введите ФИО" value={ name } style={ errors.indexOf("name") > -1 ? { color: "#ED0A34" } : {} } onChange={ (event) => { this._handle_onChange("name", event.target.value) } }/>
|
||
</div>
|
||
<div className="table_cell" data-title="Почта">
|
||
<input type="email" placeholder="Введите почту" value={ email } style={ errors.indexOf("email") > -1 ? { color: "#ED0A34" } : {} } onChange={ (event) => { this._handle_onChange("email", event.target.value) } }/>
|
||
</div>
|
||
<div className="table_cell" data-title="Роль">Пользователь</div>
|
||
<div className="table_cell" data-title="Доступные организации">
|
||
<button className="settings_dropdown" data-selected="false" onClick={ this._handle_onCompaniesSelection }>{ selected_companies_all || selected_companies_list.length > 0 ? selected_companies_all ? "Все организации" : selected_companies_list.map((company, index) => <p key={ index }>{ company.title }</p>) : "Выберите организацию" }</button>
|
||
<div className={ `dropdown_list ${ selection ? 'opened' : '' }` }>
|
||
<div className="list_item">
|
||
<input type="checkbox" value="" name="companies_list" id="company_1" hidden checked={ selected_companies_all } onChange={ this._handle_onChangeCompanies_all }/>
|
||
<label htmlFor="company_1">
|
||
Все организации
|
||
</label>
|
||
</div>
|
||
{ companies !== undefined && companies !== null && companies.map((company, index) =>
|
||
{
|
||
let checked = false;
|
||
if(selected_companies_all)
|
||
{
|
||
checked = true;
|
||
}
|
||
else
|
||
{
|
||
for(let i in selected_companies_list)
|
||
{
|
||
if(selected_companies_list[i].acc_number === company.acc_number)
|
||
{
|
||
checked = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return (
|
||
<div className="list_item" key={ index }>
|
||
<input type="checkbox" checked={ checked } value={ company.inn } name="companies_list" id={ `company_${ index }` } hidden onChange={ () => this._handle_onCompanySelect(company) }/>
|
||
<label htmlFor={ `company_${ index }` }>
|
||
{ company.title }
|
||
<span>ИНН: { company.inn } { company.kpp !== undefined && company.kpp !== null && `КПП: ${ company.kpp }` }</span>
|
||
</label>
|
||
</div>
|
||
)
|
||
}) }
|
||
</div>
|
||
</div>
|
||
<div className="table_cell" data-title="Статус">-</div>
|
||
</>
|
||
)
|
||
}
|
||
}
|
||
|
||
class AdminPage extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
loading: false,
|
||
user: {},
|
||
users: null,
|
||
companies: null,
|
||
add: false,
|
||
edit: false,
|
||
save: false,
|
||
form: {},
|
||
observer: false,
|
||
to_delete: [],
|
||
errors: [],
|
||
};
|
||
|
||
this.formRef = React.createRef();
|
||
}
|
||
|
||
static getDerivedStateFromProps(nextProps, prevState)
|
||
{
|
||
return {
|
||
observer: nextProps.observer,
|
||
user: nextProps.user,
|
||
users: nextProps.users,
|
||
companies: nextProps.companies,
|
||
};
|
||
}
|
||
|
||
componentDidMount()
|
||
{
|
||
this.setState({ loading: true }, () =>
|
||
{
|
||
if(!this.state.observer && !this.state.user.is_admin)
|
||
{
|
||
this.props.router.push("/");
|
||
}
|
||
else
|
||
{
|
||
getUsers({ dispatch: this.props.dispatch })
|
||
.then(() =>
|
||
{
|
||
this.setState({ loading: false, })
|
||
})
|
||
.catch(() =>
|
||
{
|
||
this.setState({ loading: false });
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
_handle_onAdd = () =>
|
||
{
|
||
this.setState({ add: true }, () =>
|
||
{
|
||
this.formRef.current.scrollIntoView({
|
||
behavior: 'smooth',
|
||
block: 'center',
|
||
});
|
||
});
|
||
}
|
||
|
||
_handle_onEdit = () =>
|
||
{
|
||
this.setState({ edit: true });
|
||
}
|
||
|
||
_handle_onSave = () =>
|
||
{
|
||
const { form, add, edit, to_delete } = this.state;
|
||
|
||
if(add)
|
||
{
|
||
const { name, email, selected_companies_list } = form;
|
||
|
||
const companies = [];
|
||
for(let i in selected_companies_list)
|
||
{
|
||
companies.push(selected_companies_list[i].acc_number);
|
||
}
|
||
|
||
this.setState({ add: false, edit: false, loading: true }, () =>
|
||
{
|
||
sendInvite({ name, email, companies })
|
||
.then((result) =>
|
||
{
|
||
if(result.status === "success")
|
||
{
|
||
getUsers({ dispatch: this.props.dispatch })
|
||
.then(() =>
|
||
{
|
||
this.setState({ loading: false, })
|
||
})
|
||
.catch(() =>
|
||
{
|
||
this.setState({ loading: false });
|
||
});
|
||
}
|
||
else
|
||
{
|
||
this.setState({ loading: false });
|
||
}
|
||
})
|
||
.catch((error) =>
|
||
{
|
||
this.setState({ loading: false, add: true, errors: error.errors });
|
||
});
|
||
});
|
||
}
|
||
else
|
||
{
|
||
this.setState({ add: false, edit: false, loading: true }, () =>
|
||
{
|
||
removeUser({ emails: to_delete })
|
||
.then((result) =>
|
||
{
|
||
if(result.status === "success")
|
||
{
|
||
getUsers({ dispatch: this.props.dispatch })
|
||
.then(() =>
|
||
{
|
||
this.setState({ loading: false, to_delete: [] })
|
||
})
|
||
.catch(() =>
|
||
{
|
||
this.setState({ loading: false, to_delete: [] });
|
||
});
|
||
}
|
||
else
|
||
{
|
||
this.setState({ loading: false });
|
||
}
|
||
})
|
||
.catch(() =>
|
||
{
|
||
this.setState({ loading: false });
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onCancel = () =>
|
||
{
|
||
this.setState({ add: false, edit: false, to_delete: [], });
|
||
}
|
||
|
||
_onFormEdit = (form) =>
|
||
{
|
||
let save = true;
|
||
if(form.name === "")
|
||
{
|
||
save = false;
|
||
}
|
||
if(form.email === "")
|
||
{
|
||
save = false;
|
||
}
|
||
if(!form.selected_companies_all)
|
||
{
|
||
if(form.selected_companies_list.length === 0)
|
||
{
|
||
save = false;
|
||
}
|
||
}
|
||
|
||
this.setState({ form, save, errors: [] });
|
||
}
|
||
|
||
_handle_onMarkToDelete = (email) =>
|
||
{
|
||
const to_delete = [ ...this.state.to_delete ];
|
||
|
||
if(to_delete.indexOf(email) > -1)
|
||
{
|
||
|
||
to_delete.splice(to_delete.indexOf(email), 1);
|
||
}
|
||
else
|
||
{
|
||
to_delete.push(email);
|
||
}
|
||
|
||
this.setState({ to_delete });
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { loading, user, observer, users, companies, errors, form, add, edit, save, to_delete } = this.state;
|
||
|
||
return (
|
||
<React.Fragment>
|
||
<Head>
|
||
<title>ЛК Эволюция автолизинга</title>
|
||
<meta
|
||
name="description"
|
||
content="ЛК Эволюция автолизинга"
|
||
/>
|
||
</Head>
|
||
<Header { ...this.props }/>
|
||
<AccountLayout>
|
||
<div className="title_wrapper">
|
||
<div className="left">
|
||
<h1 className="section_title">Личный кабинет</h1>
|
||
</div>
|
||
<Company { ...this.props }/>
|
||
</div>
|
||
<div className="aside_container about">
|
||
<InnerMenu { ...this.props } user={ user } observer={ observer }/>
|
||
<article>
|
||
{ loading ? (
|
||
<div className="table_row table_header" style={{ minHeight: 300, display: "flex", justifyContent: "center", alignItems: "center" }}>
|
||
<SpinnerCircular size={90} thickness={51} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
|
||
</div>
|
||
) : (
|
||
<>
|
||
<div className="settings_user_control">
|
||
<p>Настройки доступа к личному кабинету</p>
|
||
<div>
|
||
{ add || edit ? (
|
||
<>
|
||
<button className="button button-blue" onClick={ this._handle_onCancel }>Отменить</button>
|
||
<button className="button button-blue" onClick={ this._handle_onSave } disabled={ add ? save ? false : true : to_delete.length > 0 ? false : true }>Сохранить</button>
|
||
</>
|
||
) : (
|
||
<>
|
||
<button className="button button-blue" onClick={ this._handle_onAdd }>Добавить пользователя</button>
|
||
<button className="button button-blue" onClick={ this._handle_onEdit }>Редактировать</button>
|
||
</>
|
||
) }
|
||
</div>
|
||
</div>
|
||
<div className="settings_table editable">
|
||
<div className="table_header table_row">
|
||
<div className="table_cell">ФИО пользователя</div>
|
||
<div className="table_cell">Почта</div>
|
||
<div className="table_cell">Роль</div>
|
||
<div className="table_cell">Доступные организации</div>
|
||
<div className="table_cell" style={ !edit ? { border: "none", } : {} }>Статус</div>
|
||
{ edit && (
|
||
<div className="table_cell" style={{ border: "none", }}></div>
|
||
) }
|
||
</div>
|
||
{ users !== undefined && users !== null && users.map((entry, index) =>
|
||
{
|
||
if(entry.email === user.email)
|
||
{
|
||
return (
|
||
<div className="table_row" key={ index }>
|
||
<div className="table_cell" data-title="ФИО пользователя">{ entry.name } (Вы)</div>
|
||
<div className="table_cell" data-title="Почта">{ entry.email }</div>
|
||
<div className="table_cell" data-title="Роль">{ entry.is_admin ? "Администратор" : "Пользователь" }</div>
|
||
<div className="table_cell" data-title="Доступные организации">Все организации</div>
|
||
<div className="table_cell" data-title="Статус">{ entry.is_admin ? "Активен" : entry.last !== null ? "Активен" : "Приглашен" }</div>
|
||
{ edit && (
|
||
<div className="table_cell delete" style={{ position: 'relative' }}></div>
|
||
) }
|
||
</div>
|
||
)
|
||
}
|
||
return null;
|
||
}) }
|
||
{ users !== undefined && users !== null && users.map((entry, index) =>
|
||
{
|
||
if(entry.email !== user.email)
|
||
{
|
||
return (
|
||
<div className="table_row" key={ index } style={ to_delete.indexOf(entry.email) > -1 ? { backgroundColor: "#eee" } : {} }>
|
||
<div className="table_cell" data-title="ФИО пользователя" style={ to_delete.indexOf(entry.email) > -1 ? { textDecoration: "line-through" } : {} }>{ entry.name }</div>
|
||
<div className="table_cell" data-title="Почта" style={ to_delete.indexOf(entry.email) > -1 ? { textDecoration: "line-through" } : {} }>{ entry.email }</div>
|
||
<div className="table_cell" data-title="Роль" style={ to_delete.indexOf(entry.email) > -1 ? { textDecoration: "line-through" } : {} }>{ entry.is_admin ? "Администратор" : "Пользователь" }</div>
|
||
<div className="table_cell" data-title="Доступные организации">{ entry.companies.map((company, c_index) => (
|
||
<p key={ c_index } style={ to_delete.indexOf(entry.email) > -1 ? { textDecoration: "line-through" } : {} }>{ company.title }</p>
|
||
)) }</div>
|
||
<div className="table_cell" data-title="Статус" style={ to_delete.indexOf(entry.email) > -1 ? { textDecoration: "line-through" } : {} }>{ entry.is_admin ? "Активен" : entry.last !== null ? "Активен" : "Приглашен" }</div>
|
||
{ edit && (
|
||
<div className="table_cell delete" style={{ position: 'relative' }}>
|
||
<button className="delete_user" title="Удалить пользователя" onClick={ () => { this._handle_onMarkToDelete(entry.email) }}></button>
|
||
</div>
|
||
) }
|
||
</div>
|
||
)
|
||
}
|
||
return null;
|
||
}) }
|
||
{/*}
|
||
{ user !== undefined && user !== null && user.email !== undefined && user.email !== null && (
|
||
<div className="table_row">
|
||
<div className="table_cell" data-title="ФИО пользователя">{ `${ user.lastname } ${ user.name } ${ user.secondname }` }</div>
|
||
<div className="table_cell" data-title="Почта">{ user.email }</div>
|
||
<div className="table_cell" data-title="Роль">Администратор</div>
|
||
<div className="table_cell" data-title="Доступные организации">Все организации</div>
|
||
<div className="table_cell" data-title="Статус">Активен</div>
|
||
<div className="table_cell delete" style={{ position: 'relative' }}>
|
||
</div>
|
||
</div>
|
||
) }
|
||
{*/}
|
||
{/*}
|
||
<div className="table_row">
|
||
<div className="table_cell" data-title="ФИО пользователя">Иванов Иван Иванович</div>
|
||
<div className="table_cell" data-title="Почта">iivanov@mail.com</div>
|
||
<div className="table_cell" data-title="Роль">Администратор</div>
|
||
<div className="table_cell" data-title="Доступные организации">Все организации</div>
|
||
<div className="table_cell" data-title="Статус">Активен</div>
|
||
<div className="table_cell delete" style={{ position: 'relative' }}>
|
||
<button className="delete_user" title="Удалить пользователя"></button>
|
||
</div>
|
||
</div>
|
||
{*/}
|
||
{ add && (
|
||
<div className="table_row editable" ref={ this.formRef }>
|
||
<Form companies={ companies } errors={ errors } form={ form } onForm={ this._onFormEdit }/>
|
||
</div>
|
||
) }
|
||
{/*}
|
||
{*/}
|
||
</div>
|
||
</>
|
||
) }
|
||
</article>
|
||
</div>
|
||
</AccountLayout>
|
||
<Footer/>
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
}
|
||
|
||
function mapStateToProps(state, ownProps)
|
||
{
|
||
return {
|
||
observer: state.auth.observer,
|
||
user: state.user,
|
||
users: state.admin.users,
|
||
companies: state.companies.list,
|
||
}
|
||
}
|
||
|
||
export const getServerSideProps = reduxWrapper.getServerSideProps(store =>
|
||
async ({ req, res, query }) =>
|
||
{
|
||
let props = {};
|
||
|
||
if(req.headers.cookie !== undefined)
|
||
{
|
||
const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");
|
||
|
||
if(cookies.jwt === undefined || cookies.jwt === null)
|
||
{
|
||
res.statusCode = 302;
|
||
res.setHeader('Location', `/login`);
|
||
}
|
||
else
|
||
{
|
||
//const tokenValid = await checkToken(cookies.jwt);
|
||
const tokenValid = true;
|
||
if(!tokenValid)
|
||
{
|
||
res.statusCode = 302;
|
||
res.setHeader('Location', `/login`);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
res.statusCode = 302;
|
||
res.setHeader('Location', `/login`);
|
||
}
|
||
|
||
return { props: props };
|
||
}
|
||
);
|
||
|
||
export default withRouter(connect(mapStateToProps)(AdminPage)); |