update for events listing

This commit is contained in:
merelendor 2022-09-07 13:24:27 +03:00
parent 5f1c3065b4
commit 441ebe743d
16 changed files with 5214 additions and 182 deletions

View File

@ -28,53 +28,59 @@ export const getEvents = ({ dispatch, type, contract }) =>
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
{ {
axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/events`, {}, { if(global.store.getState().events.list === undefined)
withCredentials: true, {
}) axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/events`, {}, {
.then((response) => withCredentials: true,
})
.then((response) =>
{
console.log("ACTION", "getEvents()", "response", response.data);
const events = response.data;
const filtered_events = [];
console.log("ACTION", "getEvents()", "events", events);
dispatch({ type: actionTypes.EVENTS, data: { list: events, loaded: true } });
resolve();
})
.catch((error) =>
{
console.log("error");
console.error(error);
reject();
});
}
else
{ {
console.log("ACTION", "getEvents()", "response", response.data);
const events = response.data;
const filtered_events = [];
console.log("ACTION", "getEvents()", "events", events);
dispatch({ type: actionTypes.EVENTS, data: { list: events, loaded: true } });
resolve(); resolve();
}) }
.catch((error) =>
{
console.log("error");
console.error(error);
reject();
});
}); });
} }
export const getFilteredEvents = ({ dispatch, type, search, contract }) => export const getFilteredEvents = ({ dispatch, search }) =>
{ {
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
{ {
console.log("getFilteredEvents"); console.log("getFilteredEvents");
const types = { const types = {
"restrictions": "restrictions", "additional": [ "osago_prolong", "kasko_prolong", "fingap_prolong" ],
"payments": [ "kasko_prolong", "fingap_prolong", "osago_prolong" ], "finance": [ "graph_change", "end_contract" ],
"additional": "graph_change",
"finance": "end_contract",
"fines": "fine_gibdd", "fines": "fine_gibdd",
"pts": "return_pts", "pts": "return_pts",
}; };
if(type !== undefined || (search !== undefined || search !== null || search !== "")) if((search !== undefined || search !== null || search !== ""))
{ {
console.log(global.store.getState().events); console.log(global.store.getState().events);
const events = global.store.getState().events.list; const events = global.store.getState().events.list;
let query = nSQL(events) let query = nSQL(events)
.query("select"); .query("select");
/*
if(type !== undefined) if(type !== undefined)
{ {
if(typeof types[ type ] === "string") if(typeof types[ type ] === "string")
@ -97,30 +103,22 @@ export const getFilteredEvents = ({ dispatch, type, search, contract }) =>
query.where(array_of_queries); query.where(array_of_queries);
} }
} }
*/
if(contract !== undefined && contract !== null && contract !== "")
{
query.where([ [ "contract_number", "=", contract ] ]);
}
if(search !== undefined && search !== null && search !== "") if(search !== undefined && search !== null && search !== "")
{ {
query.where([ [ "contract_number", "LIKE", `%${ search }%` ], "OR", [ "add_info", "LIKE", `%${ search }%` ]]); query.where([ [ "contract_number", "LIKE", `%${ search }%` ], "OR", [ "add_info", "LIKE", `%${ search }%` ]]);
} }
query.exec().then((rows) => query.exec().then((rows) =>
{ {
console.log("rows"); console.log("rows");
console.log(rows); console.log(rows);
dispatch({ type: actionTypes.EVENTS_FILTERED, data: { filtered: rows } }); dispatch({ type: actionTypes.EVENTS_FILTERED, data: { filtered: rows } });
resolve(); resolve();
//callback(null, rows);
}); });
/*
.orderBy("number", "asc")
*/
} }
else else
{ {
@ -129,3 +127,34 @@ export const getFilteredEvents = ({ dispatch, type, search, contract }) =>
} }
}); });
} }
export const getContractEvents = ({ dispatch, contract }) =>
{
return new Promise((resolve, reject) =>
{
console.log("getContractEvents");
console.log(global.store.getState().events);
const events = global.store.getState().events.list;
let query = nSQL(events)
.query("select");
if(contract !== undefined && contract !== null && contract !== "")
{
query.where([ [ "contract_number", "=", contract ] ]);
}
query.exec().then((rows) =>
{
console.log("rows");
console.log(rows);
const events_list = {};
events_list[`${ contract }`] = rows;
dispatch({ type: actionTypes.CONTRACT_EVENTS, data: events_list });
resolve();
});
});
}

View File

@ -26,6 +26,9 @@ export const CONTRACT_OPTIONS = 'CONTRACT_OPTIONS';
export const CONTRACT_CURRENT = 'CONTRACT_CURRENT'; export const CONTRACT_CURRENT = 'CONTRACT_CURRENT';
export const CONTRACT_CALCULATED = 'CONTRACT_CALCULATED'; export const CONTRACT_CALCULATED = 'CONTRACT_CALCULATED';
export const CONTRACT_EVENTS = 'CONTRACT_EVENTS';
export const CONTRACT_EVENTS_RESET = 'CONTRACT_EVENTS_RESET';
export const CALENDAR = 'CALENDAR'; export const CALENDAR = 'CALENDAR';
export const EVENTS = 'EVENTS'; export const EVENTS = 'EVENTS';
export const EVENTS_FILTERED = 'EVENTS_FILTERED'; export const EVENTS_FILTERED = 'EVENTS_FILTERED';

View File

@ -96,7 +96,7 @@ header .system_nav > li > a[data-notify]:before {
text-align: center; text-align: center;
color: #fff; color: #fff;
background: #A8026B; background: #A8026B;
font-size: 13px; font-size: 11px;
} }
@media all and (max-width: 768px) { @media all and (max-width: 768px) {
header .system_nav > li > a[data-notify]:before { header .system_nav > li > a[data-notify]:before {

View File

@ -114,7 +114,7 @@ header {
text-align: center; text-align: center;
color: #fff; color: #fff;
background: #A8026B; background: #A8026B;
font-size: 13px; font-size: 11px;
@media all and (max-width: 768px) { @media all and (max-width: 768px) {
width: 13px; width: 13px;

File diff suppressed because one or more lines are too long

View File

@ -2081,6 +2081,7 @@ main {
font-weight: 400; font-weight: 400;
text-align: center; text-align: center;
line-height: 20px; line-height: 20px;
font-size: 11px;
} }
&.active { &.active {

View File

@ -7,30 +7,37 @@ export default class InnerMenu extends React.Component
{ {
super(props); super(props);
this.state = { this.state = {
type: undefined type: undefined,
finance: 0,
additional: 0,
fines:0,
pts: 0,
}; };
this.menuRef = React.createRef(); this.menuRef = React.createRef();
} }
componentDidMount() _checkEventsCount = () =>
{ {
const hash = this.props.router.asPath.split('#')[1]; const { events, types } = this.props;
this.setState({ type: hash }); const count = {
} finance: 0,
additional: 0,
fines:0,
pts: 0,
};
componentDidUpdate(prevProps, prevState) for(let i in events)
{
const hash = this.props.router.asPath.split('#')[1];
if(this.state.type !== hash)
{ {
this.setState({ type: hash }); count[types[events[i].event_type]]++;
} }
return count;
} }
render() render()
{ {
console.log("Events", "InnerMenu", "this.props.router", this.props.router); const { type } = this.props;
const { type } = this.state; const count = this._checkEventsCount();
return ( return (
<aside> <aside>
@ -47,29 +54,31 @@ export default class InnerMenu extends React.Component
</Link> </Link>
</li> </li>
{*/} {*/}
{/*}
<li> <li>
<Link href={`/events#payments`} shallow> <Link href={`/events#payments`} shallow>
<a className={ type === "payments" ? "active" : "" }>Платежи</a> <a className={ type === "payments" ? "active" : "" }>Платежи</a>
</Link> </Link>
</li> </li>
{*/}
<li> <li>
<Link href={`/events#finance`} shallow> <Link href={`/events#finance`} shallow>
<a className={ type === "finance" ? "active" : "" }>Договоры</a> <a className={ type === "finance" ? "active" : "" }>Договоры { count.finance > 0 && (<span>{ count.finance }</span>) }</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href={`/events#additional`} shallow> <Link href={`/events#additional`} shallow>
<a className={ type === "additional" ? "active" : "" }>Дополнительные услуги</a> <a className={ type === "additional" ? "active" : "" }>Дополнительные услуги { count.additional > 0 && (<span>{ count.additional }</span>) }</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href={`/events#fines`} shallow> <Link href={`/events#fines`} shallow>
<a className={ type === "fines" ? "active" : "" }>Штрафы</a> <a className={ type === "fines" ? "active" : "" }>Штрафы { count.fines > 0 && (<span>{ count.fines }</span>) }</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href={`/events#pts`} shallow> <Link href={`/events#pts`} shallow>
<a className={ type === "pts" ? "active" : "" }>ПТС</a> <a className={ type === "pts" ? "active" : "" }>ПТС { count.pts > 0 && (<span>{ count.pts }</span>) }</a>
</Link> </Link>
</li> </li>
</ul> </ul>

View File

@ -277,9 +277,9 @@ class SumSelector extends React.Component
const { option, onOption } = this.props; const { option, onOption } = this.props;
this.setState({ this.setState({
value: option.min, value: option.value !== null ? option.value : option.min,
min: option.min, min: option.min,
max: option.max, max: option.max,
}, () => }, () =>
{ {
onOption(this.state.value, false); onOption(this.state.value, false);

View File

@ -10,11 +10,11 @@ export default class ContractHeader extends React.Component
}; };
} }
componentDidMount() componentDidMount()
{ {
} }
render() render()
{ {
const { number, date, car } = this.props; const { number, date, car } = this.props;

View File

@ -1,7 +1,9 @@
import React from "react"; import React from "react";
import Link from "next/link"; import Link from "next/link";
import { connect } from "react-redux";
import { getContractEvents, } from "../../../../actions";
export default class InnerMenu extends React.Component class InnerMenu extends React.Component
{ {
constructor(props) constructor(props)
{ {
@ -12,11 +14,27 @@ export default class InnerMenu extends React.Component
menuOpened: false, menuOpened: false,
count_events: 0, count_events: 0,
count_fines: 0, count_fines: 0,
contract_events: {},
};
}
static getDerivedStateFromProps(nextProps, prevState)
{
return {
contract_events: nextProps.contract_events,
}; };
} }
componentDidMount() componentDidMount()
{ {
const { number, dispatch } = this.props;
const { contract_events } = this.state;
if(contract_events[number] === undefined)
{
getContractEvents({ dispatch, contract: number });
}
let l = 0; let l = 0;
let m = 0; let m = 0;
const menu = [ "payments", "services", "agreement", "documents", "materials", "events", "change" ]; const menu = [ "payments", "services", "agreement", "documents", "materials", "events", "change" ];
@ -61,7 +79,10 @@ export default class InnerMenu extends React.Component
render() render()
{ {
const { number, status } = this.props; const { number, status } = this.props;
const { menuOpened, count_events, count_fines } = this.state; const { menuOpened, count_fines, contract_events } = this.state;
const count_events = contract_events[number] !== undefined && contract_events[number] !== null ? Object.keys(contract_events[number]).length : 0;
console.log("contract_events", contract_events);
return ( return (
<aside> <aside>
@ -115,4 +136,13 @@ export default class InnerMenu extends React.Component
</aside> </aside>
) )
} }
} }
function mapStateToProps(state, ownProps)
{
return {
contract_events: state.contract_events
};
}
export default connect(mapStateToProps)(InnerMenu);

View File

@ -29,6 +29,7 @@ class ContractPage extends React.Component
contracts_info: {}, contracts_info: {},
events_loaded: false, events_loaded: false,
filtered: undefined, filtered: undefined,
contract_events: {},
}; };
} }
@ -36,8 +37,8 @@ class ContractPage extends React.Component
{ {
return { return {
contracts_info: nextProps.contracts_info, contracts_info: nextProps.contracts_info,
events_loaded: nextProps.events_loaded, events_loaded: nextProps.events_loaded,
filtered: nextProps.filtered, filtered: nextProps.filtered,
}; };
} }
@ -105,32 +106,6 @@ class ContractPage extends React.Component
<SpinnerCircular size={ 90 } thickness={ 51 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" /> <SpinnerCircular size={ 90 } thickness={ 51 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
</div> </div>
) } ) }
{/*}
<li className="new">
<p className="name"><b>Внимание! Просрочена дата возврата СТС по договору: ХХ.ХХ.ХХХХ</b></p>
<p className="type">Важное</p>
<p className="date">10.01.2022</p>
<p className="action">
<a href="">Посмотрите порядок возврата СТС</a>&nbsp; или
&nbsp;<a href="">Загрузите скан СТС</a>
</p>
</li>
<li className="new">
<p className="name"><b>Внимание! Просрочена дата возврата СТС по договору: ХХ.ХХ.ХХХХ</b></p>
<p className="date">10.01.2022</p>
<p className="action">
<a href="">Посмотрите порядок возврата СТС</a>&nbsp; или
&nbsp;<a href="">Загрузите скан СТС</a>
</p>
</li>
<li className="new">
<p className="name">Внимание! Осталось ХХ дней до пролонгации КАСКО по договору ХХХХ: ХХ.ХХ.ХХХХ. Не забудьте самостоятельно продлить полис ОСАГО</p>
<p className="date">10.01.2022</p>
<p className="action">
<a href="">Подробнее</a>
</p>
</li>
{*/}
</article> </article>
</div> </div>
</AccountLayout> </AccountLayout>

View File

@ -16,12 +16,12 @@ import InnerMenu from "./components/Events/InnerMenu";
import NotificationMessage from "./components/Events/NotificationMessage"; import NotificationMessage from "./components/Events/NotificationMessage";
import { getFilteredEvents } from "../actions"; import { getEvents, getFilteredEvents } from "../actions";
import AccountLayout from "./components/Layout/Account"; import AccountLayout from "./components/Layout/Account";
class EventsPage extends React.Component class EventsPage extends React.Component
{ {
constructor(props) constructor(props)
{ {
super(props); super(props);
this.state = { this.state = {
@ -29,12 +29,21 @@ class EventsPage extends React.Component
events_loaded: false, events_loaded: false,
filtered: undefined, filtered: undefined,
type: undefined, type: undefined,
types: {
"osago_prolong": "additional",
"kasko_prolong": "additional",
"fingap_prolong": "additional",
"graph_change": "finance",
"end_contract": "finance",
"fine_gibdd": "fines",
"return_pts": "pts",
},
loading: false, loading: false,
search: "" search: ""
}; };
} }
static getDerivedStateFromProps(nextProps, prevState) static getDerivedStateFromProps(nextProps, prevState)
{ {
return { return {
events: nextProps.events, events: nextProps.events,
@ -43,8 +52,25 @@ class EventsPage extends React.Component
}; };
} }
componentDidMount() componentDidMount()
{ {
const { events_loaded } = this.state;
const { dispatch, router } = this.props;
const hash = router.asPath.split('#')[1];
console.log("HASH", hash);
this.setState({ type: hash }, () =>
{
if(!events_loaded)
{
getEvents({ dispatch })
.then(() =>
{
this._filterEvents();
});
}
});
} }
componentDidUpdate(prevProps, prevState) componentDidUpdate(prevProps, prevState)
@ -52,10 +78,7 @@ class EventsPage extends React.Component
const hash = this.props.router.asPath.split('#')[1]; const hash = this.props.router.asPath.split('#')[1];
if(this.state.type !== hash) if(this.state.type !== hash)
{ {
this.setState({ type: hash }, () => this.setState({ type: hash });
{
this._filterEvents();
});
} }
} }
@ -72,13 +95,46 @@ class EventsPage extends React.Component
_filterEvents = () => _filterEvents = () =>
{ {
console.log("_filterEvents"); console.log("_filterEvents");
const { type, search } = this.state; const { dispatch } = this.props;
getFilteredEvents({ dispatch: this.props.dispatch, type, search }); const { search } = this.state;
getFilteredEvents({ dispatch, search });
}
_renderEvents = (events) =>
{
const { type, types } = this.state;
const notifications = [];
for(let i in events)
{
let event = events[i];
if(type !== undefined && type !== types[ event.event_type ]) {}
else
{
notifications.push(<NotificationMessage event={ event } key={ i } { ...this.props }/>);
}
}
if(notifications.length > 0)
{
return (
<ul className="list events-list">
{ notifications }
</ul>
)
}
else
{
return (<p>Нет событий по выбранным условиям.</p>)
}
} }
render() render()
{ {
const { loading, search, events, events_loaded, filtered } = this.state; const { loading, type, types, search, events, events_loaded, filtered } = this.state;
console.log("events", "type", type);
return ( return (
<React.Fragment> <React.Fragment>
@ -95,7 +151,7 @@ class EventsPage extends React.Component
<Company { ...this.props }/> <Company { ...this.props }/>
</div> </div>
<div className="aside_container about"> <div className="aside_container about">
<InnerMenu { ...this.props }/> <InnerMenu { ...this.props } type={ type } types={ types } events={ filtered !== undefined ? filtered : events }/>
<article> <article>
<div className="contract_search"> <div className="contract_search">
<form onSubmit={ (event) => { event.preventDefault(); } }> <form onSubmit={ (event) => { event.preventDefault(); } }>
@ -107,79 +163,11 @@ class EventsPage extends React.Component
<button className="button" disabled={ search !== "" ? false : true } onClick={ this._handle_onSearch }>Поиск</button> <button className="button" disabled={ search !== "" ? false : true } onClick={ this._handle_onSearch }>Поиск</button>
</form> </form>
</div> </div>
{ events_loaded && ( { events_loaded && (
<> <>
{ filtered !== undefined ? ( { filtered !== undefined ? this._renderEvents(filtered) : this._rederEvents(events) }
<> </>
{ filtered.length > 0 ? ( ) }
<ul className="list events-list">
{ filtered.map((event, index) => (
<NotificationMessage event={ event } key={ index } { ...this.props }/>
)) }
</ul>
) : (
<p>Нет событий по выбранным условиям.</p>
) }
</>
) : (
<>
{ events.length > 0 ? (
<ul className="list events-list">
{ events.map((event, index) => (
<NotificationMessage event={ event } key={ index } { ...this.props }/>
)) }
</ul>
) : (
<p>У Вас нет событий по договорам.</p>
) }
</>
)}
</>
) }
{/*}
<li className="new">
<p className="name">
<b>
Внимание! { events_loaded === true ? "events_loaded" : "!!!events_loaded" } Просрочена дата возврата СТС по договору:
ХХ.ХХ.ХХХХ
</b>
</p>
<p className="type">Важное</p>
<p className="date">10.01.2022</p>
<p className="action">
<a href="">Посмотрите порядок возврата СТС</a>&nbsp; или
&nbsp;<a href="">Загрузите скан СТС</a>
</p>
</li>
{*/}
{/*}
<li className="new">
<p className="name">
<b>
Внимание! Просрочена дата возврата СТС по договору:
ХХ.ХХ.ХХХХ
</b>
</p>
<p className="date">10.01.2022</p>
<p className="action">
<a href="">Посмотрите порядок возврата СТС</a>&nbsp; или
&nbsp;<a href="">Загрузите скан СТС</a>
</p>
</li>
{*/}
{/*}
<li className="new">
<p className="name">
Внимание! Осталось ХХ дней до пролонгации КАСКО по
договору ХХХХ: ХХ.ХХ.ХХХХ. Не забудьте самостоятельно
продлить полис ОСАГО
</p>
<p className="date">10.01.2022</p>
<p className="action">
<a href="">Подробнее</a>
</p>
</li>
{*/}
</article> </article>
</div> </div>
</AccountLayout> </AccountLayout>

View File

@ -242,7 +242,10 @@ class SupportRequestPage extends React.Component
}) })
.then(() => .then(() =>
{ {
this.setState({ loading: false, success: true, }); this.setState({ loading: false, success: true, }, () =>
{
window.scrollTo(0, 0);
});
}) })
.catch(() => .catch(() =>
{ {
@ -251,7 +254,10 @@ class SupportRequestPage extends React.Component
} }
else else
{ {
this.setState({ loading: false, success: true, }); this.setState({ loading: false, success: true, }, () =>
{
window.scrollTo(0, 0);
});
} }
}) })
.catch(() => .catch(() =>

View File

@ -0,0 +1,28 @@
import { HYDRATE } from 'next-redux-wrapper';
import * as actionTypes from '../constants/actionTypes';
import initialState from "./initialState";
const contractEventsReducer = (state = initialState.contract_events, action) =>
{
switch (action.type)
{
case actionTypes.CONTRACT_EVENTS:
{
return {
...state, ...action.data,
};
}
case actionTypes.CONTRACT_EVENTS_RESET:
{
return {};
}
default: {
return state;
}
}
};
export default contractEventsReducer;

View File

@ -64,6 +64,7 @@ export const defaultState = {
calculated: null, calculated: null,
}, },
}, },
contract_events: {},
calendar: { calendar: {
payments: null, payments: null,
periods: null, periods: null,
@ -87,7 +88,7 @@ export const defaultState = {
events: events:
{ {
loaded: false, loaded: false,
list: [], list: undefined,
filtered: undefined, filtered: undefined,
}, },
support: support:

View File

@ -12,6 +12,7 @@ import eventsReducer from '../reducers/eventsReducer';
import supportReducer from '../reducers/supportReducer'; import supportReducer from '../reducers/supportReducer';
import adminReducer from '../reducers/adminReducer'; import adminReducer from '../reducers/adminReducer';
import contractsInfoReducer from '../reducers/contractsInfoReducer'; import contractsInfoReducer from '../reducers/contractsInfoReducer';
import contractEventsReducer from '../reducers/contractEventsReducer';
const combinedReducer = combineReducers({ const combinedReducer = combineReducers({
auth: authReducer, auth: authReducer,
@ -25,6 +26,7 @@ const combinedReducer = combineReducers({
support: supportReducer, support: supportReducer,
admin: adminReducer, admin: adminReducer,
contracts_info: contractsInfoReducer, contracts_info: contractsInfoReducer,
contract_events: contractEventsReducer,
}); });
const makeStore = (context) => const makeStore = (context) =>
@ -42,7 +44,7 @@ const makeStore = (context) =>
const persistConfig = { const persistConfig = {
key: 'nextjs', key: 'nextjs',
whitelist: [ 'auth', 'user', 'company', 'companies', 'contracts_info', ], whitelist: [ 'auth', 'user', 'company', 'companies', 'contracts_info', 'contract_events' ],
storage storage
}; };