Sauvegarde l'état entre deux reload

pull/2782/head
Johan Girod 2023-06-19 15:51:17 +02:00
parent 88ec1cc2f6
commit f6f478767a
23 changed files with 156 additions and 429 deletions

View File

@ -5,11 +5,6 @@ entreprise . associés:
possibilités:
- unique
- multiples
non applicable si:
une de ces conditions:
- entreprise . catégorie juridique = 'EI'
- entreprise . catégorie juridique = 'association'
- entreprise . catégorie juridique = 'autre'
description: |
Si vous êtes le seul associé de votre société, alors vous êtes dans le cas d'une « société unipersonnelle ».
@ -59,25 +54,18 @@ entreprise . catégorie juridique . EI:
une de ces conditions:
- associés . multiples
- entreprise . imposition . IR . type de bénéfices = 'BA'
question: Êtes-vous auto-entrepreneur ?
remplace:
- règle: imposition . régime
par: "'micro-entreprise'"
- règle: entreprise . imposition
par: "'IR'"
- règle: entreprise . imposition . IR
par: oui
- règle: entreprise . imposition . IS
par: non
par défaut:
nom: par défaut
experimental: oui
valeur: oui
EI:
non applicable si: associés . multiples
titre: entreprise individuelle
acronyme: EI
valeur: auto-entrepreneur = non
non applicable si: associés . multiples
### (niveau 1 code 5) Société commerciale ###
@ -90,7 +78,8 @@ entreprise . catégorie juridique . SARL:
SARL:
titre: Société à responsabilité limitée
acronyme: SARL
valeur: associés . multiples
# valeur: associés . multiples
non applicable si: associés . unique
description: |
La société à responsabilité limitée (SARL) comprend au minimum deux associés. Cette forme juridique est la plus répandue pour les sociétés. En revanche, elle ne peut être choisie pour les professions juridiques, judiciaires ou de santé (hors pharmaciens).
@ -172,22 +161,8 @@ entreprise . catégorie juridique . SELARL:
titre: SELARL ou SELARLU
description: Société d'exercice libéral à responsabilité limitée
valeur: catégorie juridique = 'SELARL'
rend non applicable:
- activités . commerciale
- activités . agricole
- activités . artisanale
meta:
code insee: 5485
remplace:
- règle: activités . libérale
par: oui
- règle: activités . libérale . réglementée
par: oui
# TODO : remove when old activity modele is not used anymore :
- règle: entreprise . activité . nature
par: "'libérale'"
- règle: entreprise . activité . nature . libérale . réglementée
par: oui
avec:
SELARLU:
acronyme: SELARLU
@ -205,20 +180,6 @@ entreprise . catégorie juridique . SELAS:
valeur: catégorie juridique = 'SELAS'
meta:
code insee: 5785
rend non applicable:
- activités . commerciale
- activités . agricole
- activités . artisanale
remplace:
- règle: activités . libérale
par: oui
- règle: activités . libérale . réglementée
par: oui
# TODO : remove when old activity modele is not used anymore :
- règle: entreprise . activité . nature
par: "'libérale'"
- règle: entreprise . activité . nature . libérale . réglementée
par: oui
avec:
SELASU:
acronyme: SELASU
@ -238,3 +199,66 @@ entreprise . catégorie juridique . autre:
sévérité: avertissement
description: |
Ce simulateur ne gère pas encore tout les types d'entreprises, le montant affiché pourrait être incorrect.
entreprise . catégorie juridique . remplacements:
# On extrait tous les remplacements dans un espace de nom que l'on peut désactiver pour l'aide au choix du statut par exemple
# Cela permet d'éviter des boucles de dans les missingVariables
experimental: oui
valeur: oui
avec:
régime micro-entreprise:
privé: oui
valeur: EI . auto-entrepreneur
remplace:
- règle: imposition . régime
par: "'micro-entreprise'"
- règle: entreprise . imposition
par: "'IR'"
- règle: entreprise . imposition . IR
par: oui
- règle: entreprise . imposition . IS
par: non
associé unique:
privé: oui
une de ces conditions:
- EI
- SARL . EURL
- SAS . SASU
- SELAS . SELASU
- SELARL . SELARLU
remplace:
- règle: associés
par: "'unique'"
associé multiples:
une de ces conditions:
- SNC
- SARL . SARL
- SAS . SAS
- SELAS . SELAS
- SELARL . SELARL
remplace:
- règle: associés
par: "'unique'"
profession libérale reglementée:
privé: oui
applicable si:
une de ces conditions:
- SELARL
- SELAS
remplace:
- règle: activités . libérale
par: oui
- règle: activités . libérale . réglementée
par: oui
# TODO : remove when old activity modele is not used anymore :
- règle: entreprise . activité . nature
par: "'libérale'"
- règle: entreprise . activité . nature . libérale . réglementée
par: oui
rend non applicable:
- activités . commerciale
- activités . agricole
- activités . artisanale

View File

@ -17,13 +17,13 @@ import {
import { useIsEmbedded } from '@/hooks/useIsEmbedded'
import useSimulationConfig from '@/hooks/useSimulationConfig'
import { situationSelector } from '@/store/selectors/simulationSelectors'
import { Merge, ToOptional } from '@/types/utils'
import { Merge } from '@/types/utils'
import { NextSteps } from '../pages/simulateurs/NextSteps'
import { TrackChapter } from './ATInternetTracking'
import BetaBanner from './BetaBanner'
export default function PageData() {
export default function SimulateurOrAssistantPage() {
const { currentSimulatorData } = useCurrentSimulatorData()
const { pathname, search } = useLocation()
if (!currentSimulatorData) {
@ -41,6 +41,7 @@ export default function PageData() {
component: Component,
seoExplanations: SeoExplanations,
nextSteps,
autoloadLastSimulation,
path,
} = currentSimulatorData
@ -50,7 +51,11 @@ export default function PageData() {
const year = typeof année === 'number' ? `Année ${année}` : ''
const inIframe = useIsEmbedded()
useSimulationConfig({ path, config: simulation })
useSimulationConfig({
key: path,
config: simulation,
autoloadLastSimulation,
})
useSearchParamsSimulationSharing()
const trackInfo = {

View File

@ -10,11 +10,11 @@ import { configSelector } from '@/store/selectors/simulationSelectors'
import { ImmutableType } from '@/types/utils'
export default function useSimulationConfig({
path,
key,
config,
autoloadLastSimulation = false,
}: {
path: string
key: string
config?: ImmutableType<SimulationConfig>
autoloadLastSimulation?: boolean
}) {
@ -22,7 +22,7 @@ export default function useSimulationConfig({
// Initialize redux store in SSR mode
if (import.meta.env.SSR) {
dispatch(setSimulationConfig(config ?? {}, path))
dispatch(setSimulationConfig(config ?? {}, key))
}
const lastConfig = useSelector(configSelector)
@ -35,14 +35,10 @@ export default function useSimulationConfig({
useLayoutEffectWithoutWarnInSSR(() => {
if (config && lastConfig !== config) {
dispatch(setSimulationConfig(config ?? {}, path))
dispatch(setSimulationConfig(config ?? {}, key))
}
}, [config, dispatch, lastConfig, path])
useEffect(() => {
if (autoloadLastSimulation) {
dispatch(loadPreviousSimulation())
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
}, [config, dispatch, lastConfig, key])
}

View File

@ -1,7 +1,5 @@
import { Trans } from 'react-i18next'
import { Grid } from '@/design-system/layout'
import { H1, H3 } from '@/design-system/typography/heading'
import { H3 } from '@/design-system/typography/heading'
import StatutsDisponibles from './StatutsDisponibles'
@ -14,9 +12,6 @@ export default function Layout({
}) {
return (
<>
<H1>
<Trans i18nKey="choix-statut.title">Choisir votre statut</Trans>
</H1>
<Grid container spacing={5}>
<Grid item sm={12} md={7} lg={8}>
<H3 as="h2">{title}</H3>

View File

@ -1,12 +1,12 @@
import { Trans, useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
import styled from 'styled-components'
import { TrackPage } from '@/components/ATInternetTracking'
import { Button } from '@/design-system/buttons'
import { Grid, Spacing } from '@/design-system/layout'
import { useSitePaths } from '@/sitePaths'
import { useNextStep } from './useNextStep'
import { useCurrentStep, useNextStep, usePreviousStep } from './useSteps'
export default function Navigation({
currentStepIsComplete,
@ -23,12 +23,14 @@ export default function Navigation({
}) {
const { t } = useTranslation()
const nextStep = useNextStep()
const navigate = useNavigate()
const resultatPath =
useSitePaths().absoluteSitePaths.assistants['choix-du-statut'].résultat
const currentStep = useCurrentStep()
const previousStep = usePreviousStep()
const choixDuStatutPath =
useSitePaths().absoluteSitePaths.assistants['choix-du-statut']
return (
<>
<TrackPage name={currentStep} />
<Spacing xs />
<StyledNavigation>
<Grid container spacing={2}>
@ -36,10 +38,8 @@ export default function Navigation({
<Button
light
color={'secondary'}
onPress={() => {
onPreviousStep?.()
navigate(-1)
}}
to={choixDuStatutPath[previousStep]}
onPress={onPreviousStep}
>
<span aria-hidden></span> <Trans>Précédent</Trans>
</Button>
@ -48,7 +48,7 @@ export default function Navigation({
<Grid item>
<Button
onPress={onNextStep}
to={nextStep}
to={choixDuStatutPath[nextStep]}
isDisabled={!currentStepIsComplete}
aria-label={t("Suivant, passer à l'étape suivante")}
>
@ -62,7 +62,7 @@ export default function Navigation({
{assistantIsCompleted && (
<Grid item>
<Button
to={resultatPath}
to={choixDuStatutPath['résultat']}
aria-label={t('Suivant, voir le résultat')}
>
{nextStepLabel || (

View File

@ -6,6 +6,7 @@ type ChoixStatut = RelativeSitePaths['assistants']['choix-du-statut']
type Step = keyof ChoixStatut
const stepOrder: readonly Step[] = [
'index',
'recherche-activité',
'détails-activité',
'commune',
@ -13,16 +14,15 @@ const stepOrder: readonly Step[] = [
'associé',
'rémunération',
'statuts',
'résultat',
] as const
export function useNextStep() {
export function useCurrentStep() {
const { relativeSitePaths, absoluteSitePaths } = useSitePaths()
const localizedStep = useMatch(
`${absoluteSitePaths.assistants['choix-du-statut'].index}/:step`
)?.params.step
if (!localizedStep) {
return absoluteSitePaths.assistants['choix-du-statut'][stepOrder[0]]
return 'index'
}
const entries = Object.entries(
@ -32,8 +32,21 @@ export function useNextStep() {
const [currentStep] =
entries.find(([, value]) => value === localizedStep) ?? []
return currentStep
}
export function useNextStep() {
const currentStep = useCurrentStep()
const nextStep =
stepOrder[currentStep ? stepOrder.indexOf(currentStep) + 1 : 0]
return absoluteSitePaths.assistants['choix-du-statut'][nextStep]
return nextStep
}
export function usePreviousStep() {
const currentStep = useCurrentStep()
const previousStep =
stepOrder[currentStep ? stepOrder.indexOf(currentStep) - 1 : 0]
return previousStep
}

View File

@ -25,19 +25,20 @@ export default function Associés() {
<HelpButtonWithPopover
title={t(
'choix-statut.associés.help.title',
'Être associé(e) ou actionnaire'
'Être plusieurs associé(e)s ou actionnaires'
)}
type="info"
>
<Body>
Vous{' '}
<Strong>
partagez la propriété de votre entreprise avec dautres
personnes qui peuvent être physiques (individus) ou morales
(sociétés)
</Strong>
. Dans le cas des <Strong>sociétés par actions</Strong> (SASU,
SAS), on parle d<Strong>actionnaires</Strong>.
Vous <Strong>partagez la propriété de votre entreprise </Strong>
avec dautres personnes qui peuvent être{' '}
<Strong>physiques</Strong> (individus) ou{' '}
<Strong>morales</Strong> (sociétés).
</Body>
<Body>
Dans le cas des <Strong>sociétés par actions</Strong> (SASU,
SAS), on parle d
<Strong>actionnaires</Strong>.
</Body>
</HelpButtonWithPopover>
</Trans>
@ -86,10 +87,7 @@ function useAssociésSelection(): [
const associés = useEngine().evaluate('entreprise . associés').nodeValue as
| RadioOption
| undefined
console.log(
useEngine().evaluate('entreprise . associés'),
useEngine().evaluate('entreprise . catégorie juridique')
)
const [currentSelection, setCurrentSelection] =
useState<RadioOption>(associés)

View File

@ -26,11 +26,14 @@ export function choixStatutJuridiqueConfig({
'SASU, EURL, auto-entrepreneur, EIRL : choisissez le statut qui vous convient le mieux grâce à cet assistant'
),
},
title: t(
'pages.choix-statut.title',
'Assistant au choix du statut juridique'
),
title: t('pages.choix-statut.title', 'Choisir votre statut'),
shortName: t('pages.choix-statut.shortname', 'Assistant statut juridique'),
component: ChoixDuStatut,
simulation: {
situation: {
'entreprise . catégorie juridique . remplacements': 'non',
},
},
autoloadLastSimulation: true,
} as const)
}

View File

@ -85,6 +85,7 @@ export default function DétailsActivité() {
onGuichetSelected={(code) => {
setCodeGuichet(code)
}}
codeGuichet={codeGuichet}
/>
)}
<Navigation

View File

@ -1,8 +1,7 @@
import { Trans, useTranslation } from 'react-i18next'
import { Trans } from 'react-i18next'
import { TrackPage } from '@/components/ATInternetTracking'
import PageHeader from '@/components/PageHeader'
import Meta from '@/components/utils/Meta'
import { Message } from '@/design-system'
import { Button } from '@/design-system/buttons'
import { ClockIcon } from '@/design-system/icons'
@ -12,31 +11,22 @@ import { H3 } from '@/design-system/typography/heading'
import { Body, Intro, SmallBody } from '@/design-system/typography/paragraphs'
import useSimulatorsData from '@/hooks/useSimulatorsData'
import { SimulateurCard } from '@/pages/simulateurs-et-assistants'
import { useSitePaths } from '@/sitePaths'
import { useNextStep } from './_components/useNextStep'
import { useNextStep } from './_components/useSteps'
import créerSvg from './_illustrations/créer.svg'
export default function AccueilChoixStatut() {
const { t } = useTranslation()
const simulateurData = useSimulatorsData()
const nextStep = useNextStep()
const choixStatutPath =
useSitePaths().absoluteSitePaths.assistants['choix-du-statut']
return (
<>
<TrackPage name="accueil" />
<Meta
title={t('choix-statut.meta.title', 'Choisir votre statut')}
description={t('choix-statut.meta.description', 'Choisir votre statut')}
ogImage={créerSvg}
/>
<PageHeader
titre={
<Trans i18nKey="choix-statut.home.title">Choisir votre statut</Trans>
}
picture={créerSvg}
>
<PageHeader picture={créerSvg}>
<Intro>
<Trans i18nKey="choix-statut.home.intro">
La première étape consiste à choisir un{' '}
@ -58,7 +48,7 @@ export default function AccueilChoixStatut() {
<Grid container spacing={3} style={{ alignItems: 'center' }}>
<Grid item xs={12} sm={'auto'}>
<Button size="XL" to={nextStep}>
<Button size="XL" to={choixStatutPath[nextStep]}>
<Trans i18nKey="choix-statut.home.find-statut">
Trouver le bon statut
</Trans>

View File

@ -1,8 +1,9 @@
import { Route, Routes, useLocation } from 'react-router-dom'
import { Route, Routes } from 'react-router-dom'
import { ScrollToTop } from '@/components/utils/Scroll'
import { useSitePaths } from '@/sitePaths'
import { useCurrentStep } from './_components/useSteps'
import Association from './association'
import Associé from './associé'
import Commune from './commune'
@ -15,12 +16,12 @@ import Statuts from './statuts'
export default function ChoixDuStatut() {
const { relativeSitePaths } = useSitePaths()
const location = useLocation()
const currentStep = useCurrentStep()
const childrenPaths = relativeSitePaths.assistants['choix-du-statut']
return (
<>
<ScrollToTop key={location.pathname} />
<ScrollToTop key={currentStep} />
<Routes>
<Route index element={<AccueilChoixStatut />} />
<Route

View File

@ -57,7 +57,6 @@ export default function RechercheActivité() {
<Navigation
currentStepIsComplete={!!codeApe}
onNextStep={() => {
console.log('yaaaaaay')
dispatch(
updateSituation(
'entreprise . activités . principale . code APE',

View File

@ -50,7 +50,7 @@ const config: SimulationConfig = {
export default function AideDéclarationIndépendant() {
const { absoluteSitePaths } = useSitePaths()
useSimulationConfig({
path: absoluteSitePaths.assistants[
key: absoluteSitePaths.assistants[
'déclaration-charges-sociales-indépendant'
],
config,

View File

@ -41,7 +41,7 @@ const config: SimulationConfig = {
export default function AideDéclarationIndépendant() {
const { absoluteSitePaths } = useSitePaths()
useSimulationConfig({
path: absoluteSitePaths.assistants.déclarationIndépendant.index,
key: absoluteSitePaths.assistants.déclarationIndépendant.index,
config,
autoloadLastSimulation: true,
})

View File

@ -36,7 +36,7 @@ const LazyEndBlock = import.meta.env.SSR
const config = { situation: { dirigeant: 'non' } }
export default function PageMobilité() {
useSimulationConfig({ path: 'page-mobilité', config })
useSimulationConfig({ key: 'page-mobilité', config })
const engine = new Engine(formulaire)
return (

View File

@ -1,280 +0,0 @@
import { Trans, useTranslation } from 'react-i18next'
import { connect, useSelector } from 'react-redux'
import { TrackPage } from '@/components/ATInternetTracking'
import { FromBottom } from '@/components/ui/animate'
import { CheckItem, Checklist, ChecklistProps } from '@/components/ui/Checklist'
import DefaultHelmet from '@/components/utils/DefaultHelmet'
import { H1, H2, H3 } from '@/design-system/typography/heading'
import { Link } from '@/design-system/typography/link'
import { Li, Ul } from '@/design-system/typography/list'
import { Body } from '@/design-system/typography/paragraphs'
import {
checkHiringItem,
initializeHiringChecklist,
} from '@/store/actions/hiringChecklistAction'
import { RootState } from '@/store/reducers/rootReducer'
import { SimulatorRessourceCard } from '../simulateurs/cards/SimulatorRessourceCard'
type EmbaucherProps = {
onChecklistInitialization: ChecklistProps['onInitialization']
onItemCheck: ChecklistProps['onItemCheck']
}
function Embaucher({ onChecklistInitialization, onItemCheck }: EmbaucherProps) {
const { t } = useTranslation()
const hiringChecklist = useSelector(
(state: RootState) => state.choixStatutJuridique.hiringChecklist
)
return (
<FromBottom>
<TrackPage name="embaucher" />
<DefaultHelmet>
<title>
{t('embauche.tâches.page.titre', {
defaultValue: 'Les formalités pour embaucher',
})}
</title>
<meta
name="description"
content={t(
'embauche.tâches.page.description',
"Toutes les démarches nécessaires à l'embauche de votre premier salarié."
)}
/>
</DefaultHelmet>
<H1>
<Trans i18nKey="embauche.tâches.titre">
Les formalités pour embaucher
</Trans>
</H1>
<Body>
<Trans i18nKey="embauche.tâches.description">
Toutes les étapes nécessaires à l'embauche de votre premier employé.
</Trans>
</Body>
<Checklist
onInitialization={onChecklistInitialization}
onItemCheck={onItemCheck}
defaultChecked={hiringChecklist}
>
<CheckItem
name="contract"
title={t(
'embauche.tâches.contrat.titre',
'Signer un contrat de travail avec votre employé'
)}
explanations={
<Body>
<a
href="https://www.service-public.fr/particuliers/vosdroits/N19871"
target="_blank"
rel="noreferrer"
aria-label="Plus d'informations sur service-public.fr, nouvelle fenêtre"
>
{' '}
<Trans>Plus d'informations</Trans>
</a>
</Body>
}
/>
<CheckItem
name="dpae"
title={t(
'embauche.tâches.dpae.titre',
"Déclarer l'embauche à l'administration sociale"
)}
explanations={
<Body>
<Trans i18nKey="embauche.tâches.dpae.description">
Ceci peut être fait par le biais du formulaire appelé DPAE, doit
être complété dans les 8 jours avant toute embauche, et peut{' '}
<a
href="https://www.due.urssaf.fr"
target="_blank"
rel="noreferrer"
aria-label={t(
'embauche.tâches.dpae.ariaLabel',
"être effectué en ligne, accéder au site de l'URSSAF, nouvelle fenêtre"
)}
>
être effectué en ligne
</a>
.
</Trans>
</Body>
}
/>
<CheckItem
name="paySoftware"
title={t(
'embauche.tâches.logiciel de paie.titre',
'Choisir un logiciel de paie'
)}
explanations={
<Body>
<Trans i18nKey="embauche.tâches.logiciel de paie.description">
Les fiches de paie et les déclarations peuvent être traitées en
ligne gratuitement par le{' '}
<a
href="http://www.letese.urssaf.fr"
target="_blank"
rel="noreferrer"
>
Tese
</a>
. Vous pouvez aussi utiliser un{' '}
<a
href="http://www.dsn-info.fr/convention-charte.htm"
target="_blank"
rel="noreferrer"
aria-label={t(
'embauche.tâches.logiciel de paie.ariaLabel',
'logiciel de paie privé, voir des exemples sur dsn-info.fr, nouvelle fenêtre'
)}
>
logiciel de paie privé.
</a>
</Trans>
</Body>
}
/>
<CheckItem
name="registre"
title={t(
'embauche.tâches.registre.titre',
'Tenir un registre des employés à jour'
)}
explanations={
<Body>
<a
href="https://www.service-public.fr/professionnels-entreprises/vosdroits/F1784"
target="_blank"
rel="noreferrer"
aria-label={t(
"Plus d'informations sur service-public.fr, nouvelle fenêtre"
)}
>
<Trans>Plus d'informations</Trans>
</a>
</Body>
}
/>
<CheckItem
name="complementaryPension"
title={t(
'embauche.tâches.pension.titre',
"Prendre contact avec l'institution de prévoyance complémentaire obligatoire qui vous est assignée"
)}
explanations={
<Body>
<a
href="https://www.espace-entreprise.services-retraite.fr/prod-simape-cmc-ihm/#/connaitre-ma-caisse"
target="_blank"
rel="noreferrer"
aria-label={t(
'embauche.tâches.pension.aria-label',
'Trouver mon institution de prévoyance, nouvelle fenêtre'
)}
>
<Trans i18nKey="embauche.tâches.pension.description">
Trouver mon institution de prévoyance
</Trans>
</a>
{/* // The AGIRC-ARRCO complementary pension is mandatory. Those are only federations,{' '} */}
</Body>
}
/>
<CheckItem
name="complementaryHealth"
title={t(
'embauche.tâches.prévoyance . santé.titre',
'Choisir une prévoyance . santé'
)}
explanations={
<Body>
<Trans i18nKey="embauche.tâches.prévoyance . santé.description">
Vous devez couvrir vos salariés avec l'assurance complémentaire
santé privée de votre choix (aussi appelée "mutuelle"), pour
autant qu'elle offre un ensemble de garanties minimales.
L'employeur doit payer au moins la moitié du forfait.
</Trans>
</Body>
}
/>
<CheckItem
name="workMedicine"
title={t(
'embauche.tâches.medecine.titre',
"S'inscrire à un bureau de médecine du travail"
)}
explanations={
<Body>
<Trans i18nKey="embauche.tâches.medecine.description">
N'oubliez pas de planifier un rendez-vous initial pour chaque
nouvelle embauche.{' '}
<a href="https://www.service-public.fr/particuliers/vosdroits/F2211">
Plus d'infos.
</a>
</Trans>
</Body>
}
/>
</Checklist>
<Trans i18nKey="embauche.chaque mois">
<H2>Tous les mois</H2>
<Ul>
<Li>
Utiliser un logiciel de paie pour calculer les cotisations sociales
et les transmettre via la déclaration sociale nominative (DSN).
<br />
Certaines offres de service de lUrssaf comme le{' '}
<Link
href="https://www.letese.urssaf.fr"
target="_blank"
rel="noreferrer"
aria-label={t(
'embauche.teseAriaLabel',
"titre emploi service entreprise (Tese), voir plus d'informations sur letese.urssaf.fr, nouvelle fenêtre"
)}
>
titre emploi service entreprise (Tese)
</Link>{' '}
ou le{' '}
<Link
href="https://www.cesu.urssaf.fr"
target="_blank"
rel="noreferrer"
aria-label={t(
'embauche.cesuAriaLabel',
"chèque emploi associatif (CEA), voir plus d'informations sur cesu.urssaf.fr, nouvelle fenêtre"
)}
>
chèque emploi associatif (CEA)
</Link>{' '}
gèrent automatiquement la transmission de la DSN pour vous.
</Li>
<Li>Remettre la fiche de paie à votre employé</Li>
</Ul>
</Trans>
<H3 as="h2">
<Trans i18nKey="common.useful-resources">Ressources utiles</Trans>
</H3>
<SimulatorRessourceCard simulatorId="salarié" />
</FromBottom>
)
}
export default connect(
(state: RootState) => ({
hiringChecklist: state.choixStatutJuridique.hiringChecklist,
}),
{
onChecklistInitialization: initializeHiringChecklist,
onItemCheck: checkHiringItem,
}
)(Embaucher)

View File

@ -2,14 +2,12 @@ import { Trans } from 'react-i18next'
import { Navigate, Route, Routes, useLocation } from 'react-router-dom'
import { TrackChapter } from '@/components/ATInternetTracking'
import PageData from '@/components/PageData'
import SimulateurOrAssistantPage from '@/components/SimulateurOrAssistantPage'
import { ScrollToTop } from '@/components/utils/Scroll'
import { Link } from '@/design-system/typography/link'
import useSimulatorsData from '@/hooks/useSimulatorsData'
import { useSitePaths } from '@/sitePaths'
import ChoixDuStatut from './choix-du-statut'
import Embaucher from './embaucher'
import SocialSecurity from './sécurité-sociale'
export default function Gérer() {
@ -46,23 +44,7 @@ export default function Gérer() {
</TrackChapter>
}
/>
<Route
path={relativeSitePaths.assistants.embaucher}
element={
<TrackChapter chapter1="gerer">
{back}
<Embaucher />
</TrackChapter>
}
/>
<Route
path={relativeSitePaths.assistants['choix-du-statut'].index + '/*'}
element={
<TrackChapter chapter1="creer">
<ChoixDuStatut />
</TrackChapter>
}
/>
{Object.entries(simulateurs)
.filter(([, simu]) => simu.pathId.startsWith('assistants.'))
.map(([, simu]) => (
@ -73,7 +55,7 @@ export default function Gérer() {
}
element={
<>
<PageData />
<SimulateurOrAssistantPage />
</>
}
/>

View File

@ -288,7 +288,7 @@ const UlInColumns = styled.ul`
const AskCompanyMissingDetails = () => {
const { absoluteSitePaths } = useSitePaths()
useSimulationConfig({
path: absoluteSitePaths.assistants.index,
key: absoluteSitePaths.assistants.index,
config: configCompanyDetails,
})

View File

@ -1,10 +1,10 @@
import { Helmet } from 'react-helmet-async'
import { Route, Routes, useLocation } from 'react-router-dom'
import { Route, Routes } from 'react-router-dom'
import Route404 from '@/components/Route404'
import useSimulatorsData from '@/hooks/useSimulatorsData'
import SimulateurPage from '../../components/PageData'
import SimulateurOrAssistantPage from '../../components/SimulateurOrAssistantPage'
import IframeFooter from './IframeFooter'
export default function Iframes() {
@ -32,7 +32,7 @@ export default function Iframes() {
<Helmet>
<link rel="canonical" href={s.path} />
</Helmet>
<SimulateurPage />
<SimulateurOrAssistantPage />
</>
}
/>

View File

@ -90,6 +90,8 @@ export interface PageConfig {
nextSteps?: string[]
simulation?: SimulationConfig
autoloadLastSimulation?: boolean
/**
* `component` must be followed by a one-word component for the `yarn build:simulator-data` script to work
* example: `component: MyComponent,`

View File

@ -17,7 +17,7 @@ import useSimulationConfig from '@/hooks/useSimulationConfig'
import { configArtisteAuteur } from './simulationConfig'
export default function ArtisteAuteur() {
useSimulationConfig({ path: 'artiste-auteur', config: configArtisteAuteur })
useSimulationConfig({ key: 'artiste-auteur', config: configArtisteAuteur })
return (
<>

View File

@ -9,7 +9,7 @@ import { useIsEmbedded } from '@/hooks/useIsEmbedded'
import useSimulatorsData from '@/hooks/useSimulatorsData'
import { useSitePaths } from '@/sitePaths'
import SimulateurPage from '../../components/PageData'
import SimulateurOrAssistantPage from '../../components/SimulateurOrAssistantPage'
type State = {
fromGérer?: boolean
@ -42,7 +42,7 @@ export default function Simulateurs() {
path={
s.path.replace(absoluteSitePaths.simulateurs.index, '') + '/*'
}
element={<SimulateurPage />}
element={<SimulateurOrAssistantPage />}
/>
)),
[simulatorsData, absoluteSitePaths]

View File

@ -6,7 +6,6 @@ const rawSitePathsFr = {
index: '',
assistants: {
index: 'assistants',
embaucher: 'embaucher',
sécuritéSociale: 'sécurité-sociale',
formulaireMobilité: 'demande-mobilité',
'recherche-code-ape': 'recherche-code-ape',
@ -92,7 +91,6 @@ const rawSitePathsEn = {
...rawSitePathsFr,
assistants: {
index: 'assistants',
embaucher: 'hiring',
sécuritéSociale: 'social-security',
formulaireMobilité: 'posting-demand',
'recherche-code-ape': 'search-code-ape',