diff --git a/site/cypress/integration/mon-entreprise/reduction-generale.ts b/site/cypress/integration/mon-entreprise/reduction-generale.ts index a99351748..0c840287b 100755 --- a/site/cypress/integration/mon-entreprise/reduction-generale.ts +++ b/site/cypress/integration/mon-entreprise/reduction-generale.ts @@ -208,8 +208,9 @@ describe( .should('have.length', 12) .first() .click() - cy.get('div[id="options-janvier"]').should('be.visible') - cy.get('div[id="options-janvier"] input').type('{selectall}28,15') + cy.get('input[id="option-heures-sup-janvier"]') + .should('be.visible') + .type('{selectall}28,15') cy.get( '#salarié___cotisations___exonérations___réduction_générale-janvier' diff --git a/site/source/locales/ui-en.yaml b/site/source/locales/ui-en.yaml index d94a9c605..bf925987c 100644 --- a/site/source/locales/ui-en.yaml +++ b/site/source/locales/ui-en.yaml @@ -1490,14 +1490,30 @@ pages: caption: "General discount month by month :" options: description: Adds fields to modulate employee activity + heures-sup: + popover: "<0>The number of hours of overtime and complementary work is used to + calculate the general reduction: gross remuneration is compared with + the SMIC increased by this number of hours." label: - heures-complémentaires: Overtime - heures-supplémentaires: Overtime - popover: "<0>The number of hours of overtime or complementary work is used to - calculate the general reduction: gross remuneration is compared with - the SMIC increased by this number of hours.<1>If you have answered - the question on overtime or complementary hours, the value will be - overwritten by the value you enter month by month." + heures-complémentaires: Number of overtime hours + heures-supplémentaires: Number of overtime hours + rémunération-etp: Basic remuneration for a full month + rémunération-heures-complémentaires: Overtime pay + rémunération-heures-supplémentaires: Overtime pay + rémunération-primes: Remuneration not affected by the incomplete month + mois-incomplet: + description: Adds fields to handle incomplete months + rémunération-etp: + popover: <0>Indicate here the remuneration that would have been paid for a full + month, <2>excluding:<4><0>bonuses and other remuneration not + affected by the absence ;<1>remuneration for overtime or + additional hours worked. + rémunération-heures-sup: + popover: <0>Indicate here the remuneration relating to the payment of overtime + or complementary hours. + rémunération-primes: + popover: <0>Indicate here any elements of remuneration not affected by the + absence, such as bonuses. régularisation: annuelle: Annual adjustment progressive: Progressive regularization diff --git a/site/source/locales/ui-fr.yaml b/site/source/locales/ui-fr.yaml index 71e45b7e6..2eea13bef 100644 --- a/site/source/locales/ui-fr.yaml +++ b/site/source/locales/ui-fr.yaml @@ -1584,15 +1584,30 @@ pages: caption: "Réduction générale mois par mois :" options: description: Ajoute des champs pour moduler l'activité du salarié + heures-sup: + popover: "<0>Le nombre d'heures supplémentaires et complémentaires est utilisé + dans le calcul de la réduction générale : la rémunération brute est + comparée au montant du SMIC majoré de ce nombre d'heures." label: - heures-complémentaires: Heures complémentaires - heures-supplémentaires: Heures supplémentaires - popover: "<0>Le nombre d'heures supplémentaires et complémentaires est utilisé - dans le calcul de la réduction générale : la rémunération brute est - comparée au montant du SMIC majoré de ce nombre d'heures.<1>Si - vous avez répondu à la question sur les heures supplémentaires ou - complémentaires, la valeur sera écrasée par celle que vous saisissez - mois par mois." + heures-complémentaires: Nombre d'heures complémentaires + heures-supplémentaires: Nombre d'heures supplémentaires + rémunération-etp: Rémunération de base mois complet + rémunération-heures-complémentaires: Rémunération des heures complémentaires + rémunération-heures-supplémentaires: Rémunération des heures supplémentaires + rémunération-primes: Rémunération non affectée par le mois incomplet + mois-incomplet: + description: Ajoute des champs pour gérer le cas d'un mois incomplet + rémunération-etp: + popover: <0>Indiquez ici la rémunération qui aurait été versée pour un mois + complet, <2>en excluant :<4><0>les primes et autres éléments de + rémunération non affectés par l'absence ;<1>la rémunération des + heures supplémentaires ou complémentaires. + rémunération-heures-sup: + popover: <0>Indiquez ici la rémunération afférente au paiement des heures + supplémentaires ou complémentaires. + rémunération-primes: + popover: <0>Indiquez ici les éléments de rémunération non affectés par + l'absence, comme les primes. régularisation: annuelle: Régularisation annuelle progressive: Régularisation progressive diff --git a/site/source/pages/simulateurs/reduction-generale/components/MonthOptions.tsx b/site/source/pages/simulateurs/reduction-generale/components/MonthOptions.tsx index b15a14b81..3f3e37192 100644 --- a/site/source/pages/simulateurs/reduction-generale/components/MonthOptions.tsx +++ b/site/source/pages/simulateurs/reduction-generale/components/MonthOptions.tsx @@ -1,9 +1,10 @@ +import { useState } from 'react' import { Trans, useTranslation } from 'react-i18next' import { styled } from 'styled-components' import { Appear } from '@/components/ui/animate' import { useEngine } from '@/components/utils/EngineContext' -import { Message, NumberField } from '@/design-system' +import { NumberField } from '@/design-system' import { HelpButtonWithPopover } from '@/design-system/buttons' import { StyledInput, @@ -11,7 +12,13 @@ import { StyledSuffix, } from '@/design-system/field/TextField' import { FlexCenter } from '@/design-system/global-style' +import { RotatingChevronIcon } from '@/design-system/icons' +import { Grid } from '@/design-system/layout' +import { baseTheme } from '@/design-system/theme' +import { Strong } from '@/design-system/typography' +import { Li, Ul } from '@/design-system/typography/list' import { Body, SmallBody } from '@/design-system/typography/paragraphs' +import { useMediaQuery } from '@/hooks/useMediaQuery' import { Options } from '../utils' @@ -30,91 +37,275 @@ export default function MonthOptions({ }: Props) { const { t } = useTranslation() const engine = useEngine() + const [isMoisIncompletVisible, setMoisIncompletVisible] = useState(false) + const isDesktop = useMediaQuery( + `(min-width: ${baseTheme.breakpointsWidth.md})` + ) + const isTempsPartiel = engine.evaluate( 'salarié . contrat . temps de travail . temps partiel' ).nodeValue as boolean - const additionalHours = isTempsPartiel ? 'complémentaires' : 'supplémentaires' + const additionalHours = isTempsPartiel + ? 'heuresComplémentaires' + : 'heuresSupplémentaires' const additionalHoursLabels = { - supplémentaires: t( + heuresSupplémentaires: t( 'pages.simulateurs.réduction-générale.options.label.heures-supplémentaires', - 'Heures supplémentaires' + "Nombre d'heures supplémentaires" ), - complémentaires: t( + heuresComplémentaires: t( 'pages.simulateurs.réduction-générale.options.label.heures-complémentaires', - 'Heures complémentaires' + "Nombre d'heures complémentaires" + ), + } + const additionalHoursRémunérationLabels = { + heuresSupplémentaires: t( + 'pages.simulateurs.réduction-générale.options.label.rémunération-heures-supplémentaires', + 'Rémunération des heures supplémentaires' + ), + heuresComplémentaires: t( + 'pages.simulateurs.réduction-générale.options.label.rémunération-heures-complémentaires', + 'Rémunération des heures complémentaires' ), } - const onChange = (value?: number) => { - const options = { + const onHeuresSupChange = (value?: number) => { + const newOptions = { + ...options, heuresSupplémentaires: 0, heuresComplémentaires: 0, } if (isTempsPartiel) { - options.heuresComplémentaires = value ?? 0 + newOptions.heuresComplémentaires = value ?? 0 } else { - options.heuresSupplémentaires = value ?? 0 + newOptions.heuresSupplémentaires = value ?? 0 } - onOptionsChange(index, options) + onOptionsChange(index, newOptions) + } + + const onRémunérationETPChange = (value?: number) => { + const newOptions = { + ...options, + rémunérationETP: value ?? 0, + } + onOptionsChange(index, newOptions) + } + + const onRémunérationPrimesChange = (value?: number) => { + const newOptions = { + ...options, + rémunérationPrimes: value ?? 0, + } + onOptionsChange(index, newOptions) + } + + const onRémunérationHeuresSupChange = (value?: number) => { + const newOptions = { + ...options, + rémunérationHeuresSup: value ?? 0, + } + onOptionsChange(index, newOptions) } return ( - - - - {additionalHoursLabels[additionalHours]} - - - - - + + + + + {additionalHoursLabels[additionalHours]} + + + + + + + + + + + + - - - - + setMoisIncompletVisible(!isMoisIncompletVisible)} + aria-describedby="options-mois-incomplet-description" + aria-expanded={isMoisIncompletVisible} + aria-controls={`options-mois-incomplet-${month}`} + aria-label={!isMoisIncompletVisible ? t('Déplier') : t('Replier')} + > + Mois incomplet {isDesktop && '(embauche, absences, départ...)'}{' '} + + + + {t( + 'pages.simulateurs.réduction-générale.options.mois-incomplet.description', + "Ajoute des champs pour gérer le cas d'un mois incomplet" + )} + + + {isMoisIncompletVisible && ( + + + + + {t( + 'pages.simulateurs.réduction-générale.options.label.rémunération-etp', + 'Rémunération de base mois complet' + )} + + + + + + + + + + + + + + + + {t( + 'pages.simulateurs.réduction-générale.options.label.rémunération-primes', + 'Rémunération non affectée par le mois incomplet' + )} + + + + + + + + + + + + + + + + {additionalHoursRémunérationLabels[additionalHours]} + + + + + + + + + + + + + )} ) } const HeuresSupplémentairesPopoverContent = () => ( - + Le nombre d'heures supplémentaires et complémentaires est utilisé dans le calcul de la réduction générale : la rémunération brute est comparée au montant du SMIC majoré de ce nombre d'heures. - - Si vous avez répondu à la question sur les heures supplémentaires ou - complémentaires, la valeur sera écrasée par celle que vous saisissez mois - par mois. - ) -const InputContainer = styled.div` - ${FlexCenter} - gap: ${({ theme }) => theme.spacings.md}; -` +const RémunérationETPPopoverContent = () => ( + + + Indiquez ici la rémunération qui aurait été versée pour un mois complet,{' '} + en excluant : + + + +) + +const RémunérationPrimesPopoverContent = () => ( + + + Indiquez ici les éléments de rémunération non affectés par l'absence, + comme les primes. + + +) + +const RémunérationHeuresSupPopoverContent = () => ( + + + Indiquez ici la rémunération afférente au paiement des heures + supplémentaires ou complémentaires. + + +) + const FlexDiv = styled.div` ${FlexCenter} justify-content: end; ` -const StyledSmallBody = styled(SmallBody)` +const StyledLabel = styled(SmallBody)` margin: 0; color: ${({ theme }) => theme.colors.bases.primary[800]}; ` @@ -131,3 +322,13 @@ const NumberFieldContainer = styled.div` } } ` +const StyledButton = styled(SmallBody)` + cursor: pointer; + font-weight: bold; + color: ${({ theme }) => theme.colors.bases.primary[800]}; + margin-top: ${({ theme }) => theme.spacings.xs}; + margin-bottom: 0; + svg { + fill: ${({ theme }) => theme.colors.bases.primary[800]} !important; + } +`