1
0
Fork 0
mirror of https://github.com/betagouv/mon-entreprise synced 2025-02-13 06:05:02 +00:00

feat(lodeom): stylise les switchs

This commit is contained in:
Alice Dahan 2024-12-27 11:03:31 +01:00 committed by liliced
parent b67d0dec5f
commit 617d0ee6df
8 changed files with 239 additions and 83 deletions

View file

@ -2,9 +2,12 @@ import { DottedName } from 'modele-social'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useDispatch } from 'react-redux'
import { styled } from 'styled-components'
import { useEngine } from '@/components/utils/EngineContext'
import { Radio, ToggleGroup } from '@/design-system'
import { Strong } from '@/design-system/typography'
import { Body } from '@/design-system/typography/paragraphs'
import { enregistreLaRéponse } from '@/store/actions/actions'
export default function EffectifSwitch() {
@ -21,16 +24,46 @@ export default function EffectifSwitch() {
}, [currentEffectif, engineEffectif])
return (
<ToggleGroup
value={currentEffectif}
onChange={(value) => {
setCurrentEffectif(value)
dispatch(enregistreLaRéponse(dottedName, `'${value}'`))
}}
aria-label={t("Effectif de l'entreprise")}
>
<Radio value="10">{t('Moins de 50 salariés')}</Radio>
<Radio value="100">{t('Plus de 50 salariés')}</Radio>
</ToggleGroup>
<Container>
<StyledBody id="effectif-switch-label">
<Strong>{t("Effectif de l'entreprise")} :</Strong>
</StyledBody>
<StyledToggleGroup
value={currentEffectif}
onChange={(value) => {
setCurrentEffectif(value)
dispatch(enregistreLaRéponse(dottedName, `'${value}'`))
}}
aria-labelledby="effectif-switch-label"
>
<StyledRadio value="10">{t('Moins de 50 salariés')}</StyledRadio>
<StyledRadio value="100">{t('Plus de 50 salariés')}</StyledRadio>
</StyledToggleGroup>
</Container>
)
}
const Container = styled.div`
text-align: left;
display: flex;
flex-direction: column;
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;
> * {
display: flex;
/* flex-direction: column; */
}
`
const StyledRadio = styled(Radio)`
white-space: nowrap;
> span {
width: 100%;
}
`

View file

@ -1,6 +1,9 @@
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import { Radio, ToggleGroup } from '@/design-system'
import { Strong } from '@/design-system/typography'
import { Body } from '@/design-system/typography/paragraphs'
import { RégularisationMethod } from '@/utils/réductionDeCotisations'
type Props = {
@ -15,28 +18,62 @@ export default function RégularisationSwitch({
const { t } = useTranslation()
return (
<ToggleGroup
value={régularisationMethod}
onChange={(value) => {
setRégularisationMethod(value as RégularisationMethod)
}}
aria-label={t(
'pages.simulateurs.réduction-générale.régularisation.type',
'Type de régularisation'
)}
>
<Radio value="annuelle">
{t(
'pages.simulateurs.réduction-générale.régularisation.annuelle',
'Régularisation annuelle'
)}
</Radio>
<Radio value="progressive">
{t(
'pages.simulateurs.réduction-générale.régularisation.progressive',
'Régularisation progressive'
)}
</Radio>
</ToggleGroup>
<Container>
<StyledBody id="régularisation-switch-label">
<Strong>
{t(
'pages.simulateurs.réduction-générale.régularisation.type',
'Type de régularisation'
)}{' '}
:
</Strong>
</StyledBody>
<StyledToggleGroup
value={régularisationMethod}
onChange={(value) => {
setRégularisationMethod(value as RégularisationMethod)
}}
aria-labelledby="régularisation-switch-label"
>
<StyledRadio value="annuelle">
{t(
'pages.simulateurs.réduction-générale.régularisation.annuelle',
'Régularisation annuelle'
)}
</StyledRadio>
<StyledRadio value="progressive">
{t(
'pages.simulateurs.réduction-générale.régularisation.progressive',
'Régularisation progressive'
)}
</StyledRadio>
</StyledToggleGroup>
</Container>
)
}
const Container = styled.div`
text-align: left;
display: flex;
flex-direction: column;
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;
> * {
display: flex;
/* flex-direction: column; */
}
`
const StyledRadio = styled(Radio)`
white-space: nowrap;
> span {
width: 100%;
}
`

View file

@ -379,7 +379,6 @@ Vous êtes dirigeant d'une SAS(U) ? <2>Accéder au simulateur de revenu dédié<
with a company director, there are <1>3 possible statuses</1> for
you<3>(collaborating spouse</3>, <6>associate spouse</6> or <9>salaried
spouse</9>).
Zone de l'entreprise: Company zone
accessibility:
description: Référentiel Général d'Amélioration de l'Accessibilité (General
Accessibility Improvement Reference System)
@ -1451,6 +1450,7 @@ pages:
included in the simulator.</5>
title: Corporate tax simulator
lodeom:
barème-switch-label: "Scale to be applied :"
legend: Employee's gross salary and applicable Lodeom exemption
meta:
description: Estimated amount of Lodeom exemption. This exemption applies, under
@ -1490,6 +1490,7 @@ pages:
salaries below 3.5 SMIC. This means, for 2024, a total
remuneration not exceeding <2>€6,306.30</2> gross per month.
stage: The Lodeom exemption does not apply to internship bonuses.
zone-switch-label: Company location
médecin:
meta:
description: Calculation of net income after deduction of contributions, based

View file

@ -402,7 +402,6 @@ Vous êtes dirigeant d'une SAS(U) ? <2>Accéder au simulateur de revenu dédié<
"Vous êtes marié(e), pacsé(e) ou en union libre avec un chef dentreprise : il
existe <1>3 statuts possibles</1> pour vous (<3>conjoint collaborateur</3>,
<6>conjoint associé</6> ou <9>conjoint salarié</9>)."
Zone de l'entreprise: Zone de l'entreprise
accessibility:
description: Référentiel Général dAmélioration de lAccessibilité
title: Accessibilité
@ -1544,6 +1543,7 @@ pages:
pas intégrés dans le simulateur.</5>
title: Simulateur d'impôt sur les sociétés
lodeom:
barème-switch-label: "Barème à appliquer :"
legend: Rémunération brute du salarié et exonération Lodeom applicable
meta:
description: Estimation du montant de l'exonération Lodeom. Cette exonération
@ -1587,6 +1587,7 @@ pages:
2024, une rémunération totale qui ne dépasse pas <2>6 306,30 €</2>
bruts par mois.
stage: L'exonération Lodeom ne s'applique pas sur les gratifications de stage.
zone-switch-label: Localisation de l'entreprise
médecin:
meta:
description: Calcul du revenu net après déduction des cotisations à partir du

View file

@ -3,7 +3,7 @@ import { DottedName } from 'modele-social'
import { PublicodesExpression, RuleNode } from 'publicodes'
import { useCallback, useContext } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { styled } from 'styled-components'
import { IStyledComponent, styled } from 'styled-components'
import { ExplicableRule } from '@/components/conversation/Explicable'
import RuleInput from '@/components/conversation/RuleInput'
@ -73,6 +73,7 @@ type SimpleFieldProps = {
showSuggestions?: boolean
label?: string
['aria-label']?: string
labelStyle?: IStyledComponent<'web', object>
}
export function SimpleField(props: SimpleFieldProps) {
@ -82,6 +83,7 @@ export function SimpleField(props: SimpleFieldProps) {
summary,
showSuggestions = false,
label,
labelStyle,
} = props
const dispatch = useDispatch()
const engine = useContext(EngineContext)
@ -95,39 +97,38 @@ export function SimpleField(props: SimpleFieldProps) {
[dispatch]
)
let displayedQuestion =
question ?? evaluateQuestion(engine, engine.getRule(dottedName))
const labelId = useSSRSafeId()
const targetUnit = useSelector(targetUnitSelector)
if (evaluation.nodeValue === null) {
return null
}
let displayedLabel =
label ??
(!displayedQuestion
? rule.title + (rule.rawNode.résumé ? ` ${rule.rawNode.résumé}` : '')
: undefined)
let displayedLabel = label
if (!displayedLabel) {
displayedLabel =
question ?? evaluateQuestion(engine, engine.getRule(dottedName))
}
if (!displayedLabel) {
displayedLabel =
rule.title + (rule.rawNode.résumé ? ` ${rule.rawNode.résumé}` : '')
}
if (meta.requis === 'oui') {
if (displayedLabel) {
displayedLabel += ' *'
}
if (displayedQuestion) {
displayedQuestion += ' *'
}
}
const markdownComponents = {
p: labelStyle ?? Intro,
}
return (
<FadeIn>
{displayedQuestion ? (
<StyledQuestion id={labelId}>
<Markdown components={{ p: Intro }}>{displayedQuestion}</Markdown>
<ExplicableRule dottedName={dottedName} />
</StyledQuestion>
) : (
<Spacing sm />
)}
<StyledQuestion id={labelId}>
<Markdown components={markdownComponents}>{displayedLabel}</Markdown>
<ExplicableRule dottedName={dottedName} />
</StyledQuestion>
{summary && <SmallBody>{summary ?? rule.rawNode.résumé}</SmallBody>}
<RuleInput
dottedName={dottedName}
@ -136,8 +137,7 @@ export function SimpleField(props: SimpleFieldProps) {
? targetUnit
: undefined
}
aria-labelledby={displayedQuestion ? labelId : undefined}
label={displayedLabel}
aria-labelledby={labelId}
required={meta.requis === 'oui'}
missing={
evaluation.nodeValue === undefined ||

View file

@ -1,18 +1,49 @@
import { DottedName } from 'modele-social'
import { renderToString } from 'react-dom/server'
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import { Body } from '@/design-system/typography/paragraphs'
import { useZoneLodeom } from '@/hooks/useZoneLodeom'
import { SimpleField } from '@/pages/assistants/components/Fields'
export default function BarèmeSwitch() {
const { currentZone } = useZoneLodeom()
const { t } = useTranslation()
return (
currentZone && (
<SimpleField
dottedName={
`salarié . cotisations . exonérations . lodeom . ${currentZone} . barèmes` as DottedName
}
/>
<Container>
<SimpleField
dottedName={
`salarié . cotisations . exonérations . lodeom . ${currentZone} . barèmes` as DottedName
}
label={renderToString(
<p>
<strong>
{t(
'pages.simulateurs.lodeom.barème-switch-label',
'Barème à appliquer :'
)}
</strong>
</p>
)}
labelStyle={StyledBody}
/>
</Container>
)
)
}
const Container = styled.div`
text-align: left;
display: flex;
flex-direction: column;
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
margin-bottom: -${({ theme }) => theme.spacings.xl};
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
`

View file

@ -1,6 +1,9 @@
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import { Radio, ToggleGroup } from '@/design-system'
import { Strong } from '@/design-system/typography'
import { Body } from '@/design-system/typography/paragraphs'
import { useZoneLodeom } from '@/hooks/useZoneLodeom'
export default function ZoneSwitch() {
@ -8,17 +11,53 @@ export default function ZoneSwitch() {
const { t } = useTranslation()
return (
<ToggleGroup
value={currentZone}
onChange={(value) => {
updateZone(value)
}}
aria-label={t("Zone de l'entreprise")}
>
<Radio value="zone un">
{t('Guadeloupe, Guyane, Martinique, La Réunion')}
</Radio>
<Radio value="zone deux">{t('Saint-Barthélémy, Saint-Martin')}</Radio>
</ToggleGroup>
<Container>
<StyledBody id="zone-switch-label">
<Strong>
{t(
'pages.simulateurs.lodeom.zone-switch-label',
"Localisation de l'entreprise"
)}{' '}
:
</Strong>
</StyledBody>
<StyledToggleGroup
value={currentZone}
onChange={updateZone}
aria-labelledby="zone-switch-label"
>
<StyledRadio value="zone un">
{t('Guadeloupe, Guyane, Martinique, La Réunion')}
</StyledRadio>
<StyledRadio value="zone deux">
{t('Saint-Barthélémy, Saint-Martin')}
</StyledRadio>
</StyledToggleGroup>
</Container>
)
}
const Container = styled.div`
text-align: left;
display: flex;
flex-direction: column;
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;
> * {
display: flex;
flex-direction: column;
}
`
const StyledRadio = styled(Radio)`
white-space: nowrap;
> span {
width: 100%;
}
`

View file

@ -6,7 +6,7 @@ import { styled } from 'styled-components'
import { useEngine } from '@/components/utils/EngineContext'
import { Radio, ToggleGroup } from '@/design-system'
import { FlexCenter } from '@/design-system/global-style'
import { Strong } from '@/design-system/typography'
import { Body } from '@/design-system/typography/paragraphs'
import { enregistreLaRéponse } from '@/store/actions/actions'
import { réductionGénéraleDottedName } from '@/utils/réductionDeCotisations'
@ -30,9 +30,9 @@ export default function CongésPayésSwitch() {
return (
<Container>
<StyledBody id="caisse-congés-payés-label">
{engine.getRule(dottedName).title}
<Strong>{engine.getRule(dottedName).title} :</Strong>
</StyledBody>
<ToggleGroup
<StyledToggleGroup
value={currentCongésPayés}
onChange={(value) => {
setCurrentCongésPayés(value)
@ -40,19 +40,33 @@ export default function CongésPayésSwitch() {
}}
aria-labelledby="caisse-congés-payés-label"
>
<Radio value="oui">{t('Oui')}</Radio>
<Radio value="non">{t('Non')}</Radio>
</ToggleGroup>
<StyledRadio value="oui">{t('Oui')}</StyledRadio>
<StyledRadio value="non">{t('Non')}</StyledRadio>
</StyledToggleGroup>
</Container>
)
}
const Container = styled.div`
${FlexCenter}
text-align: left;
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;
> * {
display: flex;
}
`
const StyledRadio = styled(Radio)`
white-space: nowrap;
> span {
width: 100%;
}
`