Skip to content

Instantly share code, notes, and snippets.

@brandonsueur
Created April 28, 2020 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonsueur/94c855f421a6c8e2751f47a0c2fab4a3 to your computer and use it in GitHub Desktop.
Save brandonsueur/94c855f421a6c8e2751f47a0c2fab4a3 to your computer and use it in GitHub Desktop.
managefixation.js
import React from 'react'
import { connect } from 'react-redux'
import { withTranslation } from 'react-i18next'
import { Modal, Form, DatePicker, Select, Button, Row, Col, Alert } from 'antd'
import { Formik, Field as FormikField } from 'formik'
import { ExclamationCircleOutlined } from '@ant-design/icons'
import {
fixations,
getFixations,
changeFixations,
hasFixationsSuccess,
} from '../../store/ducks/contract'
import { SelectPeriods } from '../SelectPeriods'
import Fixations from '../Tables/Fixations'
import FormatPeriodDate from '../FormatPeriodDate'
import { uuid, Error } from '../../utils'
import { getSelects } from '../../utils/fixations'
import moment from 'moment'
import { ModalUpdateOptimization } from './index'
const FormItem = Form.Item
const { Option } = Select
const { confirm } = Modal
class ModalManageFixations extends React.Component {
constructor(props) {
super(props)
this.state = {
edited: false,
periods: null,
currentPeriod: null,
amountFixed: null,
amountRemaining: null,
}
}
/**
* Calculates the already fixed and the remaining to fix.
* @param {Object} period
*/
calculateTotal(period) {
const { maxFixation } = this.state
const countAmountFixed = period.fixations.reduce(
(result, { amount }) => result + amount,
0,
)
this.setState({
currentPeriod: period,
amountFixed: countAmountFixed,
amountRemaining: maxFixation - countAmountFixed,
})
}
/**
* Initializes the value of state currentPeriod.
* @param {Number} id Get the ID of the selected period.
*/
handleChangeSelectPeriod(id) {
const period = this.state.periods.filter(period => period.id === id)[0]
this.setState({ currentPeriod: period })
this.calculateTotal(period)
}
handleChangeSelectAmount(fixation) {
this.setState({
edited: true,
currentPeriod: this.state.currentPeriod.fixations.map(f => {
if (f.id === fixation.id) f.amount = fixation.value
return f
}),
})
this.calculateTotal(this.state.currentPeriod)
}
handleDeleteFixation(fixation) {
const currentPeriod = this.state.currentPeriod
currentPeriod.fixations = currentPeriod.fixations.filter(
fix => fix.id !== fixation.id,
)
this.setState({
edited: true,
currentPeriod: currentPeriod,
})
this.calculateTotal(this.state.currentPeriod)
}
/**
* Add an fixation in the table.
* @param {*} fixation
*/
handleAddFixation(fixation) {
const currentPeriod = this.state.currentPeriod
const sortedFixations = [...currentPeriod.fixations, fixation].sort(
(a, b) => new Date(a.date) - new Date(b.date),
)
currentPeriod.fixations = sortedFixations
this.setState({
edited: true,
currentPeriod: currentPeriod,
})
}
componentDidMount() {
this.props.getFixations(this.props.contract.id)
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (!nextProps.fixations) return
this.setState({
maxFixation: nextProps.fixations.contract.maxFixation,
periods: nextProps.fixations.periods,
})
}
render() {
const {
t,
contract,
fixations,
toggleModal,
hasChangeFixationsSuccess,
} = this.props
const {
periods,
currentPeriod,
amountFixed,
amountRemaining,
maxFixation,
} = this.state
return (
<Modal
title={t('modal.manage_fixations.title')}
centered
visible={true}
cancelText={t('global.cancel')}
okText={t('global.save')}
onOk={() => {
if (!this.state.edited) return
this.setState({
modalWaiting: true,
})
this.props.changeFixations(this.props.contract.id, {
contract: this.props.contract,
periods: this.state.periods,
})
}}
onCancel={() => {
if (this.state.edited) {
return confirm({
title: t('modal.manage_fixations.cancelled.title'),
icon: <ExclamationCircleOutlined />,
content: t('modal.manage_fixations.cancelled.description'),
okText: t('global.yes'),
onOk() {
toggleModal()
},
})
} else {
toggleModal()
}
}}
maskClosable={false}
width={'700px'}
>
<h2>{contract.name}</h2>
<p>{t('modal.manage_fixations.description')}</p>
{this.state.modalWaiting && <ModalUpdateOptimization />}
<SelectPeriods
granularity={fixations && fixations.contract.fixationGranularity}
periods={periods}
data={this.handleChangeSelectPeriod.bind(this)}
/>
{currentPeriod && (
<div className="page-createfixation" style={{ marginTop: '20px' }}>
<h2>
Fixations for{' '}
<FormatPeriodDate
granularity={
fixations && fixations.contract.fixationGranularity
}
date={currentPeriod}
/>
</h2>
<div
style={{
marginBottom: '10px',
display: 'flex',
justifyContent: 'space-between',
}}
>
<div>
Already fixed: <b>{amountFixed}%</b>
</div>
<div>
Remaining to fix : <b>{amountRemaining}%</b>
</div>
</div>
<Fixations
fixations={[
...currentPeriod.fixations.filter(f => f.type === 'initial'),
...currentPeriod.fixations.filter(f => f.type !== 'initial'),
]}
granularity={fixations && fixations.contract.fixationGranularity}
maxFixation={maxFixation}
amountFixed={amountFixed}
data={this.handleChangeSelectAmount.bind(this)}
deleteFixation={this.handleDeleteFixation.bind(this)}
/>
<h2>Add a fixation</h2>
{amountFixed === fixations.contract.maxFixation && (
<Alert
message={t('form.add_fixation.rate.error.maxRate')}
type="warning"
style={{ marginBottom: '1em' }}
showIcon
/>
)}
<Formik
initialValues={{
fixation_date: '',
fixation_rate: '',
}}
onSubmit={(values, actions) => {
const data = {
id: uuid(),
type: 'external',
date: moment(values.fixation_date).format('YYYY-MM-DD'),
amount: values.fixation_rate,
}
this.handleAddFixation(data)
this.calculateTotal(currentPeriod)
actions.resetForm({})
actions.setSubmitting(false)
}}
>
{props => {
const {
submitForm,
setFieldValue,
values,
validateForm,
} = props
const getNumbersSelect = getSelects()
const maxDate = fixations.contract.end
const validateFixationDate = value => {
let error
if (!value) error = t('form.add_fixation.date.error.required')
return error
}
const validateFixationRate = value => {
let error
if (!value) error = t('form.add_fixation.rate.error.required')
if (value < 5)
error = t('form.add_fixation.rate.error.limitFive')
return error
}
return (
<div>
<Row style={{ alignItems: 'center' }}>
<Col xs={7} lg={7}>
<FormItem label={t('form.add_fixation.date.label')}>
<FormikField
name="fixation_date"
validate={validateFixationDate}
>
{({ field }) => (
<DatePicker
{...field}
onChange={value => {
setFieldValue('fixation_date', value)
}}
size={'large'}
disabled={
amountFixed === fixations.contract.maxFixation
}
format="dddd D MMMM YYYY"
label={t('form.add_fixation.date.placeholder')}
disabledDate={d =>
!d || d.isSameOrAfter(maxDate)
}
/>
)}
</FormikField>
<Error name="fixation_date" />
</FormItem>
</Col>
<Col xs={15} lg={7}>
<FormItem
label={t('form.add_fixation.rate.label')}
style={{
marginLeft: '3em',
}}
>
<FormikField
name="fixation_rate"
validate={validateFixationRate}
>
{({ field }) => (
<Select
{...field}
onChange={value =>
setFieldValue('fixation_rate', value)
}
value={values.fixation_rate}
disabled={
amountFixed === fixations.contract.maxFixation
}
size={'middle'}
>
{getNumbersSelect.map((number, index) => (
<Option
key={index}
value={number}
name="fixation_rate"
size={'large'}
disabled={
number >
this.state.maxFixation -
this.state.amountFixed
}
>
{number}%
</Option>
))}
</Select>
)}
</FormikField>
<Error name="fixation_rate" />
</FormItem>
</Col>
<Col xs={24} lg={7}>
<Button
className="btn btn-succes btn-outline"
disabled={
amountFixed === fixations.contract.maxFixation
}
onClick={() =>
validateForm().then(() => submitForm())
}
>
{t('global.add')}
</Button>
</Col>
</Row>
</div>
)
}}
</Formik>
</div>
)}
</Modal>
)
}
}
const mapStateToProps = state => ({
fixations: fixations(state),
hasFixationsSuccess: hasFixationsSuccess(state),
isChangeFixationsLoaded: state.contractReducer.loadingChangeStrategy,
})
const mapDispatchToProps = dispatch => ({
getFixations: contractId => dispatch(getFixations(contractId)),
changeFixations: (contractId, data) =>
dispatch(changeFixations(contractId, data)),
})
export default connect(
mapStateToProps,
mapDispatchToProps,
)(withTranslation()(ModalManageFixations))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment