558 lines
17 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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));