🐛 répare le site embauche.beta.gouv

pull/439/head
Johan Girod 2019-01-23 18:04:22 +01:00
parent e07c480a45
commit 5cc443ac12
35 changed files with 290 additions and 172 deletions

View File

@ -1,3 +1,34 @@
# 302 Redirect following URL changes (waiting the hostname change to mon-entreprise.fr for 301)
[[redirects]]
from = "https://embauche.beta.gouv.fr/règle/contrat-salarié--salaire--net-après-impôt"
to = "https://embauche.beta.gouv.fr/documentation/contrat-salarié/salaire/net-après-impôt"
status = 302
[[redirects]]
from = "https://embauche.beta.gouv.fr/règle/prime-de-fin-de-contrat"
to = "https://embauche.beta.gouv.fr/documentation/contrat-salarié/CDD/prime-de-fin-de-contrat"
status = 302
[[redirects]]
from = "https://embauche.beta.gouv.fr/règle/contrat-salarié--salaire--brut-de-base"
to = "https://embauche.beta.gouv.fr/documentation/contrat-salarié/salaire/brut-de-base"
status = 302
[[redirects]]
from = "https://embauche.beta.gouv.fr/règle/contrat-salarié--rémunération-total"
to = "https://embauche.beta.gouv.fr/documentation/contrat-salarié/rémunération/total"
status = 302
[[redirects]]
from = "https://embauche.beta.gouv.fr/règle/contribution-au-dialogue-social"
to = "https://embauche.beta.gouv.fr/documentation/contrat-salarié/contribution-au-dialogue-social"
status = 302
[[redirects]]
from = "https://embauche.beta.gouv.fr/règle/contrat-salarié--CDD--motif--complément-formation"
to = "https://embauche.beta.gouv.fr/documentation/contrat-salarié/CDD/motif/complément-formation"
status = 302
# InFrance PRODUCTION settings
[[redirects]]

View File

@ -48,7 +48,12 @@ const AnswerList = ({
</h2>
<p style={{ textAlign: 'center' }}>
{emoji('🗑')}{' '}
<button className="ui__ link-button" onClick={resetSimulation}>
<button
className="ui__ link-button"
onClick={() => {
resetSimulation()
onClose()
}}>
<Trans>Effacer</Trans>
</button>
</p>

View File

@ -10,6 +10,7 @@
border: none;
text-align: inherit;
font-family: inherit;
padding: 0;
font-weight: inherit;
min-width: 0;
outline: none;

View File

@ -1,6 +1,6 @@
import { findRuleByDottedName, nestedSituationToPathMap } from 'Engine/rules'
import { compose, filter, map, toPairs } from 'ramda'
import React from 'react'
import React, { useEffect } from 'react'
import emoji from 'react-easy-emoji'
import { Trans, translate } from 'react-i18next'
import { connect } from 'react-redux'
@ -8,27 +8,50 @@ import { batchActions } from 'redux-batched-actions'
import { change, Field, reduxForm } from 'redux-form'
import {
flatRulesSelector,
situationSelector
situationSelector,
situationsWithDefaultsSelector
} from 'Selectors/analyseSelectors'
import './PeriodSwitch.css'
export default compose(
reduxForm({
form: 'conversation',
destroyOnUnmount: false,
initialValues: { période: 'année' }
destroyOnUnmount: false
}),
translate(),
connect(
state => ({
rules: flatRulesSelector(state),
situation: nestedSituationToPathMap(situationSelector(state))
}),
state => {
let situation = situationsWithDefaultsSelector(state)
if (Array.isArray(situation)) {
situation = situation[0]
}
return {
rules: flatRulesSelector(state),
situation: nestedSituationToPathMap(situationSelector(state)),
initialPériode: situation.période
}
},
dispatch => ({
batchPeriodChange: actions => dispatch(batchActions(actions))
})
)
)(function PeriodSwitch({ situation, rules, batchPeriodChange }) {
)(function PeriodSwitch({
situation,
rules,
batchPeriodChange,
initialPériode
}) {
useEffect(() => {
!situation.période &&
updateSituation(
initialPériode || 'année',
batchPeriodChange,
situation,
rules
)
return
})
return (
<div id="PeriodSwitch">
<label>

View File

@ -3,13 +3,8 @@
}
.rule-page__header {
display: flex;
margin-bottom: 0.6rem;
justify-content: space-between;
margin-bottom: 1rem;
text-decoration: none;
}
.rule-page__search {
align-self: flex-end;
text-decoration: none;
}
#situationBranch {

View File

@ -1,6 +1,5 @@
import { goBackToSimulation } from 'Actions/actions'
import { ScrollToTop } from 'Components/utils/Scroll'
import withSitePaths from 'Components/utils/withSitePaths'
import { encodeRuleName } from 'Engine/rules'
import {
decodeRuleName,
@ -23,7 +22,6 @@ import Namespace from './rule/Namespace'
import Rule from './rule/Rule'
import './RulePage.css'
import SearchButton from './SearchButton'
import backSvg from 'Images/back.svg'
export default compose(
connect(state => ({
@ -31,7 +29,7 @@ export default compose(
flatRules: flatRulesSelector(state),
brancheName: situationBranchNameSelector(state)
})),
withSitePaths,
withNamespaces()
)(
class RulePage extends Component {
@ -57,23 +55,14 @@ export default compose(
return this.renderRule(dottedName)
}
renderRule(dottedName) {
let { brancheName, sitePaths } = this.props
let { brancheName } = this.props
return (
<div id="RulePage">
<div id="RulePage" className="ui__ container">
<ScrollToTop key={brancheName + dottedName} />
<div className="rule-page__header">
{this.props.valuesToShow ? (
<BackToSimulation />
) : (
<span>
{emoji('🧾')}{' '}
<Link to={sitePaths.sécuritéSociale.index}>
Calculer vos cotisations
</Link>
</span>
)}
{this.props.valuesToShow ? <BackToSimulation /> : <span />}
{brancheName && <span id="situationBranch">{brancheName}</span>}
<SearchButton className="rule-page__search" rulePageBasePath="" />
<SearchButton />
</div>
<Rule dottedName={dottedName} />
</div>
@ -95,11 +84,8 @@ const BackToSimulation = compose(
render() {
let { goBackToSimulation } = this.props
return (
<button
style={{ display: 'flex', alignItems: 'center' }}
className="ui__ link-button"
onClick={goBackToSimulation}>
<img src={backSvg} style={{ marginRight: '0.3em', width: '1.2em' }} />
<button className="ui__ link-button" onClick={goBackToSimulation}>
{emoji('⬅️')}
<Trans i18nKey="back">Reprendre la simulation</Trans>
</button>
)

View File

@ -26,6 +26,6 @@
}
.result-view__body {
border-top-left-radius: 0;
border-top-left-radius: 0 !important;
margin-bottom: 2em;
}

View File

@ -49,7 +49,7 @@ export default class SalaryCompactExplanation extends Component<Props, State> {
</button>
))}
</div>
<SearchButton rulePageBasePath="./règle" />
<SearchButton />
</div>
<div className="ui__ card result-view__body">
{this.state.resultView === 'payslip' ? (

View File

@ -2,17 +2,10 @@
import Distribution from 'Components/Distribution'
import PaySlip from 'Components/PaySlip'
import SearchButton from 'Components/SearchButton'
import withTracker from 'Components/utils/withTracker'
import { compose } from 'ramda'
import React, { Component } from 'react'
import { Trans } from 'react-i18next'
import { connect } from 'react-redux'
import ficheDePaieSelectors from 'Selectors/ficheDePaieSelectors'
import type { Tracker } from 'Components/utils/withTracker'
export default class SalaryFirstExplanation extends Component<Props, State> {
export default class SalaryFirstExplanation extends Component {
render() {
return (
<>

View File

@ -1,12 +1,11 @@
import { compose } from 'ramda'
import React, { Component } from 'react'
import emoji from 'react-easy-emoji'
import { Trans, withNamespaces } from 'react-i18next'
import { connect } from 'react-redux'
import { flatRulesSelector } from 'Selectors/analyseSelectors'
import { LinkButton } from 'Ui/Button'
import Overlay from './Overlay'
import SearchBar from './SearchBar'
import emoji from 'react-easy-emoji'
export default compose(
connect(state => ({
@ -49,15 +48,12 @@ export default compose(
/>
</Overlay>
) : (
<LinkButton
onClick={() => this.setState({ visible: true })}
className={this.props.className}
style={this.props.style}>
{emoji('🔍 ')}
<span>
<Trans>Rechercher</Trans>
</span>
</LinkButton>
<button
className="ui__ link-button"
onClick={() => this.setState({ visible: true })}>
{emoji('🔍')}
<Trans>Rechercher</Trans>
</button>
)
}
}

View File

@ -1,8 +1,3 @@
#targetsContainer {
border-radius: 0.6em;
box-shadow: 0 1px 3px 0 #d4d4d5, 0 0 0 1px #d4d4d5;
}
#targetSelection h1 {
margin: 0.6em;
color: inherit;
@ -12,17 +7,22 @@
#targetSelection #targets {
list-style: none;
padding: 0 0.5em;
padding: 0;
margin: 0;
}
#targetSelection #targets > li:last-child {
margin-bottom: 0;
margin-bottom: -1rem;
border-bottom: none;
}
#targetSelection #targets > li:first-child {
margin-top: -1rem;
}
#targetSelection #targets > li {
padding: 0.6em;
border-bottom: 1px solid rgba(255, 255, 255, 0.5);
margin: 0;
padding: 0.6rem 1rem;
margin-left: -1rem;
margin-right: -1rem;
}
#targetSelection #targets > li .main {
display: flex;
@ -72,18 +72,16 @@
text-decoration: underline;
}
@media (hover: none) {
#targetSelection .optionTitle {
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 0.25em;
padding: 0.05em .4em;
font-size: 125%;
font-weight: 400;
}
@media (hover: none) {
#targetSelection .optionTitle {
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 0.25em;
padding: 0.05em 0.4em;
font-size: 125%;
font-weight: 400;
}
}
#targetSelection #labelNew {
background: #e2011c; /* Couleur de la marianne */
border-radius: 0.3em;
@ -103,14 +101,16 @@
#targetSelection #aidesGlimpse a {
font-weight: 300;
}
#targetSelection .editable {
#targetSelection .editable:not(.attractClick) {
border: 2px solid rgba(0, 0, 0, 0);
border-bottom: 1px dashed #ffffff91;
min-width: 2.5em;
margin: 0.2rem 0.6rem;
display: inline-block;
}
#targetSelection .attractClick.editable {
height: 2.6rem;
#targetSelection .attractClick.editable::before {
content: '€';
}
#targetSelection .attractClick,
@ -120,10 +120,9 @@
text-align: right;
background: rgba(255, 255, 255, 0.2);
cursor: text;
font-weight: 500;
padding: 0;
padding: 0.2em 0.5em;
border-radius: 0.2em;
padding: 0.2rem 0.6rem;
border-radius: 0.3rem;
border: 2px solid;
font-size: inherit;
}

View File

@ -18,10 +18,11 @@ import {
flatRulesSelector,
noUserInputSelector
} from 'Selectors/analyseSelectors'
import Animate from 'Ui/animate'
import AnimatedTargetValue from 'Ui/AnimatedTargetValue'
import CurrencyInput from './CurrencyInput/CurrencyInput'
import './TargetSelection.css'
import QuickLinks from './QuickLinks'
import './TargetSelection.css'
export default compose(
translate(),
@ -59,7 +60,7 @@ export default compose(
<QuickLinks />
{/* <Controls {...{ controls }} /> */}
<section
id="targetsContainer"
className="ui__ plain card"
style={{
color: colours.textColour,
background: `linear-gradient(
@ -118,14 +119,16 @@ export default compose(
/>
</div>
{activeInput === target.dottedName && !conversationStarted && (
<InputSuggestions
suggestions={target.suggestions}
onFirstClick={value =>
this.props.setFormValue(target.dottedName, '' + value)
}
rulePeriod={target.période}
colouredBackground={true}
/>
<Animate.fromTop>
<InputSuggestions
suggestions={target.suggestions}
onFirstClick={value =>
this.props.setFormValue(target.dottedName, '' + value)
}
rulePeriod={target.période}
colouredBackground={true}
/>
</Animate.fromTop>
)}
</li>
))}

View File

@ -1,7 +1,6 @@
#namespace {
padding: 0;
margin: 0;
font-size: medium;
}
#namespace li {

View File

@ -1,6 +1,3 @@
#rule {
margin: 1rem auto;
}
.reportErrorContainer {
text-align: center;
padding: 0.3em 0.6em;
@ -25,6 +22,7 @@ h2 small {
#rule #ruleValue {
font-weight: 400;
text-align: center;
font-size: 200%;
color: inherit;
margin-bottom: 0.6em;

View File

@ -9,7 +9,7 @@ import {
findRuleByDottedName,
findRuleByNamespace
} from 'Engine/rules'
import { compose, isEmpty } from 'ramda'
import { compose, isEmpty, isNil } from 'ramda'
import React, { Component, Suspense } from 'react'
import emoji from 'react-easy-emoji'
import Helmet from 'react-helmet'
@ -24,13 +24,13 @@ import {
ruleAnalysisSelector
} from 'Selectors/analyseSelectors'
import Animate from 'Ui/animate'
import Montant from 'Ui/Montant'
import { AttachDictionary } from '../AttachDictionary'
import Algorithm from './Algorithm'
import Examples from './Examples'
import RuleHeader from './Header'
import References from './References'
import './Rule.css'
import sitePaths from '../../sites/mycompanyinfrance.fr/sitePaths'
let LazySource = React.lazy(() => import('./RuleSource'))
@ -44,6 +44,7 @@ export default compose(
})),
AttachDictionary(knownMecanisms),
withNamespaces(),
withSitePaths,
withLanguage
)(
class Rule extends Component {
@ -54,6 +55,7 @@ export default compose(
currentExample,
flatRules,
valuesToShow,
sitePaths,
analysedExample,
analysedRule,
language
@ -63,7 +65,8 @@ export default compose(
namespaceRules = findRuleByNamespace(flatRules, dottedName)
let displayedRule = analysedExample || analysedRule
let ruleFormat = displayedRule.format || displayedRule.explanation?.format
console.log('ruleFormat', ruleFormat)
return (
<>
{this.state.viewSource ? (
@ -97,26 +100,44 @@ export default compose(
{this.renderToggleSourceButton()}
<section id="rule-content">
{displayedRule.nodeValue ? (
{!isNil(displayedRule.nodeValue) && (
<div id="ruleValue">
{displayedRule.format === 'euros' || displayedRule.formule
? Intl.NumberFormat(language, {
style: 'currency',
currency: 'EUR'
}).format(displayedRule.nodeValue)
: typeof displayedRule.nodeValue !== 'object'
? displayedRule.nodeValue
: null}
{['euros', 'pourcentage'].includes(ruleFormat) ||
displayedRule.formule ? (
<Montant
type={
ruleFormat === 'euros'
? 'currency'
: ruleFormat === 'pourcentage'
? 'percent'
: 'decimal'
}>
{displayedRule.nodeValue}
</Montant>
) : typeof displayedRule.nodeValue !== 'object' ? (
displayedRule.nodeValue
) : null}
</div>
) : null}
)}
{displayedRule.defaultValue != null &&
typeof displayedRule.defaultValue !== 'object' ? (
<div id="ruleDefault">
Valeur par défaut : {displayedRule.defaultValue}
</div>
) : null}
{!valuesToShow && (
<div style={{ textAlign: 'center' }}>
<Link
className="ui__ plain button"
to={
sitePaths.sécuritéSociale
? sitePaths.sécuritéSociale.index
: sitePaths.index
}>
Simuler ma situation
</Link>
</div>
)}
{//flatRule.question &&
// Fonctionnalité intéressante, à implémenter correctement
false && <UserInput {...{ flatRules, dottedName }} />}

View File

@ -15,7 +15,6 @@
}
.Rule-value {
transition: background 0.8s;
font-size: 105%;
}
.Rule-value .unsatisfied {
font-style: italic;

View File

@ -2,10 +2,10 @@ objectifs:
- entreprise . chiffre d'affaires
- revenu disponible
questions:
questions:
- entreprise . charges
questions à l'affiche:
questions à l'affiche:
Charges: entreprise . charges
situation:
@ -16,3 +16,4 @@ situation:
contrat salarié . CDD: non
contrat salarié . temps partiel: non
contrat salarié . ATMP . taux réduit: oui
période: année

View File

@ -2,11 +2,11 @@ objectifs:
- entreprise . chiffre d'affaires
- revenu disponible
questions:
questions:
- entreprise . charges
- entreprise . catégorie d'activité
questions à l'affiche:
questions à l'affiche:
Charges: entreprise . charges
Commerçant, artisan, ou libéral ?: entreprise . catégorie d'activité
@ -14,3 +14,4 @@ situation:
indépendant: oui
micro entreprise: non
contrat salarié: non
période: année

View File

@ -2,11 +2,11 @@ objectifs:
- entreprise . chiffre d'affaires
- revenu disponible
questions:
questions:
- entreprise . catégorie d'activité
- entreprise . charges
questions à l'affiche:
questions à l'affiche:
Charges: entreprise . charges
Commerçant, artisan, ou libéral ?: entreprise . catégorie d'activité
@ -14,3 +14,4 @@ situation:
micro entreprise: oui
indépendant: non
contrat salarié: non
période: année

View File

@ -9,6 +9,9 @@ questions:
- entreprise . catégorie d'activité
- entreprise . charges
situation:
période: année
branches:
- nom: Micro-entreprise
situation:

View File

@ -4,7 +4,7 @@ objectifs:
- contrat salarié . salaire . net
- contrat salarié . salaire . net après impôt
questions à l'affiche:
questions à l'affiche:
CDD: contrat salarié . CDD
Cadre: contrat salarié . statut cadre
Temps partiel: contrat salarié . temps partiel
@ -15,3 +15,4 @@ situation:
contrat salarié . assimilé salarié: non
indépendant: non
micro entreprise: non
période: mois

View File

@ -14,8 +14,10 @@ export default config => SimulationComponent =>
constructor(props) {
super(props)
if (config !== props.config) {
props.resetSimulation()
props.setSimulationConfig(config)
if (props.config) {
props.resetSimulation()
}
}
}
render() {

View File

@ -1,5 +1,4 @@
.Rule-value {
font-size: 105%;
position: relative;
}

View File

@ -119,6 +119,12 @@
font-family: inherit;
margin: 0;
}
.ui__.link-button img[src*='twemoji.maxcdn'],
.ui__.dashed-button img[src*='twemoji.maxcdn'],
.ui__.text-button img[src*='twemoji.maxcdn'] {
margin-right: 0.2rem !important;
margin-left: 0.2rem !important;
}
.ui__.link-button,
.ui__.text-button {
text-decoration: none;

View File

@ -6,7 +6,7 @@ import './Montant.css'
type Props = {
children: number,
className?: string,
type: 'currency' | 'percent',
type: 'currency' | 'percent' | 'decimal',
style?: { [string]: string },
numFractionDigit?: number
} & ConnectedProps

View File

@ -46,6 +46,34 @@ export const fromBottom = ({
))}
</Trail>
)
export const fromTop = ({
children,
config = configPresets.stiff,
style: inheritedStyle = {},
delay = 0
}: Props) => (
<Trail
keys={React.Children.map(children, (_, i) => i)}
native={true}
delay={delay}
config={config}
leave={{ opacity: 0, y: 50 }}
from={{ opacity: 0, y: -50 }}
to={{ opacity: 1, y: 0 }}>
{/* eslint-disable-next-line react/display-name */}
{React.Children.map(children, (item, i) => ({ y, ...style }) => (
<animated.div
key={i}
style={{
transform: y.interpolate(y => `translate3d(0, ${y}px,0)`),
...style,
...inheritedStyle
}}>
{item}
</animated.div>
))}
</Trail>
)
export const leftToRight = ({
children,
@ -122,5 +150,6 @@ export default {
appear,
fromBottom,
leftToRight,
fromTop,
fadeIn
}

View File

@ -40,8 +40,10 @@ button {
.ui__.container {
width: 100%;
max-width: 800px;
margin: auto;
padding: 0 0.6rem;
margin-right: auto;
margin-left: auto;
padding-right: 0.6rem;
padding-left: 0.6rem;
}
.ui__.container .ui__.full-width {
margin: 0 calc((800px - 100vw) / 2);

View File

@ -2782,6 +2782,7 @@
- espace: indépendant . cotisations
nom: retraite complémentaire
période: année
format: euros
notes: Pour les professions libérales, nous avons retenu un des 8 régimes de retraite, celui de la CIPAV, la caisse interprofessionnelle.
formule:
variations:

View File

@ -118,7 +118,7 @@ export let validatedSituationBranchesSelector = createSituationBrancheSelector(
validatedSituationSelector
)
let situationsWithDefaultsSelector = createSelector(
export let situationsWithDefaultsSelector = createSelector(
[ruleDefaultsSelector, situationBranchesSelector],
(defaults, situations) =>
mapOrApply(situation => ({ ...defaults, ...situation }), situations)

View File

@ -7,6 +7,7 @@ import { defaultTracker } from 'Components/utils/withTracker'
import createRavenMiddleware from 'raven-for-redux'
import Raven from 'raven-js'
import React, { Component } from 'react'
import { withNamespaces } from 'react-i18next'
import { Redirect, Route, Switch } from 'react-router-dom'
import 'Ui/index.css'
import Provider from '../../Provider'
@ -28,6 +29,7 @@ import Integration from './pages/Integration'
import IntegrationTest from './pages/IntegrationTest'
import Route404 from './pages/Route404'
import RulesList from './pages/RulesList'
import sitePaths from './sitePaths'
if (process.env.NODE_ENV === 'production') {
Raven.config(
@ -56,42 +58,53 @@ if (process.env.NODE_ENV === 'production') {
}
const middlewares = [createRavenMiddleware(Raven), trackDomainActions(tracker)]
const paths = sitePaths()
class EmbaucheRoute extends Component {
render() {
return (
<Provider
basename="embauche"
initialStore={{
previousSimulation: retrievePersistedSimulation()
previousSimulation: retrievePersistedSimulation(),
form: {
conversation: {
values: {
période: 'mois'
}
}
}
}}
sitePaths={paths}
reduxMiddlewares={middlewares}
tracker={tracker}
onStoreCreated={persistSimulation}>
<TrackPageView />
{!inIframe() && <Header />}
{inIframe() && <DisableScroll />}
<Switch>
<Route exact path="/" component={Home} />
<Route path="/contact" component={Contact} />
<Route path="/règle/:name" component={RulePage} />
<Redirect from="/simu/*" to="/" />
<Route path="/règles" component={RulesList} />
<Route path="/exemples" component={ExampleSituations} />
<Route path="/mecanismes" component={Mecanisms} />
<Route path="/à-propos" component={About} />
<Route path="/intégrer" component={Integration} />
<Route path="/couleur" component={Couleur} />
<Route path="/integration-test" component={IntegrationTest} />
<Redirect from="/simulateur" to="/" />
<Route component={Route404} />
</Switch>
<RouterSwitch />
<PageFeedback blacklist={['/', '/simulation']} />
{inIframe() && <IframeFooter />}
</Provider>
)
}
}
const RouterSwitch = withNamespaces()(() => (
<Switch>
<Route exact path="/" component={Home} />
<Route path="/contact" component={Contact} />
<Route path={paths.documentation.index + '/:name+'} component={RulePage} />
<Route path={paths.documentation.index} component={RulesList} />
<Redirect from="/simu/*" to="/" />
<Route path="/exemples" component={ExampleSituations} />
<Route path="/mecanismes" component={Mecanisms} />
<Route path="/à-propos" component={About} />
<Route path="/intégrer" component={Integration} />
<Route path="/couleur" component={Couleur} />
<Route path="/integration-test" component={IntegrationTest} />
<Redirect from="/simulateur" to="/" />
<Route component={Route404} />
</Switch>
))
let ExportedApp = EmbaucheRoute

View File

@ -0,0 +1,13 @@
/* @flow */
import { constructSitePaths } from '../../utils'
const sitePath = constructSitePaths('', {
index: '',
documentation: {
index: '/documentation',
exemples: '/exemples'
},
contact: '/contact'
})
export default () => sitePath

View File

@ -16,11 +16,13 @@ export let SalarySimulation = withSitePaths(({ sitePaths }) => (
<T k="simulation-end.hiring.text">
Vous pouvez maintenant concrétiser votre projet d'embauche.
</T>
<div style={{ textAlign: 'center' }}>
<Link className="ui__ button" to={sitePaths.démarcheEmbauche.index}>
<T k="simulation-end.cta">Connaître les démarches</T>
</Link>
</div>
{sitePaths.démarcheEmbauche && (
<div style={{ textAlign: 'center' }}>
<Link className="ui__ button" to={sitePaths.démarcheEmbauche.index}>
<T k="simulation-end.cta">Connaître les démarches</T>
</Link>
</div>
)}
</>
}
targets={<TargetSelection />}

View File

@ -1,6 +1,7 @@
/* @flow */
import { map, reduce, toPairs, zipObj } from 'ramda'
import { reduce, toPairs, zipObj } from 'ramda'
import i18n from '../../i18n'
import { constructSitePaths } from '../../utils'
import type { LegalStatus } from 'Selectors/companyStatusSelectors'
export const LANDING_LEGAL_STATUS_LIST: Array<LegalStatus> = [
@ -88,21 +89,6 @@ const constructLocalizedSitePath = language => {
}
})
}
const constructSitePaths = (
root: string,
{ index, ...sitePaths }: { index: string }
) => ({
index: root + index,
...map(
value =>
typeof value === 'string'
? root + index + value
: typeof value === 'function'
? (...args) => root + index + value(...args)
: constructSitePaths(root + index, value),
sitePaths
)
})
let sitePath = constructLocalizedSitePath()
i18n.on('languageChanged', () => {

View File

@ -82,3 +82,19 @@ export function softCatch<ArgType: any, ReturnType: any>(
}
}
}
export const constructSitePaths = (
root: string,
{ index, ...sitePaths }: { index: string }
) => ({
index: root + index,
...map(
value =>
typeof value === 'string'
? root + index + value
: typeof value === 'function'
? (...args) => root + index + value(...args)
: constructSitePaths(root + index, value),
sitePaths
)
})

View File

@ -1521,7 +1521,7 @@ babel-polyfill@^6.26.0:
core-js "^2.5.0"
regenerator-runtime "^0.10.5"
babel-runtime@6.x, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.25.0, babel-runtime@^6.26.0:
babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.25.0, babel-runtime@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
dependencies:
@ -6880,13 +6880,6 @@ raw-loader@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa"
rc-progress@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-2.2.6.tgz#d5d07c07333b352a9ef13230c5940e13336c1e62"
dependencies:
babel-runtime "6.x"
prop-types "^15.5.8"
rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"