Ajoute le module de retour au simulateur et garde en memoire les
retours déjà effectués startingpull/374/head
parent
c6277328ba
commit
776cbaf7d5
|
@ -6,6 +6,9 @@ import type {
|
|||
StartConversationAction
|
||||
} from 'Types/ActionsTypes'
|
||||
import { deletePersistedSimulation } from '../storage/persistSimulation'
|
||||
import { normalizeBasePath } from '../utils'
|
||||
|
||||
import type { RouterHistory } from 'react-router-dom'
|
||||
|
||||
export function resetSimulation(): ResetSimulationAction {
|
||||
return {
|
||||
|
@ -22,13 +25,18 @@ export const deletePreviousSimulation = () => (
|
|||
deletePersistedSimulation()
|
||||
}
|
||||
|
||||
export function startConversation(
|
||||
priorityNamespace: ?string
|
||||
): StartConversationAction {
|
||||
return {
|
||||
export const startConversation = (priorityNamespace: ?string) => (
|
||||
dispatch: StartConversationAction => void,
|
||||
_: any,
|
||||
history: RouterHistory
|
||||
) => {
|
||||
dispatch({
|
||||
type: 'START_CONVERSATION',
|
||||
...(priorityNamespace ? { priorityNamespace } : {})
|
||||
}
|
||||
})
|
||||
const simulationPath =
|
||||
normalizeBasePath(history.location.pathname) + 'simulation'
|
||||
history.push(simulationPath)
|
||||
}
|
||||
|
||||
// $FlowFixMe
|
||||
|
|
|
@ -9,35 +9,63 @@ import './Feedback.css'
|
|||
import Form from './FeedbackForm'
|
||||
import type { Tracker } from 'Components/utils/withTracker'
|
||||
import type { Location } from 'react-router-dom'
|
||||
import type { Node } from 'react'
|
||||
|
||||
type Props = {
|
||||
location: Location,
|
||||
blacklist: Array<string>,
|
||||
tracker: Tracker
|
||||
customMessage?: Node,
|
||||
tracker: Tracker,
|
||||
customEventName?: string
|
||||
}
|
||||
type State = {
|
||||
showForm: boolean,
|
||||
showThanks: boolean
|
||||
}
|
||||
|
||||
const localStorageKey = (feedback: [string, string]) =>
|
||||
`app::feedback::${feedback.join('::')}`
|
||||
const saveFeedbackOccurrenceInLocalStorage = ([name, path, rating]: [
|
||||
string,
|
||||
string,
|
||||
number
|
||||
]) => {
|
||||
localStorage.setItem(localStorageKey([name, path]), JSON.stringify(rating))
|
||||
}
|
||||
const feedbackAlreadyGiven = (feedback: [string, string]) => {
|
||||
return !!localStorage.getItem(localStorageKey(feedback))
|
||||
}
|
||||
|
||||
class PageFeedback extends Component<Props, State> {
|
||||
static defaultProps = {
|
||||
blacklist: []
|
||||
}
|
||||
state = {
|
||||
showForm: false,
|
||||
showThanks: false
|
||||
feedbackAlreadyGiven: boolean
|
||||
feedbackAlreadyGiven = false
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
showForm: false,
|
||||
showThanks: false
|
||||
}
|
||||
this.feedbackAlreadyGiven = feedbackAlreadyGiven([
|
||||
this.props.customEventName || 'rate page usefulness',
|
||||
this.props.location.pathname
|
||||
])
|
||||
}
|
||||
|
||||
handleFeedback = ({ useful }) => {
|
||||
this.props.tracker.push([
|
||||
'trackEvent',
|
||||
'Feedback',
|
||||
'rate page usefulness',
|
||||
const feedback = [
|
||||
this.props.customEventName || 'rate page usefulness',
|
||||
this.props.location.pathname,
|
||||
useful ? 10 : 0
|
||||
])
|
||||
this.setState({ showThanks: useful, showForm: !useful })
|
||||
]
|
||||
this.props.tracker.push(['trackEvent', 'Feedback', ...feedback])
|
||||
saveFeedbackOccurrenceInLocalStorage(feedback)
|
||||
this.setState({
|
||||
showThanks: useful,
|
||||
showForm: !useful
|
||||
})
|
||||
}
|
||||
handleErrorReporting = () => {
|
||||
this.props.tracker.push([
|
||||
|
@ -49,6 +77,9 @@ class PageFeedback extends Component<Props, State> {
|
|||
this.setState({ showForm: true })
|
||||
}
|
||||
render() {
|
||||
if (this.feedbackAlreadyGiven) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
!this.props.blacklist.includes(this.props.location.pathname) && (
|
||||
<div className="feedback-page ui__ container notice">
|
||||
|
@ -56,9 +87,11 @@ class PageFeedback extends Component<Props, State> {
|
|||
!this.state.showThanks && (
|
||||
<>
|
||||
<div style={{ flex: 1 }}>
|
||||
<Trans i18nKey="feedback.question">
|
||||
Cette page vous a-t-elle été utile ?
|
||||
</Trans>{' '}
|
||||
{this.props.customMessage || (
|
||||
<Trans i18nKey="feedback.question">
|
||||
Cette page vous a-t-elle été utile ?
|
||||
</Trans>
|
||||
)}{' '}
|
||||
<button
|
||||
style={{ marginLeft: '0.4rem' }}
|
||||
className="ui__ link-button"
|
||||
|
@ -75,7 +108,9 @@ class PageFeedback extends Component<Props, State> {
|
|||
<button
|
||||
className="ui__ link-button"
|
||||
onClick={this.handleErrorReporting}>
|
||||
<Trans i18nKey="feedback.reportError">Report an error</Trans>
|
||||
<Trans i18nKey="feedback.reportError">
|
||||
Signaler une erreur
|
||||
</Trans>
|
||||
</button>{' '}
|
||||
</>
|
||||
)}
|
||||
|
@ -105,7 +140,7 @@ const PageFeedbackWithRouter = ({ location, ...props }) => (
|
|||
)
|
||||
|
||||
export default compose(
|
||||
withRouter,
|
||||
translate(),
|
||||
withTracker
|
||||
withTracker,
|
||||
withRouter
|
||||
)(PageFeedbackWithRouter)
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
/* @flow */
|
||||
import { startConversation } from 'Actions/actions'
|
||||
import withLanguage from 'Components/utils/withLanguage'
|
||||
import { toPairs, compose } from 'ramda'
|
||||
import { compose, toPairs } from 'ramda'
|
||||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { connect } from 'react-redux'
|
||||
import { withRouter } from 'react-router'
|
||||
import { animated, Spring } from 'react-spring'
|
||||
import { validInputEnteredSelector } from 'Selectors/analyseSelectors'
|
||||
import type { Location } from 'react-router'
|
||||
|
||||
type Props = {
|
||||
startConversation: (?string) => void
|
||||
startConversation: (?string) => void,
|
||||
location: Location,
|
||||
validInputEntered: boolean
|
||||
}
|
||||
|
||||
let quickLinks = {
|
||||
|
@ -17,22 +24,53 @@ let quickLinks = {
|
|||
Autres: null
|
||||
}
|
||||
|
||||
const QuickLink = ({ startConversation }: Props) => (
|
||||
<>
|
||||
{toPairs(quickLinks).map(([label, dottedName]) => (
|
||||
<button
|
||||
key={label}
|
||||
className="ui__ link-button"
|
||||
onClick={() => startConversation(dottedName)}>
|
||||
<Trans>{label}</Trans>
|
||||
</button>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
const QuickLink = ({
|
||||
startConversation,
|
||||
location,
|
||||
validInputEntered
|
||||
}: Props) => {
|
||||
const show = !location.pathname.endsWith('/simulation') && validInputEntered
|
||||
return (
|
||||
<Spring
|
||||
to={{
|
||||
height: show ? 'auto' : 0,
|
||||
opacity: show ? 1 : 0
|
||||
}}
|
||||
native>
|
||||
{styles => (
|
||||
<animated.div
|
||||
className="ui__ button-container"
|
||||
style={{
|
||||
...styles,
|
||||
display: 'flex',
|
||||
overflow: 'hidden',
|
||||
flexWrap: 'wrap-reverse',
|
||||
fontSize: '110%',
|
||||
justifyContent: 'space-evenly',
|
||||
marginBottom: '0.6rem'
|
||||
}}>
|
||||
{toPairs(quickLinks).map(([label, dottedName]) => (
|
||||
<button
|
||||
key={label}
|
||||
className="ui__ link-button"
|
||||
onClick={() => startConversation(dottedName)}>
|
||||
<Trans>{label}</Trans>
|
||||
</button>
|
||||
))}
|
||||
</animated.div>
|
||||
)}
|
||||
</Spring>
|
||||
)
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withLanguage,
|
||||
withRouter,
|
||||
connect(
|
||||
(state, props) => ({ key: props.language }),
|
||||
(state, props) => ({
|
||||
key: props.language,
|
||||
validInputEntered: validInputEnteredSelector(state)
|
||||
}),
|
||||
{
|
||||
startConversation
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { compose } from 'ramda'
|
|||
import React from 'react'
|
||||
import { withRouter } from 'react-router'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { capitalise0 } from '../utils'
|
||||
import { capitalise0, normalizeBasePath } from '../utils'
|
||||
import './RuleLink.css'
|
||||
import type { Règle } from 'Types/RegleTypes'
|
||||
import type { Match } from 'react-router'
|
||||
|
@ -13,14 +13,18 @@ type Props = Règle & {
|
|||
style: CSSStyleDeclaration,
|
||||
colours: { colour: string }
|
||||
}
|
||||
const RuleLink = ({ lien, nom, colours: { colour }, match, style }: Props) => (
|
||||
<Link
|
||||
to={match.path + (match.path.endsWith('/') ? '' : '/') + lien}
|
||||
className="rule-link"
|
||||
style={{ color: colour, ...style }}>
|
||||
{capitalise0(nom)}
|
||||
</Link>
|
||||
)
|
||||
const RuleLink = ({ lien, nom, colours: { colour }, match, style }: Props) => {
|
||||
const newPath =
|
||||
normalizeBasePath(match.path).replace(/simulation\/$/, '') + lien
|
||||
return (
|
||||
<Link
|
||||
to={newPath}
|
||||
className="rule-link"
|
||||
style={{ color: colour, ...style }}>
|
||||
{capitalise0(nom)}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withRouter,
|
||||
|
|
|
@ -83,7 +83,7 @@ class BackToSimulation extends Component {
|
|||
return (
|
||||
<Link
|
||||
id="toSimulation"
|
||||
to=".."
|
||||
to="../simulation"
|
||||
onClick={() => {
|
||||
setExample(null)
|
||||
}}
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
import { resetSimulation, startConversation } from 'Actions/actions'
|
||||
import { startConversation } from 'Actions/actions'
|
||||
import AnswerList from 'Components/AnswerList'
|
||||
import { ScrollToTop } from 'Components/utils/Scroll'
|
||||
import withColours from 'Components/utils/withColours'
|
||||
import withLanguage from 'Components/utils/withLanguage'
|
||||
import React, { Component } from 'react'
|
||||
import { Trans, translate } from 'react-i18next'
|
||||
import { connect } from 'react-redux'
|
||||
import { Redirect, withRouter } from 'react-router'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { animated, Spring } from 'react-spring'
|
||||
import { reset } from 'redux-form'
|
||||
import {
|
||||
blockingInputControlsSelector,
|
||||
nextStepsSelector,
|
||||
noUserInputSelector
|
||||
noUserInputSelector,
|
||||
validInputEnteredSelector
|
||||
} from 'Selectors/analyseSelectors'
|
||||
import * as Animate from 'Ui/animate'
|
||||
import AnswerList from './AnswerList'
|
||||
import { normalizeBasePath } from '../utils'
|
||||
import Conversation from './conversation/Conversation'
|
||||
import Distribution from './Distribution'
|
||||
import PageFeedback from './Feedback/PageFeedback'
|
||||
import PaySlip from './PaySlip'
|
||||
import QuickLink from './QuickLink'
|
||||
import ResultView from './ResultView'
|
||||
import './Simu.css'
|
||||
import TargetSelection from './TargetSelection'
|
||||
|
||||
@withRouter
|
||||
@withColours
|
||||
@translate() // Triggers rerender when the language changes
|
||||
@connect(
|
||||
state => ({
|
||||
noUserInput: noUserInputSelector(state),
|
||||
blockingInputControls: blockingInputControlsSelector(state),
|
||||
conversationStarted: state.conversationStarted,
|
||||
validInputEntered: validInputEnteredSelector(state),
|
||||
arePreviousAnswers: state.conversationSteps.foldedSteps.length !== 0,
|
||||
nextSteps: state.conversationStarted && nextStepsSelector(state)
|
||||
nextSteps: state.conversationStarted && nextStepsSelector(state),
|
||||
userInput: noUserInputSelector(state)
|
||||
}),
|
||||
dispatch => ({
|
||||
startConversation: () => dispatch(startConversation()),
|
||||
resetSimulation: () => {
|
||||
dispatch(resetSimulation())
|
||||
dispatch(reset('conversation'))
|
||||
}
|
||||
})
|
||||
{
|
||||
startConversation
|
||||
}
|
||||
)
|
||||
@withLanguage
|
||||
class Simu extends Component {
|
||||
class Simulation extends Component {
|
||||
state = {
|
||||
displayPreviousAnswers: false
|
||||
}
|
||||
|
@ -50,141 +50,155 @@ class Simu extends Component {
|
|||
let {
|
||||
colours,
|
||||
conversationStarted,
|
||||
noUserInput,
|
||||
arePreviousAnswers,
|
||||
nextSteps,
|
||||
startConversation,
|
||||
resetSimulation,
|
||||
blockingInputControls
|
||||
blockingInputControls,
|
||||
match,
|
||||
validInputEntered,
|
||||
location
|
||||
} = this.props
|
||||
const firstValidInputEntered =
|
||||
!conversationStarted && !blockingInputControls && !noUserInput
|
||||
const displayConversation = conversationStarted && !blockingInputControls
|
||||
const simulationCompleted =
|
||||
!blockingInputControls && conversationStarted && !nextSteps.length
|
||||
const displayPreviousAnswers =
|
||||
arePreviousAnswers && this.state.displayPreviousAnswers
|
||||
const simulationHomePath = normalizeBasePath(match.path).replace(
|
||||
/simulation\/$/,
|
||||
''
|
||||
)
|
||||
return (
|
||||
<>
|
||||
<div id="simu">
|
||||
{displayConversation && (
|
||||
<button className="ui__ button small" onClick={resetSimulation}>
|
||||
←
|
||||
</button>
|
||||
)}
|
||||
{arePreviousAnswers && (
|
||||
<div className="change-answer-link">
|
||||
<button
|
||||
className="ui__ link-button"
|
||||
onClick={() => this.setState({ displayPreviousAnswers: true })}>
|
||||
<Trans>Modifier mes réponses</Trans>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<Spring
|
||||
to={{
|
||||
height: firstValidInputEntered ? 'auto' : 0,
|
||||
opacity: firstValidInputEntered ? 1 : 0
|
||||
}}
|
||||
native>
|
||||
{styles => (
|
||||
<animated.div
|
||||
className="ui__ button-container"
|
||||
style={{
|
||||
...styles,
|
||||
display: 'flex',
|
||||
overflow: 'hidden',
|
||||
flexWrap: 'wrap-reverse',
|
||||
fontSize: '110%',
|
||||
justifyContent: 'space-evenly',
|
||||
marginBottom: '0.6rem'
|
||||
}}>
|
||||
<QuickLink />
|
||||
</animated.div>
|
||||
)}
|
||||
</Spring>
|
||||
{simulationCompleted && (
|
||||
<QuickLink />
|
||||
{location.pathname.endsWith('/simulation') && (
|
||||
<>
|
||||
<h1>
|
||||
<Trans i18nKey="simulation-end.title">
|
||||
Plus de questions !
|
||||
</Trans>
|
||||
</h1>
|
||||
<p>
|
||||
<Trans i18nKey="simulation-end.text">
|
||||
Vous avez atteint l'estimation la plus précise. Vous pouvez
|
||||
maintenant concrétiser votre projet d'embauche.
|
||||
</Trans>
|
||||
</p>
|
||||
{this.props.displayHiringProcedures && (
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<Link className="ui__ button" to="/hiring-process">
|
||||
<Trans i18nKey="simulation-end.cta">
|
||||
Connaître les démarches
|
||||
</Trans>
|
||||
</Link>
|
||||
{!conversationStarted && <Redirect to={simulationHomePath} />}
|
||||
<Link to={simulationHomePath} style={{ position: 'absolute' }}>
|
||||
<i
|
||||
className="fa fa-arrow-left"
|
||||
aria-hidden="true"
|
||||
style={{ marginRight: '0.5rem' }}
|
||||
/>
|
||||
<Trans>Retour</Trans>
|
||||
</Link>
|
||||
{arePreviousAnswers && (
|
||||
<div className="change-answer-link">
|
||||
<button
|
||||
className="ui__ link-button"
|
||||
onClick={() =>
|
||||
this.setState({ displayPreviousAnswers: true })
|
||||
}>
|
||||
<Trans>Modifier mes réponses</Trans>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<br />
|
||||
{displayPreviousAnswers && (
|
||||
<AnswerList
|
||||
onClose={() =>
|
||||
this.setState({ displayPreviousAnswers: false })
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{simulationCompleted && (
|
||||
<>
|
||||
<h1>
|
||||
<Trans i18nKey="simulation-end.title">
|
||||
Plus de questions !
|
||||
</Trans>
|
||||
</h1>
|
||||
<p>
|
||||
<Trans i18nKey="simulation-end.text">
|
||||
Vous avez atteint l'estimation la plus précise. Vous
|
||||
pouvez maintenant concrétiser votre projet d'embauche.
|
||||
</Trans>
|
||||
</p>
|
||||
{this.props.displayHiringProcedures && (
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<Link className="ui__ button" to="/hiring-process">
|
||||
<Trans i18nKey="simulation-end.cta">
|
||||
Connaître les démarches
|
||||
</Trans>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
<br />
|
||||
</>
|
||||
)}
|
||||
{displayConversation && (
|
||||
<>
|
||||
<ScrollToTop />
|
||||
<Conversation textColourOnWhite={colours.textColourOnWhite} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<div id="focusZone">
|
||||
{displayConversation && (
|
||||
<>
|
||||
<ScrollToTop />
|
||||
<Conversation textColourOnWhite={colours.textColourOnWhite} />
|
||||
</>
|
||||
)}
|
||||
<TargetSelection colours={colours} />
|
||||
</div>
|
||||
{conversationStarted && (
|
||||
<Animate.fromBottom>
|
||||
<ResultView />
|
||||
<div style={{ textAlign: 'center' }} />
|
||||
</Animate.fromBottom>
|
||||
<TargetSelection colours={colours} />
|
||||
{location.pathname.endsWith('/simulation') && (
|
||||
<>
|
||||
{conversationStarted && (
|
||||
<Animate.fromBottom>
|
||||
<ResultView />
|
||||
<div style={{ textAlign: 'center' }} />
|
||||
</Animate.fromBottom>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{displayPreviousAnswers && (
|
||||
<AnswerList
|
||||
onClose={() => this.setState({ displayPreviousAnswers: false })}
|
||||
{validInputEntered && (
|
||||
<PageFeedback
|
||||
customMessage={
|
||||
<Trans i18nKey="feedback.simulator">
|
||||
Ce simulateur vous a plu ?
|
||||
</Trans>
|
||||
}
|
||||
customEventName="rate simulator"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{!location.pathname.endsWith('/simulation') &&
|
||||
validInputEntered && (
|
||||
<Animate.fromBottom>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
{arePreviousAnswers && (
|
||||
<button className="ui__ button" onClick={startConversation}>
|
||||
<Trans>Continuer la simulation</Trans>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<h2>
|
||||
<Trans>A quoi servent mes cotisations ?</Trans>
|
||||
</h2>
|
||||
<Distribution />
|
||||
|
||||
{firstValidInputEntered && (
|
||||
<Animate.fromBottom>
|
||||
<h2>
|
||||
<Trans>A quoi servent mes cotisations ?</Trans>
|
||||
</h2>
|
||||
<Distribution />
|
||||
|
||||
<h2>
|
||||
<Trans>Simulation personnalisée</Trans>
|
||||
</h2>
|
||||
<p>
|
||||
<Trans i18nKey="custom-simulation">
|
||||
Il s'agit pour l'instant d'une
|
||||
<strong> première estimation</strong> sur la base d'un contrat
|
||||
générique. La législation française prévoit une multitude de cas
|
||||
particuliers et de règles spécifiques qui modifient
|
||||
considérablement les montant de l'embauche.
|
||||
</Trans>
|
||||
</p>
|
||||
<p style={{ textAlign: 'center' }}>
|
||||
<button
|
||||
className="ui__ button"
|
||||
onClick={() => startConversation()}>
|
||||
<Trans>Faire une simulation personnalisée</Trans>
|
||||
</button>
|
||||
</p>
|
||||
<h2>
|
||||
<Trans>Fiche de paie</Trans>
|
||||
</h2>
|
||||
<PaySlip />
|
||||
</Animate.fromBottom>
|
||||
)}
|
||||
{!arePreviousAnswers && (
|
||||
<>
|
||||
<h2>
|
||||
<Trans>Simulation personnalisée</Trans>
|
||||
</h2>
|
||||
<p>
|
||||
<Trans i18nKey="custom-simulation">
|
||||
Il s'agit pour l'instant d'une
|
||||
<strong> première estimation</strong> sur la base d'un
|
||||
contrat générique. La législation française prévoit une
|
||||
multitude de cas particuliers et de règles spécifiques qui
|
||||
modifient considérablement les montant de l'embauche.
|
||||
</Trans>
|
||||
</p>
|
||||
<p style={{ textAlign: 'center' }}>
|
||||
<button className="ui__ button" onClick={startConversation}>
|
||||
<Trans>Faire une simulation personnalisée</Trans>
|
||||
</button>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
<h2>
|
||||
<Trans>Fiche de paie</Trans>
|
||||
</h2>
|
||||
<PaySlip />
|
||||
</Animate.fromBottom>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Simu
|
||||
export default Simulation
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
noUserInputSelector
|
||||
} from 'Selectors/analyseSelectors'
|
||||
import { mainTargetNames } from '../config'
|
||||
import { normalizeBasePath } from '../utils'
|
||||
import AnimatedTargetValue from './AnimatedTargetValue'
|
||||
import Controls from './Controls'
|
||||
import CurrencyInput from './CurrencyInput/CurrencyInput'
|
||||
|
@ -160,6 +161,10 @@ let Header = ({
|
|||
blockingInputControls,
|
||||
match
|
||||
}) => {
|
||||
const ruleLink =
|
||||
normalizeBasePath(match.path).replace(/simulation\/$/, '') +
|
||||
'règle/' +
|
||||
encodeRuleName(target.dottedName)
|
||||
return (
|
||||
<span className="header">
|
||||
{conversationStarted &&
|
||||
|
@ -177,9 +182,7 @@ let Header = ({
|
|||
</div>
|
||||
)}
|
||||
<span className="optionTitle">
|
||||
<Link to={match.path + 'règle/' + encodeRuleName(target.dottedName)}>
|
||||
{target.title || target.name}
|
||||
</Link>
|
||||
<Link to={ruleLink}>{target.title || target.name}</Link>
|
||||
</span>
|
||||
{!conversationStarted && <p>{target['résumé']}</p>}
|
||||
</span>
|
||||
|
@ -276,6 +279,7 @@ class TargetValue extends Component {
|
|||
}
|
||||
|
||||
@withColours
|
||||
@withRouter
|
||||
@connect(state => ({ analysis: analysisWithDefaultsSelector(state) }))
|
||||
class AidesGlimpse extends Component {
|
||||
render() {
|
||||
|
@ -289,7 +293,11 @@ class AidesGlimpse extends Component {
|
|||
{' '}
|
||||
- <AnimatedTargetValue value={aides.nodeValue} />{' '}
|
||||
<Link
|
||||
to={'/règle/' + encodeRuleName('contrat salarié . aides employeur')}
|
||||
to={
|
||||
this.props.match.path +
|
||||
'/règle/' +
|
||||
encodeRuleName('contrat salarié . aides employeur')
|
||||
}
|
||||
style={{ color: this.props.colours.textColour }}>
|
||||
<Trans>d'aides</Trans> {emoji(aides.icon)}
|
||||
</Link>
|
||||
|
|
|
@ -153,14 +153,18 @@ simulation-end:
|
|||
text: You have reached the most accurate estimate. You can now turn your hiring project into reality.
|
||||
cta: Know the procedures
|
||||
feedback:
|
||||
simulator: Do you like this simulator ?
|
||||
reportError: Report an error
|
||||
question: Was this information useful to you?
|
||||
bad:
|
||||
form:
|
||||
headline: Your feedback is valuable to us in order to continuously improve this site. What should we work on to better meet your expectations?
|
||||
email: Your email (if you would like an answer from us)
|
||||
thanks: Thank for your feedback! You can contact us directly at <1> </1><2>embauche.beta.gouv.fr</2>
|
||||
thanks: Thank for your feedback! You can contact us directly at <1> </1><2>contact@embauche.beta.gouv.fr</2>
|
||||
Janvier 2019: January 2019
|
||||
d'aides: of aid
|
||||
Oui: Yes
|
||||
Non: No
|
||||
Continuer la simulation: Continue simulation
|
||||
Envoyer: Send
|
||||
Retour: Back
|
||||
|
|
|
@ -132,6 +132,10 @@ export let blockingInputControlsSelector = state => {
|
|||
return analysis && analysis.blockingInputControls
|
||||
}
|
||||
|
||||
export let validInputEnteredSelector = createSelector(
|
||||
[noUserInputSelector, blockingInputControlsSelector],
|
||||
(noUserInput, blockingInputControls) => !noUserInput && !blockingInputControls
|
||||
)
|
||||
// TODO this should really not be fired twice in a user session...
|
||||
//
|
||||
// TODO the just input salary should be in the situation so that it is not a missing variable
|
||||
|
|
|
@ -73,6 +73,7 @@ class EmbaucheRoute extends Component {
|
|||
{inIframe() && <DisableScroll />}
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route exact path="/simulation" component={Home} />
|
||||
<Route path="/contact" component={Contact} />
|
||||
<Route path="/règle/:name" component={RulePage} />
|
||||
<Redirect from="/simu/*" to="/" />
|
||||
|
@ -86,7 +87,7 @@ class EmbaucheRoute extends Component {
|
|||
<Redirect from="/simulateur" to="/" />
|
||||
<Route component={Route404} />
|
||||
</Switch>
|
||||
<PageFeedback blacklist={['/']} />
|
||||
<PageFeedback blacklist={['/', '/simulation']} />
|
||||
{inIframe() && <IframeFooter />}
|
||||
</Provider>
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export let feedbackBlacklist = [
|
||||
'/',
|
||||
'/company/legal-status',
|
||||
'/company/legal-status/number-of-associates'
|
||||
'/company/legal-status/number-of-associates',
|
||||
'/social-security/simulation'
|
||||
]
|
||||
|
|
|
@ -3,6 +3,7 @@ import withColours from 'Components/utils/withColours'
|
|||
import urssafSvg from 'Images/urssaf.svg'
|
||||
import { compose } from 'ramda'
|
||||
import React from 'react'
|
||||
import { withRouter } from 'react-router'
|
||||
import { feedbackBlacklist } from '../../config'
|
||||
import './Footer.css'
|
||||
import betaGouvSvg from './logo-betagouv.svg'
|
||||
|
@ -34,4 +35,7 @@ const Footer = ({ colours: { colour } }) => (
|
|||
</div>
|
||||
)
|
||||
|
||||
export default compose(withColours)(Footer)
|
||||
export default compose(
|
||||
withRouter,
|
||||
withColours
|
||||
)(Footer)
|
||||
|
|
|
@ -46,7 +46,6 @@ const StepsHeader = ({
|
|||
<Progress percent={companyProgress} />
|
||||
</NavLink>
|
||||
<NavLink
|
||||
exact
|
||||
to="/social-security"
|
||||
activeClassName="active"
|
||||
onClick={() =>
|
||||
|
|
|
@ -137,7 +137,7 @@ const HiringProcess = ({
|
|||
</li>
|
||||
<li>Deliver the standardised payslip to your employee</li>
|
||||
</ul>
|
||||
<Link className="ui__ button" to="/social-security">
|
||||
<Link className="ui__ button" to="/social-security/simulation">
|
||||
Get an example payslip
|
||||
</Link>
|
||||
</Animate.fromBottom>
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
import Simulateur from 'Components/Simu'
|
||||
import { ScrollToTop } from 'Components/utils/Scroll'
|
||||
import { compose } from 'ramda'
|
||||
import React, { Component } from 'react'
|
||||
import Helmet from 'react-helmet'
|
||||
import { connect } from 'react-redux'
|
||||
import * as Animate from 'Ui/animate'
|
||||
import type { Match, Location } from 'react-router'
|
||||
|
||||
type Props = {
|
||||
hideText: boolean
|
||||
match: Match,
|
||||
location: Location
|
||||
}
|
||||
class SocialSecurity extends Component<Props, {}> {
|
||||
render() {
|
||||
|
@ -25,7 +25,7 @@ class SocialSecurity extends Component<Props, {}> {
|
|||
</Helmet>
|
||||
<ScrollToTop />
|
||||
<Animate.fromBottom>
|
||||
{!this.props.hideText && (
|
||||
{this.props.match.isExact && (
|
||||
<>
|
||||
<h1>Social protection: costs and benefits</h1>
|
||||
<p>
|
||||
|
@ -70,16 +70,11 @@ class SocialSecurity extends Component<Props, {}> {
|
|||
<h2>How much does it cost to hire ?</h2>
|
||||
</>
|
||||
)}
|
||||
<Simulateur displayHiringProcedures />
|
||||
<Simulateur displayHiringProcedures key={location.pathname} />
|
||||
</Animate.fromBottom>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
connect(
|
||||
state => ({ hideText: state.conversationStarted }),
|
||||
{}
|
||||
)
|
||||
)(SocialSecurity)
|
||||
export default SocialSecurity
|
||||
|
|
|
@ -64,3 +64,6 @@ export function inIframe() {
|
|||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export const normalizeBasePath = (basePath: string) =>
|
||||
basePath + (basePath.endsWith('/') ? '' : '/')
|
||||
|
|
98
yarn.lock
98
yarn.lock
|
@ -1580,7 +1580,7 @@ bluebird@3.5.0:
|
|||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
|
||||
|
||||
bluebird@^3.0.5, bluebird@^3.5.1:
|
||||
bluebird@^3.5.1:
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a"
|
||||
|
||||
|
@ -1931,27 +1931,6 @@ check-more-types@2.24.0:
|
|||
version "2.24.0"
|
||||
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
|
||||
|
||||
cheerio@^0.22.0:
|
||||
version "0.22.0"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
|
||||
dependencies:
|
||||
css-select "~1.2.0"
|
||||
dom-serializer "~0.1.0"
|
||||
entities "~1.1.1"
|
||||
htmlparser2 "^3.9.1"
|
||||
lodash.assignin "^4.0.9"
|
||||
lodash.bind "^4.1.4"
|
||||
lodash.defaults "^4.0.1"
|
||||
lodash.filter "^4.4.0"
|
||||
lodash.flatten "^4.2.0"
|
||||
lodash.foreach "^4.3.0"
|
||||
lodash.map "^4.4.0"
|
||||
lodash.merge "^4.4.0"
|
||||
lodash.pick "^4.2.1"
|
||||
lodash.reduce "^4.4.0"
|
||||
lodash.reject "^4.4.0"
|
||||
lodash.some "^4.4.0"
|
||||
|
||||
cheerio@^1.0.0-rc.2:
|
||||
version "1.0.0-rc.2"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db"
|
||||
|
@ -3173,12 +3152,6 @@ etag@~1.8.1:
|
|||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
|
||||
eval@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/eval/-/eval-0.1.2.tgz#9f7103284c105a66df4030b2b3273165837013da"
|
||||
dependencies:
|
||||
require-like ">= 0.1.1"
|
||||
|
||||
eventemitter3@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163"
|
||||
|
@ -4917,14 +4890,6 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.0.8:
|
|||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
|
||||
|
||||
lodash.assignin@^4.0.9:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
|
||||
|
||||
lodash.bind@^4.1.4:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
|
||||
|
||||
lodash.camelcase@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||
|
@ -4933,18 +4898,10 @@ lodash.debounce@^4.0.8:
|
|||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
|
||||
lodash.defaults@^4.0.1:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
|
||||
|
||||
lodash.escape@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
|
||||
|
||||
lodash.filter@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
|
||||
|
||||
lodash.flatten@^4.2.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
||||
|
@ -4953,10 +4910,6 @@ lodash.flattendeep@^4.4.0:
|
|||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
||||
|
||||
lodash.foreach@^4.3.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
|
@ -4969,35 +4922,15 @@ lodash.isstring@^4.0.1:
|
|||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
|
||||
|
||||
lodash.map@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
|
||||
|
||||
lodash.memoize@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
|
||||
lodash.merge@^4.4.0:
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
|
||||
|
||||
lodash.once@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||
|
||||
lodash.pick@^4.2.1:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||
|
||||
lodash.reduce@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
|
||||
|
||||
lodash.reject@^4.4.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
|
||||
|
||||
lodash.some@^4.4.0, lodash.some@^4.5.1:
|
||||
lodash.some@^4.5.1:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
|
||||
|
||||
|
@ -7073,10 +7006,6 @@ require-from-string@^2.0.1:
|
|||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
|
||||
"require-like@>= 0.1.1":
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa"
|
||||
|
||||
require-main-filename@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
|
||||
|
@ -7439,10 +7368,6 @@ sort-keys@^1.0.0:
|
|||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
source-list-map@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1"
|
||||
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
|
||||
|
@ -7468,7 +7393,7 @@ source-map-url@^0.4.0:
|
|||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||
|
||||
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.3:
|
||||
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
|
||||
|
@ -7536,16 +7461,6 @@ static-extend@^0.1.1:
|
|||
define-property "^0.2.5"
|
||||
object-copy "^0.1.0"
|
||||
|
||||
static-site-generator-webpack-plugin@^3.4.1:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-3.4.1.tgz#6ee22468830bc546798a37e0fca6fd699cc93b81"
|
||||
dependencies:
|
||||
bluebird "^3.0.5"
|
||||
cheerio "^0.22.0"
|
||||
eval "^0.1.0"
|
||||
url "^0.11.0"
|
||||
webpack-sources "^0.2.0"
|
||||
|
||||
"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
|
@ -8299,13 +8214,6 @@ webpack-pwa-manifest@^3.6.2:
|
|||
jimp "^0.2.28"
|
||||
mime "^1.6.0"
|
||||
|
||||
webpack-sources@^0.2.0:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb"
|
||||
dependencies:
|
||||
source-list-map "^1.1.1"
|
||||
source-map "~0.5.3"
|
||||
|
||||
webpack-sources@^1.1.0, webpack-sources@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85"
|
||||
|
|
Loading…
Reference in New Issue