364 lines
11 KiB
JavaScript
364 lines
11 KiB
JavaScript
import React from "react";
|
||
import Head from 'next/head';
|
||
import Image from 'next/image';
|
||
import moment from 'moment';
|
||
import 'moment/locale/ru';
|
||
import numeral from "numeral";
|
||
import cookie from 'cookie';
|
||
|
||
import { connect } from "react-redux";
|
||
import { withRouter } from 'next/router';
|
||
import { reduxWrapper } from '../../store';
|
||
|
||
import Header from '../components/Header';
|
||
import Footer from '../components/Footer';
|
||
import InnerMenu from "./components/InnerMenu";
|
||
import Company from "../components/Company";
|
||
import CalendarCellModal from "../components/Modal/calendar";
|
||
|
||
import { getCalendar } from '../../actions';
|
||
import { MatchMedia } from '../../utils/mediaqueries';
|
||
import AccountLayout from "../components/Layout/Account";
|
||
|
||
class CalendarPage extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
modalOpened: false,
|
||
payments: null,
|
||
periods: null,
|
||
selected_period: moment().format("YYYYMM"),
|
||
selected_payment: undefined,
|
||
current_week: parseInt(moment().format('ww'), 10),
|
||
selected_week: 0,
|
||
weeks_in_month: 1,
|
||
perweek: MatchMedia() === "mobile" ? true : false,
|
||
};
|
||
}
|
||
|
||
static getDerivedStateFromProps(nextProps, prevState)
|
||
{
|
||
return {
|
||
company: nextProps.company,
|
||
payments: nextProps.payments,
|
||
periods: nextProps.periods,
|
||
};
|
||
}
|
||
|
||
componentDidMount()
|
||
{
|
||
const date_from = moment().startOf("month").subtract(7, 'day').toDate();
|
||
const date_to = moment().endOf("month").add(7, 'day').toDate();
|
||
|
||
var clonedMoment = moment();
|
||
var first = clonedMoment.startOf('month').week();
|
||
var last = clonedMoment.endOf('month').week();
|
||
if( first > last) { last = first + last; }
|
||
let mw = last - first + 1;
|
||
const nwsd = moment().endOf("month").add(1, "day").format("e");
|
||
|
||
if(nwsd !== 0) { mw = mw - 1; }
|
||
this.setState({ weeks_in_month: mw });
|
||
|
||
getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch();
|
||
}
|
||
|
||
toggleModal = () =>
|
||
{
|
||
this.setState({
|
||
modalOpened: !this.state.modalOpened
|
||
})
|
||
}
|
||
|
||
getPayments = (date) =>
|
||
{
|
||
const { payments } = this.state;
|
||
|
||
for(let i in payments)
|
||
{
|
||
if(payments[i].date === date)
|
||
{
|
||
return payments[i];
|
||
}
|
||
}
|
||
return undefined;
|
||
}
|
||
|
||
_handle_onDayClick = (day) =>
|
||
{
|
||
this.setState({ selected_payment: day.payment });
|
||
this.toggleModal();
|
||
}
|
||
|
||
_handle_onChangePeriod = (period, new_selected_week) =>
|
||
{
|
||
var clonedMoment = moment(period, "YYYYMM");
|
||
var first = clonedMoment.startOf('month').week();
|
||
var last = clonedMoment.endOf('month').week();
|
||
if( first > last) { last = first + last; }
|
||
let mw = last - first + 1;
|
||
|
||
const ld = parseInt(moment(period, "YYYYMM").endOf("month").format("e"), 10);
|
||
if(ld !== 6) { mw = mw - 1; }
|
||
|
||
this.setState({ selected_period: period, weeks_in_month: mw, selected_week: new_selected_week}, () =>
|
||
{
|
||
const date_from = moment(period, "YYYYMM").startOf("month").subtract(7, 'day').toDate();
|
||
const date_to = moment(period, "YYYYMM").endOf("month").add(7, 'day').toDate();
|
||
|
||
getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch();
|
||
});
|
||
}
|
||
|
||
_handle_onWeek_prev = () =>
|
||
{
|
||
const { selected_period, selected_week, } = this.state;
|
||
|
||
if(selected_week === 0)
|
||
{
|
||
var clonedMoment = moment(selected_period, "YYYYMM").subtract(1, "month");
|
||
var first = clonedMoment.startOf('month').week();
|
||
var last = clonedMoment.endOf('month').week();
|
||
if( first > last) { last = first + last; }
|
||
let mw = last - first + 1;
|
||
|
||
const ld = parseInt(clonedMoment.endOf("month").format("e"), 10);
|
||
if(ld !== 6) { mw = mw - 1; }
|
||
|
||
const new_selected_week = mw - 1;
|
||
const prev_period = clonedMoment.format("YYYYMM");
|
||
|
||
this._handle_onChangePeriod(prev_period, new_selected_week);
|
||
}
|
||
else
|
||
{
|
||
this.setState({ selected_week: parseInt(selected_week, 10) - 1 }, () =>
|
||
{
|
||
});
|
||
}
|
||
}
|
||
|
||
_getWeekToSwitch = () =>
|
||
{
|
||
const { selected_period, selected_week, weeks_in_month } = this.state;
|
||
}
|
||
|
||
_handle_onWeek_next = () =>
|
||
{
|
||
const { selected_period, selected_week, weeks_in_month } = this.state;
|
||
const next_week = selected_week + 1;
|
||
|
||
if(next_week === weeks_in_month)
|
||
{
|
||
const next_period = moment(selected_period, "YYYYMM").add(1, "month").format("YYYYMM");
|
||
this._handle_onChangePeriod(next_period, 0);
|
||
}
|
||
else
|
||
{
|
||
this.setState({ selected_week: next_week }, () =>
|
||
{
|
||
});
|
||
}
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { selected_period, selected_payment, periods, payments, current_week, selected_week, perweek, weeks_in_month } = this.state;
|
||
if(payments === null) { return null; }
|
||
|
||
let month = moment(selected_period, "YYYYMM").format("M") - 1;
|
||
|
||
const dates = [];
|
||
const date_sm = moment(selected_period, 'YYYYMM').startOf("month");
|
||
const date_em = moment(selected_period, 'YYYYMM').endOf("month");
|
||
|
||
let date_s = null;
|
||
if(date_sm.clone().isoWeekday() !== 1)
|
||
{ date_s = date_sm.clone().subtract(date_sm.clone().isoWeekday() - 1, "days"); }
|
||
else
|
||
{ date_s = date_sm; }
|
||
|
||
let date_e = null;
|
||
if(date_em.day() !== 0)
|
||
{ date_e = date_em.add(7 - date_em.day(), "days"); }
|
||
else
|
||
{ date_e = date_em; }
|
||
|
||
const date = moment();
|
||
|
||
let d = date_s;
|
||
let payment = this.getPayments(date_s.format("YYYY-MM-DD"));
|
||
dates.push({
|
||
date: date_s.clone(),
|
||
payment: payment,
|
||
});
|
||
|
||
while(d.add(1, 'days').diff(date_e) < 0)
|
||
{
|
||
dates.push({
|
||
date: d.clone(),
|
||
});
|
||
}
|
||
|
||
for(let i in dates)
|
||
{
|
||
dates[i].payment = this.getPayments(dates[i].date.format("YYYY-MM-DD"));
|
||
}
|
||
|
||
const dow = date.day();
|
||
const weeks = dates.reduce(function(result, value, index, array) {
|
||
if (index % 7 === 0)
|
||
result.push(array.slice(index, index +7));
|
||
return result;
|
||
}, []);
|
||
|
||
let render_weeks = [];
|
||
if(perweek)
|
||
{
|
||
render_weeks = weeks.slice(selected_week, weeks_in_month);
|
||
}
|
||
else
|
||
{
|
||
render_weeks = weeks;
|
||
}
|
||
|
||
const periods_list = Object.values(periods);
|
||
|
||
return (
|
||
<React.Fragment>
|
||
<Head>
|
||
<title>ЛК Эволюция автолизинга</title>
|
||
<meta
|
||
name="description"
|
||
content="ЛК Эволюция автолизинга"
|
||
/>
|
||
</Head>
|
||
<Header { ...this.props }/>
|
||
<AccountLayout>
|
||
<div className="title_wrapper">
|
||
<div className="left">
|
||
{/*[{ perweek ? 1 : 0 }, { current_week }, { selected_week }, { weeks_in_month }]*/}
|
||
<h1 className="section_title">Календарь оплат</h1>
|
||
</div>
|
||
<Company { ...this.props }/>
|
||
</div>
|
||
<div className="aside_container about">
|
||
<InnerMenu { ...this.props }/>
|
||
<article>
|
||
<div className="calendar_wrapper">
|
||
<div className="form_field">
|
||
{ periods_list.length > 0 && (
|
||
<select id="calendar_month" value={ periods_list.indexOf(selected_period) < 0 ? periods_list[periods_list.length - 1] : selected_period } onChange={ (event) => this._handle_onChangePeriod(event.target.value, 0) }>
|
||
{ periods !== null && periods_list.map((period, index) => (
|
||
<option key={ index } value={ period }>{ moment(period, "YYYYMM").format('MMMM YYYY') }</option>
|
||
)) }
|
||
</select>
|
||
) }
|
||
</div>
|
||
<div className="calendar_nav">
|
||
<button onClick={ () => this._handle_onWeek_prev() } disabled={ moment(selected_period, "YYYYMM").add(selected_week * 7, "day") <= moment(periods_list[0], "YYYYMM") ? true : false }>Предыдущая неделя</button>
|
||
<button onClick={ () => this._handle_onWeek_next() } disabled={ moment(selected_period, "YYYYMM").add(selected_week * 7, "day") >= moment(periods_list[periods_list.length - 1], "YYYYMM").add(1, "month") ? true : false }>Следующая неделя</button>
|
||
</div>
|
||
<div className="calendar_grid">
|
||
<div className="grid_header">
|
||
<div className="grid_cell">Пн</div>
|
||
<div className="grid_cell">Вт</div>
|
||
<div className="grid_cell">Ср</div>
|
||
<div className="grid_cell">Чт</div>
|
||
<div className="grid_cell">Пт</div>
|
||
<div className="grid_cell">Сб</div>
|
||
<div className="grid_cell">Вс</div>
|
||
</div>
|
||
<div className="grid_body">
|
||
{ render_weeks.map((week, week_index) =>
|
||
{
|
||
return (
|
||
<div className={week_index == 0 ? "grid_week active" : "grid_week"} key={"week_" + week_index}>
|
||
{ week.map((day, index) => {
|
||
if(day.payment)
|
||
{
|
||
return (
|
||
<div key={ index } style={{ cursor: "pointer" }} className={`grid_cell payment ${ !perweek && day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `} onClick={ () => this._handle_onDayClick(day) }>
|
||
<div className="cell_header">
|
||
<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } <span className="year">{ day.date.format("Y").toLocaleLowerCase() }</span></p>
|
||
</div>
|
||
<div className="cell_body">{ day.payment && (
|
||
<p>
|
||
Общий платеж
|
||
<span style={ day.payment.total > 1000000 ? { fontSize: '14px', whiteSpace: "nowrap" } : { whiteSpace: "nowrap" }}>{ numeral(day.payment.total).format(' ., ') } ₽</span>
|
||
</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
return (
|
||
<div key={ index } className={`grid_cell ${ !perweek && day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `}>
|
||
<div className="cell_header">
|
||
<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } <span className="year">{ day.date.format("Y").toLocaleLowerCase() }</span></p>
|
||
</div>
|
||
</div>
|
||
)
|
||
}) }
|
||
</div>
|
||
)
|
||
}) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</AccountLayout>
|
||
<CalendarCellModal open={ this.state.modalOpened } selected_payment={ selected_payment } close={ () => this.toggleModal() }/>
|
||
<Footer/>
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
}
|
||
|
||
function mapStateToProps(state, ownProps)
|
||
{
|
||
return {
|
||
company: state.company,
|
||
payments: state.calendar.payments,
|
||
periods: state.calendar.periods,
|
||
}
|
||
}
|
||
|
||
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 = 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)(CalendarPage)); |