mon-entreprise/source/components/TargetSelection.js

216 lines
5.6 KiB
JavaScript
Raw Normal View History

2017-11-15 09:49:55 +00:00
import React, { Component } from 'react'
import { Trans, translate } from 'react-i18next'
import formValueTypes from 'Components/conversation/formValueTypes'
import { findRuleByName } from 'Engine/rules'
import { propEq, curry } from 'ramda'
import './TargetSelection.css'
import BlueButton from './BlueButton'
import { Field, reduxForm, formValueSelector, change } from 'redux-form'
2018-03-29 09:50:34 +00:00
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { RuleValue } from './rule/RuleValueVignette'
2018-03-14 17:20:09 +00:00
import classNames from 'classnames'
2018-04-25 13:55:17 +00:00
import ProgressCircle from './ProgressCircle/ProgressCircle'
import InputSuggestions from 'Components/conversation/InputSuggestions'
import { buildValidationFunction } from './conversation/FormDecorator'
2018-03-15 11:18:21 +00:00
export let salaries = ['salaire total', 'salaire de base', 'salaire net']
export let popularTargetNames = [...salaries, 'aides employeur']
@translate()
@reduxForm({
form: 'conversation',
destroyOnUnmount: false
})
@connect(
state => ({
getTargetValue: dottedName =>
formValueSelector('conversation')(state, dottedName),
targets: state.analysis ? state.analysis.targets : [],
flatRules: state.flatRules,
conversationStarted: state.conversationStarted,
activeInput: state.activeTargetInput
}),
dispatch => ({
setFormValue: (field, name) =>
dispatch(change('conversation', field, name)),
startConversation: () => dispatch({ type: 'START_CONVERSATION' }),
setActiveInput: name => dispatch({ type: 'SET_ACTIVE_TARGET_INPUT', name })
})
)
2017-11-15 09:49:55 +00:00
export default class TargetSelection extends Component {
render() {
let { targets, conversationStarted, colours, activeInput } = this.props
this.firstEstimationComplete = activeInput && targets.length > 0
2017-11-15 09:49:55 +00:00
return (
2018-03-14 17:20:09 +00:00
<div id="targetSelection">
2018-03-12 09:38:29 +00:00
<section
2018-03-14 17:20:09 +00:00
id="targetsContainer"
2018-03-12 09:38:29 +00:00
style={{
background: colours.colour,
color: colours.textColour
}}>
2018-03-12 09:38:29 +00:00
{this.renderOutputList()}
</section>
{!this.firstEstimationComplete && (
<h1>
<Trans i18nKey="enterSalary">Entrez un salaire mensuel</Trans>
</h1>
)}
{this.firstEstimationComplete &&
!conversationStarted && (
<div id="action">
<p>
<b>
<Trans>Estimation approximative</Trans>
</b>{' '}
<br />
<Trans i18nKey="defaults">pour un CDI non cadre</Trans>
</p>
<BlueButton onClick={this.props.startConversation}>
2018-04-24 08:29:40 +00:00
<Trans>Affiner le calcul</Trans>
</BlueButton>
</div>
)}
2018-03-14 17:20:09 +00:00
</div>
2017-11-15 09:49:55 +00:00
)
}
renderOutputList() {
let popularTargets = popularTargetNames.map(
curry(findRuleByName)(this.props.flatRules)
),
{ conversationStarted, activeInput, setActiveInput, targets } = this.props
2017-11-15 09:49:55 +00:00
return (
<div>
2018-03-22 17:54:19 +00:00
<ul id="targets">
{popularTargets.map(target => (
<li key={target.name}>
<div className="main">
<Header
{...{
target,
conversationStarted,
isActiveInput: activeInput === target.dottedName
}}
/>
<TargetInputOrValue
{...{
target,
targets,
firstEstimationComplete: this.firstEstimationComplete,
activeInput,
setActiveInput,
setFormValue: this.props.setFormValue
}}
/>
</div>
{activeInput === target.dottedName &&
!conversationStarted && (
<InputSuggestions
suggestions={target.suggestions}
onFirstClick={value =>
this.props.setFormValue(target.dottedName, '' + value)
}
colouredBackground={true}
/>
)}
2018-03-22 17:54:19 +00:00
</li>
))}
2018-03-22 17:54:19 +00:00
</ul>
</div>
2017-11-15 09:49:55 +00:00
)
}
}
let Header = ({ target, conversationStarted, isActiveInput }) => {
return (
<span className="header">
{conversationStarted && (
<ProgressCircle target={target} isActiveInput={isActiveInput} />
)}
2018-04-09 12:19:48 +00:00
<span className="texts">
<span className="optionTitle">
<Link to={'/règle/' + target.dottedName}>
{target.title || target.name}
</Link>
</span>
{!conversationStarted && <p>{target['résumé']}</p>}
</span>
</span>
)
}
let validate = buildValidationFunction(formValueTypes['euros'])
let InputComponent = ({ input, meta: { dirty, error } }) => (
<span>
{dirty && error && <span className="input-error">{error}</span>}
<input type="number" {...input} autoFocus />
</span>
)
let TargetInputOrValue = ({
target,
targets,
firstEstimationComplete,
activeInput,
2018-04-09 12:19:48 +00:00
setActiveInput
}) => (
<span className="targetInputOrValue">
{activeInput === target.dottedName ? (
<Field
name={target.dottedName}
component={InputComponent}
type="text"
validate={validate}
/>
) : (
<TargetValue {...{ targets, target, activeInput, setActiveInput }} />
)}
{(firstEstimationComplete || target.question) && (
<span className="unit"></span>
)}
</span>
)
@connect(
() => ({}),
dispatch => ({
setFormValue: (field, name) => dispatch(change('conversation', field, name))
})
)
class TargetValue extends Component {
render() {
let {
targets,
target,
setFormValue,
activeInput,
setActiveInput
} = this.props,
targetWithValue = targets.find(propEq('dottedName', target.dottedName)),
value = targetWithValue && targetWithValue.nodeValue,
humanValue = value != null && value.toFixed(0)
return (
<span
className={classNames({
editable: target.question,
attractClick: target.question && targets.length === 0
})}
onClick={() => {
if (!target.question) return
if (value != null) {
setFormValue(target.dottedName, humanValue + '')
setFormValue(activeInput, '')
}
setActiveInput(target.dottedName)
}}>
<RuleValue value={value} />
</span>
)
}
}