⬆️ Update prettier for supporting =?? syntax

refacto-evaluation-règle
Johan Girod 2020-12-01 10:17:27 +01:00
parent e8722a46bc
commit 6b1915b494
231 changed files with 1774 additions and 1758 deletions

View File

@ -1,22 +1,18 @@
describe('Pole emploi', function() {
it('should display an iframe of the simulateur', function() {
cy.on('uncaught:exception', err => {
describe('Pole emploi', function () {
it('should display an iframe of the simulateur', function () {
cy.on('uncaught:exception', (err) => {
return !err.message.contains('Unexpected token <')
})
cy.visit('https://entreprise.pole-emploi.fr/cout-salarie/')
cy.get('#simulateurEmbauche')
.iframe()
.contains('Salaire net')
cy.get('#simulateurEmbauche').iframe().contains('Salaire net')
})
})
describe('URSSAF', function() {
it('should display an iframe of the simulateur', function() {
describe('URSSAF', function () {
it('should display an iframe of the simulateur', function () {
cy.visit(
'https://www.urssaf.fr/portail/home/utile-et-pratique/estimateur-de-cotisations-2019.html'
)
cy.get('#simulateurEmbauche')
.iframe()
.contains('Salaire net')
cy.get('#simulateurEmbauche').iframe().contains('Salaire net')
})
})

View File

@ -1,15 +1,12 @@
const fr = Cypress.env('language') === 'fr'
const testText = (selector, text) =>
cy.get(`[data-test-id=${selector}]`).should($span => {
const displayedText = $span
.text()
.trim()
.replace(/[\s]/g, ' ')
cy.get(`[data-test-id=${selector}]`).should(($span) => {
const displayedText = $span.text().trim().replace(/[\s]/g, ' ')
console.log(displayedText, text)
expect(displayedText).to.eq(text)
})
describe('Page covid-19', function() {
describe('Page covid-19', function () {
if (!fr) {
return
}

View File

@ -1,6 +1,6 @@
const fr = Cypress.env('language') === 'fr'
describe('Formulaire demande mobilité', function() {
describe('Formulaire demande mobilité', function () {
if (!fr) {
return
}
@ -49,11 +49,7 @@ describe('Formulaire demande mobilité', function() {
.wait(1500)
cy.contains('29240').click()
cy.contains('Organisme Urssaf').click()
cy.focused()
.type('Bretagne')
.tab()
.tab()
.type('Boulangerie')
cy.focused().type('Bretagne').tab().tab().type('Boulangerie')
})
it('should allow to complete "votre demande" section', () => {
cy.contains('Oui').click()
@ -66,9 +62,7 @@ describe('Formulaire demande mobilité', function() {
cy.get("input[name='demande . date de fin connue'][value='oui']")
.next()
.click()
cy.get('label[for="détachement . pays"]')
.wait(1500)
.click()
cy.get('label[for="détachement . pays"]').wait(1500).click()
cy.focused()
.select('Irlande')
.tab()
@ -78,9 +72,7 @@ describe('Formulaire demande mobilité', function() {
.tab()
.tab()
.type('Fabrications de gateaux bretons')
cy.get("input[name='détachement . base fixe'][value='non']")
.next()
.click()
cy.get("input[name='détachement . base fixe'][value='non']").next().click()
cy.get(
"input[name='commentaires additionnels . commentaires'][value='non']"
)

View File

@ -1,27 +1,23 @@
describe('Manage page test', function() {
describe('Manage page test', function () {
const fr = Cypress.env('language') === 'fr'
beforeEach(() => {
cy.visit(fr ? '/gérer' : '/manage')
})
it('should not crash', function() {
it('should not crash', function () {
cy.contains(fr ? 'Gérer mon activité' : 'Manage my business')
})
it('should allow to retrieve company and show link corresponding to the legal status', function() {
it('should allow to retrieve company and show link corresponding to the legal status', function () {
cy.get('button.cta').click()
cy.get('input')
.first()
.type('menoz')
cy.get('input').first().type('menoz')
cy.contains('834364291').click()
cy.contains(fr ? 'simulateur SASU' : 'simulator for SASU').click()
cy.location().should(loc => {
cy.location().should((loc) => {
expect(loc.pathname).to.match(fr ? /dirigeant-sasu$/ : /sasu-chairman$/)
})
})
it('should allow auto entrepreneur to access the corresponding income simulator', function() {
it('should allow auto entrepreneur to access the corresponding income simulator', function () {
cy.get('button.cta').click()
cy.get('input')
.first()
.type('gwenael girod')
cy.get('input').first().type('gwenael girod')
cy.contains('MONSIEUR').click()
// ask if auto-entrepreneur
cy.contains(
@ -31,11 +27,11 @@ describe('Manage page test', function() {
cy.contains(
fr ? 'simulateur auto-entrepreneur' : 'simulator for auto-entrepreneur'
).click()
cy.location().should(loc => {
cy.location().should((loc) => {
expect(loc.pathname).to.match(/auto-entrepreneur$/)
})
})
it('should be able to navigate to the hiring simulator', function() {
it('should be able to navigate to the hiring simulator', function () {
cy.contains(fr ? 'une embauche' : 'hiring').click()
cy.contains(fr ? 'salarié' : 'employee')
})

View File

@ -1,13 +1,11 @@
describe('Iframe integration test', function() {
describe('Iframe integration test', function () {
if (Cypress.env('language') !== 'fr') {
return
}
it('should display an iframe of the simulateur', function() {
it('should display an iframe of the simulateur', function () {
cy.visit('/dev/integration-test')
cy.contains('Visualiser').click()
cy.wait(1000)
cy.get('#simulateurEmbauche')
.iframe()
.contains('Salaire net')
cy.get('#simulateurEmbauche').iframe().contains('Salaire net')
})
})

View File

@ -1,15 +1,15 @@
describe('Landing test', function() {
describe('Landing test', function () {
const fr = Cypress.env('language') === 'fr'
it('should not crash', function() {
it('should not crash', function () {
cy.visit('/')
cy.get('img[alt="logo mon-entreprise.fr"]').should('be.visible')
})
it('should display urssaf and marianne logo', function() {
it('should display urssaf and marianne logo', function () {
cy.visit('/')
cy.get('img[alt="logo urssaf"]').should('be.visible')
cy.get('img[alt="logo marianne"]').should('be.visible')
})
it('should display actionnable items', function() {
it('should display actionnable items', function () {
cy.visit('/')
cy.contains(fr ? 'Créer une entreprise' : 'Create a company')
cy.contains(fr ? 'Gérer mon activité' : 'Manage my business')

View File

@ -1,4 +1,4 @@
describe('Navigation', function() {
describe('Navigation', function () {
const fr = Cypress.env('language') === 'fr'
it('should enable switching site language', () => {
cy.visit(fr ? '/créer/auto-entrepreneur' : '/create/auto-entrepreneur')

View File

@ -1,7 +1,7 @@
const fr = Cypress.env('language') === 'fr'
const inputSelector = 'input.currencyInput__input:not([name$="charges"])'
const chargeInputSelector = 'input.currencyInput__input[name$="charges"]'
describe('Simulateurs', function() {
describe('Simulateurs', function () {
if (!fr) {
return
}
@ -14,11 +14,11 @@ describe('Simulateurs', function() {
'profession-liberale/medecin',
'profession-liberale/sage-femme',
'profession-liberale/auxiliaire-medical',
'profession-liberale/chirurgien-dentiste'
].forEach(simulateur =>
'profession-liberale/chirurgien-dentiste',
].forEach((simulateur) =>
describe(simulateur, () => {
before(() => cy.visit(`/simulateurs/${simulateur}`))
it('should not crash', function() {
it('should not crash', function () {
cy.get(inputSelector)
})
@ -41,12 +41,10 @@ describe('Simulateurs', function() {
})
})
it('should allow to change period', function() {
it('should allow to change period', function () {
cy.contains('€/an').click()
cy.wait(200)
cy.get(inputSelector)
.first()
.type('{selectall}12000')
cy.get(inputSelector).first().type('{selectall}12000')
if (['indépendant', 'dirigeant-sasu'].includes(simulateur)) {
cy.get(chargeInputSelector).type('{selectall}6000')
}
@ -57,59 +55,50 @@ describe('Simulateurs', function() {
.invoke('val')
.should('match', /1[\s]000/)
if (['indépendant', 'dirigeant-sasu'].includes(simulateur)) {
cy.get(chargeInputSelector)
.first()
.invoke('val')
.should('be', '500')
cy.get(chargeInputSelector).first().invoke('val').should('be', '500')
}
cy.contains('€/an').click()
})
it('should allow to navigate to a documentation page', function() {
cy.get(inputSelector)
.first()
.type('{selectall}2000')
it('should allow to navigate to a documentation page', function () {
cy.get(inputSelector).first().type('{selectall}2000')
cy.wait(700)
cy.contains('Cotisations').click()
cy.location().should(loc => {
cy.location().should((loc) => {
expect(loc.pathname).to.match(/\/documentation\/.*\/cotisations/)
})
})
it('should allow to go back to the simulation', function() {
it('should allow to go back to the simulation', function () {
cy.contains('← ').click()
cy.get(inputSelector)
.first()
.invoke('val')
.should('be', '2000')
cy.get(inputSelector).first().invoke('val').should('be', '2000')
})
if (simulateur === 'auto-entrepreneur') {
it('should allow to enter the date of creation', () => {
cy.get(inputSelector)
.first()
.type('{selectall}50000')
cy.contains('Passer').click()
cy.contains('Passer').click()
cy.contains('Début 2020').click()
cy.contains('ACRE')
})
it('should not have negative value', () => {
cy.contains('€/mois').click()
cy.wait(100)
cy.get(inputSelector)
.first()
.type('{selectall}5000')
cy.wait(800)
cy.get(inputSelector).each($input => {
const val = +$input.val().replace(/[\s,.]/g, '')
expect(val).not.to.be.below(4000)
})
})
}
})
)
})
describe('Simulateur auto-entrepreneur', () => {
if (!fr) {
return
}
before(() => cy.visit('/simulateurs/auto-entrepreneur'))
it('should allow to enter the date of creation', () => {
cy.get(inputSelector).first().type('{selectall}50000')
cy.contains('Passer').click()
cy.contains('Début 2020').click()
cy.contains('ACRE')
})
it('should not have negative value', () => {
cy.contains('€/mois').click()
cy.wait(100)
cy.get(inputSelector).first().type('{selectall}5000')
cy.wait(800)
cy.get(inputSelector).each(($input) => {
const val = +$input.val().replace(/[\s,.]/g, '')
expect(val).not.to.be.below(4000)
})
})
})
describe('Simulateur salarié', () => {
if (!fr) {
@ -117,22 +106,8 @@ describe('Simulateur salarié', () => {
}
before(() => cy.visit('/simulateurs/salarié'))
it('should ask for CDD motif directly after CDD is selected', function() {
cy.get(inputSelector)
.eq(1)
.type('{selectall}3000')
cy.wait(1000)
cy.get('.step')
.find('input[value="\'CDD\'"]')
.click({ force: true })
cy.contains('Suivant').click()
cy.contains('Motifs classiques')
})
it('should save the current simulation', function() {
cy.get(inputSelector)
.first()
.type('{selectall}2137')
it('should save the current simulation', function () {
cy.get(inputSelector).first().type('{selectall}2137')
cy.contains('Passer').click()
cy.contains('Passer').click()
cy.contains('Passer').click()
@ -145,32 +120,28 @@ describe('Simulateur salarié', () => {
.should('match', /2[\s]137/)
})
it('should not crash when selecting localisation', function() {
it('should not crash when selecting localisation', function () {
cy.contains('Commune').click()
cy.get('fieldset input[type="search"]').type('Steenvoorde')
cy.contains('Steenvoorde (59114)').click()
cy.contains('Suivant').click()
cy.contains('Voir ma situation').click()
cy.contains('Steenvoorde (59114)')
cy.contains('Steenvoorde')
})
describe('part time contract', () => {
before(() => {
cy.visit('/simulateurs/salarié')
cy.get('input[name$="brut de base"]').click()
cy.get('button')
.contains('SMIC')
.click()
cy.get('button').contains('SMIC').click()
cy.contains('Voir ma situation').click()
cy.contains('Temps partiel').click()
cy.get('input[value="oui"]')
.parent()
.click()
cy.get('input[value="oui"]').parent().click()
cy.wait(100)
})
it('should permit selecting the smic before part-time contrat', () => {
cy.get('input[name$="brut de base"]').should($input => {
cy.get('input[name$="brut de base"]').should(($input) => {
expect(+$input.val().replace(/[\s,.]/g, ''))
.to.be.above(1300)
.and.to.be.below(1500)
@ -180,11 +151,12 @@ describe('Simulateur salarié', () => {
it('should permit customizing the number of worked hours and clear the input value', () => {
cy.contains('Suivant').click()
cy.get('fieldset input[type="text"]').type(25)
cy.get('input[name$="net après impôt"]').should($input => {
cy.get('input[name$="net après impôt"]').should(($input) => {
expect(+$input.val().replace(/[\s,.]/g, '')).to.be.below(1000)
})
cy.get('fieldset input[type="text"]').clear()
cy.get('input[name$="net après impôt"]').should($input => {
cy.get('input[name$="net après impôt"]').should(($input) => {
expect(+$input.val().replace(/[\s,.]/g, '')).to.be.above(1000)
})
})

View File

@ -1,18 +1,18 @@
describe('Status guide', function() {
describe('Status guide', function () {
const fr = Cypress.env('language') === 'fr'
beforeEach(() => {
cy.visit(fr ? '/créer' : '/create')
cy.get('.cta').click()
})
it('should allow to go back clicking on the previous answers', function() {
it('should allow to go back clicking on the previous answers', function () {
cy.get('.ui__.answer-group')
.contains(fr ? 'Seul' : 'Alone')
.click()
cy.contains(fr ? 'Un seul associé' : 'Only one partner').click()
cy.contains(fr ? 'Seul ou à plusieurs' : 'Number of partners')
})
it('should guide thought the SASU status', function() {
it('should guide thought the SASU status', function () {
cy.get('.ui__.answer-group')
.contains(fr ? 'Seul' : 'Alone')
.click()
@ -21,9 +21,7 @@ describe('Status guide', function() {
.click()
// The click fails randomly and unexplicablly on CI
cy.wait(200)
cy.get('.answer-group button')
.contains('Assimilé')
.click()
cy.get('.answer-group button').contains('Assimilé').click()
cy.contains(fr ? 'Créer une SASU' : 'Create a SASU').click()
cy.url().should('match', /\/SASU$/)
})

View File

@ -1,12 +1,12 @@
describe('Navigation', function() {
it('landing should not crash', function() {
describe('Navigation', function () {
it('landing should not crash', function () {
cy.visit('/')
})
it('liste des mécanismes should not crash', function() {
it('liste des mécanismes should not crash', function () {
cy.contains('Liste des mécanismes').click()
cy.contains('barème')
})
it('bac à sable should work', function() {
it('bac à sable should work', function () {
cy.contains('Bac à sable').click()
cy.wait(5000)
cy.contains('Dépenses primeur')

View File

@ -23,8 +23,8 @@
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
Cypress.Commands.add('iframe', { prevSubject: 'element' }, $iframe => {
return new Cypress.Promise(resolve => {
Cypress.Commands.add('iframe', { prevSubject: 'element' }, ($iframe) => {
return new Cypress.Promise((resolve) => {
setTimeout(() => resolve($iframe.contents().find('body')), 6000)
})
})

View File

@ -29,11 +29,11 @@ if (
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/sw.js')
.then(registration => {
.then((registration) => {
// eslint-disable-next-line no-console
console.log('SW registered: ', registration)
})
.catch(registrationError => {
.catch((registrationError) => {
// eslint-disable-next-line no-console
console.log('SW registration failed: ', registrationError)
})
@ -61,12 +61,12 @@ export default function Provider({
initialStore,
onStoreCreated,
children,
sitePaths = {} as SitePaths
sitePaths = {} as SitePaths,
}: ProviderProps) {
const history = useMemo(
() =>
createBrowserHistory({
basename: process.env.NODE_ENV === 'production' ? '' : basename
basename: process.env.NODE_ENV === 'production' ? '' : basename,
}),
[]
)
@ -82,7 +82,7 @@ export default function Provider({
// Allows us to painlessly do route transition in action creators
thunk.withExtraArgument({
history,
sitePaths
sitePaths,
}),
...(reduxMiddlewares ?? [])
)

View File

@ -29,7 +29,7 @@ export default class Tracker {
previousPath: string | undefined
constructor(
pushFunction: PushType = args => {
pushFunction: PushType = (args) => {
// There is an issue with the way Safari handle cookies in iframe, cf.
// https://gist.github.com/iansltx/18caf551baaa60b79206. We could probably
// do better but for now we don't track action of iOs Safari user in
@ -45,7 +45,7 @@ export default class Tracker {
}
connectToHistory(history: History) {
this.unlistenFromHistory = history.listen(loc => {
this.unlistenFromHistory = history.listen((loc) => {
this.track(loc)
})

View File

@ -57,34 +57,34 @@ type UpdateTargetUnitAction = ReturnType<typeof updateUnit>
export const resetSimulation = () =>
({
type: 'RESET_SIMULATION'
type: 'RESET_SIMULATION',
} as const)
export const goToQuestion = (question: DottedName) =>
({
type: 'STEP_ACTION',
name: 'unfold',
step: question
step: question,
} as const)
export const validateStepWithValue = (
dottedName: DottedName,
value: unknown
): ThunkResult<void> => dispatch => {
): ThunkResult<void> => (dispatch) => {
if (value !== undefined) {
dispatch(updateSituation(dottedName, value))
}
dispatch({
type: 'STEP_ACTION',
name: 'fold',
step: dottedName
step: dottedName,
})
}
export const setSituationBranch = (id: number) =>
({
type: 'SET_SITUATION_BRANCH',
id
id,
} as const)
export const setSimulationConfig = (
@ -99,19 +99,19 @@ export const setSimulationConfig = (
type: 'SET_SIMULATION',
url,
useCompanyDetails,
config
config,
})
}
export const setActiveTarget = (targetName: DottedName) =>
({
type: 'SET_ACTIVE_TARGET_INPUT',
name: targetName
name: targetName,
} as const)
export const deletePreviousSimulation = (): ThunkResult<void> => dispatch => {
export const deletePreviousSimulation = (): ThunkResult<void> => (dispatch) => {
dispatch({
type: 'DELETE_PREVIOUS_SIMULATION'
type: 'DELETE_PREVIOUS_SIMULATION',
})
deletePersistedSimulation()
}
@ -120,13 +120,13 @@ export const updateSituation = (fieldName: DottedName, value: unknown) =>
({
type: 'UPDATE_SITUATION',
fieldName,
value
value,
} as const)
export const updateUnit = (targetUnit: string) =>
({
type: 'UPDATE_TARGET_UNIT',
targetUnit
targetUnit,
} as const)
export const goBackToSimulation = (): ThunkResult<void> => (
@ -140,7 +140,7 @@ export const goBackToSimulation = (): ThunkResult<void> => (
export function loadPreviousSimulation() {
return {
type: 'LOAD_PREVIOUS_SIMULATION'
type: 'LOAD_PREVIOUS_SIMULATION',
} as const
}
@ -151,5 +151,5 @@ export function hideNotification(id: string) {
export const explainVariable = (variableName: DottedName | null = null) =>
({
type: 'EXPLAIN_VARIABLE',
variableName
variableName,
} as const)

View File

@ -18,12 +18,12 @@ export const initializeCompanyCreationChecklist = (
({
type: 'INITIALIZE_COMPANY_CREATION_CHECKLIST',
checklistItems,
statusName
statusName,
} as const)
export const checkCompanyCreationItem = (name: string, checked: boolean) =>
({
type: 'CHECK_COMPANY_CREATION_ITEM',
name,
checked
checked,
} as const)

View File

@ -51,7 +51,7 @@ export const isSoleProprietorship = thenGoToNextQuestion(
(isSoleProprietorship?: boolean) =>
({
type: 'COMPANY_IS_SOLE_PROPRIETORSHIP',
isSoleProprietorship
isSoleProprietorship,
} as const)
)
@ -61,7 +61,7 @@ export const defineDirectorStatus = thenGoToNextQuestion(
(status: DirectorStatus) =>
({
type: 'DEFINE_DIRECTOR_STATUS',
status
status,
} as const)
)
@ -69,7 +69,7 @@ export const companyHasMultipleAssociates = thenGoToNextQuestion(
(multipleAssociates?: boolean) =>
({
type: 'COMPANY_HAS_MULTIPLE_ASSOCIATES',
multipleAssociates
multipleAssociates,
} as const)
)
@ -77,7 +77,7 @@ export const isAutoentrepreneur = thenGoToNextQuestion(
(autoEntrepreneur?: boolean) =>
({
type: 'COMPANY_IS_MICROENTERPRISE',
autoEntrepreneur
autoEntrepreneur,
} as const)
)
@ -85,7 +85,7 @@ export const directorIsInAMinority = thenGoToNextQuestion(
(minorityDirector?: boolean) =>
({
type: 'SPECIFY_DIRECTORS_SHARE',
minorityDirector
minorityDirector,
} as const)
)
@ -95,7 +95,7 @@ export const goToCompanyStatusChoice = (): ThunkResult => (
{ history, sitePaths }
) => {
dispatch({
type: 'RESET_COMPANY_STATUS_CHOICE'
type: 'RESET_COMPANY_STATUS_CHOICE',
} as const)
history.push(sitePaths.créer.index)
}
@ -107,12 +107,12 @@ export const resetCompanyStatusChoice = (from: string): ThunkResult => (
const answeredQuestion = Object.keys(
getState().inFranceApp.companyLegalStatus
)
const answersToReset = dropWhile(a => a !== from, answeredQuestion)
const answersToReset = dropWhile((a) => a !== from, answeredQuestion)
if (!answersToReset.length) {
return
}
dispatch({
type: 'RESET_COMPANY_STATUS_CHOICE',
answersToReset
answersToReset,
} as const)
}

View File

@ -1,10 +1,10 @@
import { ApiCommuneJson } from 'Components/conversation/select/SelectCommune'
import { fetchCompanyDetails } from '../api/sirene'
const fetchCommuneDetails = function(codeCommune: string) {
const fetchCommuneDetails = function (codeCommune: string) {
return fetch(
`https://geo.api.gouv.fr/communes/${codeCommune}?fields=departement,region`
).then(response => {
).then((response) => {
return response.json()
})
}
@ -32,27 +32,27 @@ export const setEntreprise = (siren: string) => async (
) => {
dispatch({
type: 'EXISTING_COMPANY::SET_SIREN',
siren
siren,
} as ActionExistingCompany)
const companyDetails = await fetchCompanyDetails(siren)
dispatch({
type: 'EXISTING_COMPANY::SET_DETAILS',
catégorieJuridique: companyDetails.categorie_juridique,
dateDeCréation: companyDetails.date_creation
dateDeCréation: companyDetails.date_creation,
})
const communeDetails: ApiCommuneJson = await fetchCommuneDetails(
companyDetails.etablissement_siege.code_commune
)
dispatch({
type: 'EXISTING_COMPANY::ADD_COMMUNE_DETAILS',
details: communeDetails
details: communeDetails,
} as ActionExistingCompany)
}
export const specifyIfAutoEntrepreneur = (isAutoEntrepreneur: boolean) =>
({
type: 'EXISTING_COMPANY::SPECIFY_AUTO_ENTREPRENEUR',
isAutoEntrepreneur
isAutoEntrepreneur,
} as const)
export const specifyIfDirigeantMajoritaire = (
@ -60,10 +60,10 @@ export const specifyIfDirigeantMajoritaire = (
) =>
({
type: 'EXISTING_COMPANY::SPECIFY_DIRIGEANT_MAJORITAIRE',
isDirigeantMajoritaire
isDirigeantMajoritaire,
} as const)
export const resetEntreprise = () =>
({
type: 'EXISTING_COMPANY::RESET'
type: 'EXISTING_COMPANY::RESET',
} as const)

View File

@ -8,12 +8,12 @@ type CheckHiringItemAction = ReturnType<typeof checkHiringItem>
export const initializeHiringChecklist = (checklistItems: Array<string>) =>
({
type: 'INITIALIZE_HIRING_CHECKLIST',
checklistItems
checklistItems,
} as const)
export const checkHiringItem = (name: string, checked: boolean) =>
({
type: 'CHECK_HIRING_ITEM',
name,
checked
checked,
} as const)

View File

@ -59,7 +59,7 @@ async function searchFullText(
)
.map(({ l1_normalisee, siren }) => ({
denomination: l1_normalisee,
siren
siren,
}))
if (!etablissements.length) {
return null

View File

@ -14,7 +14,7 @@ type BannerProps = {
export default function Banner({
children,
hidden: hiddenProp = false,
icon
icon,
}: BannerProps) {
const hiddenState = useSelector(firstStepCompletedSelector)
const hidden = hiddenProp || hiddenState

View File

@ -29,7 +29,7 @@ function ChartItemBar({ style, numberToPlot, unit }: ChartItemBarProps) {
{formatValue(numberToPlot, {
displayedUnit: unit,
precision: 0,
language
language,
})}
</div>
</div>
@ -59,10 +59,10 @@ export default function BarChartBranch({
icon,
maximum,
description,
unit
unit,
}: BarChartBranchProps) {
const [intersectionRef, brancheInViewport] = useDisplayOnIntersecting({
threshold: 0.5
threshold: 0.5,
})
const { color } = useContext(ThemeColorsContext)
const numberToPlot = brancheInViewport ? value : 0
@ -70,8 +70,8 @@ export default function BarChartBranch({
config: ANIMATION_SPRING,
to: {
flex: numberToPlot / maximum,
opacity: numberToPlot ? 1 : 0
}
opacity: numberToPlot ? 1 : 0,
},
}) as { flex: number; opacity: number } // TODO: problème avec les types de react-spring ?
return (
@ -90,7 +90,7 @@ export default function BarChartBranch({
<ChartItemBar
style={{
backgroundColor: color,
flex: styles.flex
flex: styles.flex,
}}
numberToPlot={numberToPlot}
unit={unit}

View File

@ -21,7 +21,7 @@ export default function CompanyDetails({ siren, denomination }: Etablissement) {
new Intl.DateTimeFormat(i18n.language, {
month: 'short',
day: 'numeric',
year: 'numeric'
year: 'numeric',
}),
[i18n.language]
)

View File

@ -3,7 +3,7 @@ import { mount, shallow } from 'enzyme'
import { match, spy, useFakeTimers } from 'sinon'
import CurrencyInput from './CurrencyInput'
let getInput = component => mount(component).find('input')
let getInput = (component) => mount(component).find('input')
describe('CurrencyInput', () => {
it('should render an input', () => {
expect(getInput(<CurrencyInput />)).to.have.length(1)
@ -76,19 +76,9 @@ describe('CurrencyInput', () => {
it('should change the position of the currency symbol depending on the language', () => {
const inputFr = shallow(<CurrencyInput language="fr" />)
expect(
inputFr
.children()
.last()
.text()
).to.includes('€')
expect(inputFr.children().last().text()).to.includes('€')
const inputEn = shallow(<CurrencyInput language="en" />)
expect(
inputEn
.children()
.first()
.text()
).to.includes('€')
expect(inputEn.children().first().text()).to.includes('€')
})
it('should debounce onChange call', () => {
@ -155,22 +145,22 @@ describe('CurrencyInput', () => {
mount(<CurrencyInput language="fr" onChange={onChange} />)
.find('input')
.simulate('change', {
target: { value: '-', focus: () => {} }
target: { value: '-', focus: () => {} },
})
mount(<CurrencyInput language="fr" onChange={onChange} />)
.find('input')
.simulate('change', {
target: { value: ',', focus: () => {} }
target: { value: ',', focus: () => {} },
})
mount(<CurrencyInput language="fr" onChange={onChange} />)
.find('input')
.simulate('change', {
target: { value: ',5', focus: () => {} }
target: { value: ',5', focus: () => {} },
})
mount(<CurrencyInput language="fr" onChange={onChange} />)
.find('input')
.simulate('change', {
target: { value: '8,', focus: () => {} }
target: { value: '8,', focus: () => {} },
})
expect(onChange).not.to.have.been.called
})

View File

@ -53,7 +53,7 @@ export default function CurrencyInput({
event.persist()
event.target = {
...event.target,
value: nextValue.current
value: nextValue.current,
}
nextValue.current = ''
onChangeDebounced?.(event)
@ -62,7 +62,7 @@ export default function CurrencyInput({
const {
isCurrencyPrefixed,
thousandSeparator,
decimalSeparator
decimalSeparator,
} = currencyFormat(language)
// Autogrow the input
const valueLength = currentValue.toString().length

View File

@ -18,11 +18,11 @@ export default function Distribution() {
).map(([section, cotisations]) => [
section,
cotisations
.map(c => engine.evaluate({ valeur: c, unité: targetUnit }))
.map((c) => engine.evaluate({ valeur: c, unité: targetUnit }))
.reduce(
(acc, evaluation) => acc + ((evaluation?.nodeValue as number) || 0),
0
)
),
]) as Array<[DottedName, number]>)
.filter(([, value]) => value > 0)
.sort(([, a], [, b]) => b - a)
@ -55,7 +55,7 @@ export function DistributionBranch({
dottedName,
value,
icon,
maximum
maximum,
}: DistributionBranchProps) {
const rules = useContext(EngineContext).getParsedRules()
const branche = rules[dottedName]

View File

@ -1,4 +1,4 @@
import Engine, { EvaluatedNode, formatValue } from 'publicodes'
import Engine, { formatValue } from 'publicodes'
import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { DottedName } from 'Rules'
@ -32,12 +32,12 @@ export default function Value<Names extends string>({
const isRule = expression in e.getParsedRules()
const evaluation = e.evaluate({
valeur: expression,
...(unit && { unité: unit })
...(unit && { unité: unit }),
})
const value = formatValue(evaluation, {
displayedUnit,
language,
precision
precision,
})
if (isRule && linkToRule) {
return (
@ -55,7 +55,9 @@ type ConditionProps = {
}
export function Condition({ expression, children }: ConditionProps) {
const engine = useContext(EngineContext)
if (!coerceArray(expression).every(expr => engine.evaluate(expr).nodeValue)) {
if (
!coerceArray(expression).every((expr) => engine.evaluate(expr).nodeValue)
) {
return null
}
return <>{children}</>

View File

@ -39,23 +39,23 @@ export default function FeedbackForm({ onEnd, onCancel }: Props) {
tag: 'textarea',
placeholder: 'Your Message...',
defaultValue: '',
rows: 7
rows: 7,
},
{
display: 'Nom',
name: 'name',
tag: 'input',
type: 'text',
defaultValue: '-'
defaultValue: '-',
},
{
display: 'Email (pour recevoir notre réponse)',
name: 'email',
tag: 'input',
type: 'email',
placeholder: 'Your Email'
}
]
placeholder: 'Your Email',
},
],
})
}
script.src = 'https://mon-entreprise.zammad.com/assets/form/form.js'

View File

@ -30,7 +30,7 @@ const feedbackAlreadyGiven = (feedback: [string, string]) => {
export default function PageFeedback({
customMessage,
customEventName
customEventName,
}: PageFeedbackProps) {
const location = useLocation()
const tracker = useContext(TrackerContext)
@ -39,8 +39,8 @@ export default function PageFeedback({
showThanks: false,
feedbackAlreadyGiven: feedbackAlreadyGiven([
customEventName || 'rate page usefulness',
location.pathname
])
location.pathname,
]),
})
const handleFeedback = useCallback(({ useful }: { useful: boolean }) => {
@ -48,19 +48,19 @@ export default function PageFeedback({
'trackEvent',
'Feedback',
useful ? 'positive rating' : 'negative rating',
location.pathname
location.pathname,
])
const feedback = [
customEventName || 'rate page usefulness',
location.pathname,
useful ? 10 : 0.1
useful ? 10 : 0.1,
] as [string, string, number]
tracker.push(['trackEvent', 'Feedback', ...feedback])
saveFeedbackOccurrenceInLocalStorage(feedback)
setState({
showThanks: useful,
feedbackAlreadyGiven: true,
showForm: !useful
showForm: !useful,
})
}, [])

View File

@ -7,14 +7,15 @@ import { Etablissement, searchDenominationOrSiren } from '../api/sirene'
import { debounce } from '../utils'
export default function Search() {
const [searchResults, setSearchResults] = useState<Array<
Etablissement
> | null>()
const [
searchResults,
setSearchResults,
] = useState<Array<Etablissement> | null>()
const [isLoading, setLoadingState] = useState(false)
const handleSearch = useCallback(
function(value) {
searchDenominationOrSiren(value).then(results => {
function (value) {
searchDenominationOrSiren(value).then((results) => {
setLoadingState(false)
setSearchResults(results)
})
@ -22,7 +23,7 @@ export default function Search() {
[setSearchResults, setLoadingState]
)
const debouncedHandleSearch = useMemo(() => debounce(300, handleSearch), [
handleSearch
handleSearch,
])
const dispatch = useDispatch()
return (
@ -58,7 +59,7 @@ export default function Search() {
border-color: var(--color);
}
`}
onChange={e => {
onChange={(e) => {
if (e.target.value.length < 2) {
setSearchResults(undefined)
return

View File

@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
const languageCodeToEmoji = {
en: '🇬🇧',
fr: '🇫🇷'
fr: '🇫🇷',
}
export default function LangSwitcher({ className }: { className: string }) {

View File

@ -65,7 +65,7 @@ export default function MoreInfosOnUs() {
style={{
width: '3rem',
height: '3rem',
margin: 0
margin: 0,
}}
>
<g>

View File

@ -10,7 +10,7 @@ import * as animate from 'Components/ui/animate'
const formInfos = {
method: 'post',
action:
'https://b713d5c4.sibforms.com/serve/MUIEAEJui5ynU5AtcKQfxhATKzruDK8yC3YO4M56ltHV6LXHnZPESWHRjwK6Dtp3GgPqu49TljpGSa4Iy-BbaqLArDYDt5mEYtvOkrPD2b5siSNsthqi9kDz8wbljxKSDRbOQztsjyp3InDR1EUrTZJvyAk9YEkXtANb5upeHfN2VTF2m6lRiyOMF9B5VfD6jWGyxJaSNR8gsVQo?isAjax=1'
'https://b713d5c4.sibforms.com/serve/MUIEAEJui5ynU5AtcKQfxhATKzruDK8yC3YO4M56ltHV6LXHnZPESWHRjwK6Dtp3GgPqu49TljpGSa4Iy-BbaqLArDYDt5mEYtvOkrPD2b5siSNsthqi9kDz8wbljxKSDRbOQztsjyp3InDR1EUrTZJvyAk9YEkXtANb5upeHfN2VTF2m6lRiyOMF9B5VfD6jWGyxJaSNR8gsVQo?isAjax=1',
}
export default function NewsletterRegister() {
@ -30,7 +30,7 @@ export default function NewsletterRegister() {
}
fetch(formInfos.action, {
method: formInfos.method,
body: new FormData(formElement.current)
body: new FormData(formElement.current),
}).then(() => {
tracker.push(['trackEvent', 'Newsletter', 'registered'])
setUserIsRegistered(true)

View File

@ -3,7 +3,7 @@ import animate from 'Components/ui/animate'
import {
useInversionFail,
EngineContext,
useEngine
useEngine,
} from 'Components/utils/EngineContext'
import { useContext } from 'react'
import emoji from 'react-easy-emoji'
@ -30,8 +30,8 @@ export function getNotifications(engine: Engine) {
(rule: ASTNode & { nodeKind: 'rule' }) =>
rule.rawNode['type'] === 'notification'
)
.map(node => evaluateRule(engine, node.dottedName))
.filter(node => !!node.nodeValue)
.map((node) => evaluateRule(engine, node.dottedName))
.filter((node) => !!node.nodeValue)
}
export default function Notifications() {
const { t } = useTranslation()
@ -52,8 +52,8 @@ export default function Notifications() {
'Le montant saisi abouti à un résultat impossible. Cela est dû à un effet de seuil dans le calcul des cotisations.\n\nNous vous invitons à réessayer en modifiant légèrement le montant renseigné (quelques euros de plus par exemple).'
),
type: 'notification',
sévérité: 'avertissement'
}
sévérité: 'avertissement',
},
]
: ((getNotifications(engine) as any) as Array<Notification>)
if (!messages?.length) return null

View File

@ -49,7 +49,7 @@ export default function Overlay({
<FocusTrap
focusTrapOptions={{
onDeactivate: onClose,
clickOutsideDeactivates: !!onClose
clickOutsideDeactivates: !!onClose,
}}
>
<div

View File

@ -6,7 +6,7 @@ import {
EvaluatedNode,
formatValue,
ParsedRules,
reduceAST
reduceAST,
} from 'publicodes'
import { Fragment, useContext } from 'react'
import { Trans, useTranslation } from 'react-i18next'
@ -22,7 +22,7 @@ export const SECTION_ORDER = [
'protection sociale . assurance chômage',
'protection sociale . formation',
'protection sociale . transport',
'protection sociale . autres'
'protection sociale . autres',
] as const
type Section = typeof SECTION_ORDER[number]
@ -59,19 +59,19 @@ export function getCotisationsBySection(
const cotisations = ([
...findCotisations('contrat salarié . cotisations . patronales'),
...findCotisations('contrat salarié . cotisations . salariales')
...findCotisations('contrat salarié . cotisations . salariales'),
] as Array<ASTNode & { dottedName: DottedName } & { nodeKind: 'reference' }>)
.map(cotisation => cotisation.dottedName)
.map((cotisation) => cotisation.dottedName)
.filter(Boolean)
.map(
dottedName =>
(dottedName) =>
dottedName.replace(/ . (salarié|employeur)$/, '') as DottedName
)
.reduce((acc, cotisation: DottedName) => {
const sectionName = getSection(parsedRules[cotisation])
return {
...acc,
[sectionName]: (acc[sectionName] ?? new Set()).add(cotisation)
[sectionName]: (acc[sectionName] ?? new Set()).add(cotisation),
}
}, {} as Record<Section, Set<DottedName>>)
return Object.entries(cotisations)
@ -131,7 +131,7 @@ export default function PaySlip() {
<h5 className="payslip__cotisationTitle">
<RuleLink dottedName={section.dottedName} />
</h5>
{cotisations.map(cotisation => (
{cotisations.map((cotisation) => (
<Cotisation key={cotisation} dottedName={cotisation} />
))}
</Fragment>
@ -179,7 +179,10 @@ export default function PaySlip() {
)
}
function findReferenceInNode(dottedName: DottedName, node: EvaluatedNode) {
function findReferenceInNode(
dottedName: DottedName,
node: EvaluatedNode
): EvaluatedNode | null {
return reduceAST<(EvaluatedNode & { nodeKind: 'reference' }) | null>(
(acc, node) => {
if (

View File

@ -35,7 +35,7 @@ export const SalaireNetSection = () => {
<Condition
expression={[
'contrat salarié . rémunération . avantages en nature',
'contrat salarié . frais professionnels . titres-restaurant'
'contrat salarié . frais professionnels . titres-restaurant',
]}
>
<Line rule="contrat salarié . rémunération . net de cotisations" />

View File

@ -14,7 +14,7 @@ type PercentageFieldProps = InputCommonProps & {
export default function PercentageField({
onChange,
value,
debounce = 0
debounce = 0,
}: PercentageFieldProps) {
const [localValue, setLocalValue] = useState(value)
const debouncedOnChange = useCallback(
@ -27,7 +27,7 @@ export default function PercentageField({
<div>
<input
className="range"
onChange={e => {
onChange={(e) => {
const value = e.target.value
setLocalValue(value)
debouncedOnChange(value)
@ -42,7 +42,7 @@ export default function PercentageField({
<span style={{ display: 'inline-block', width: '3em' }}>
{formatValue(localValue, {
language,
displayedUnit: '%'
displayedUnit: '%',
})}
</span>
</div>

View File

@ -12,7 +12,7 @@ export default function PeriodSwitch() {
return (
<span id="PeriodSwitch">
<span className="base ui__ small radio toggle">
{units.map(unit => (
{units.map((unit) => (
<label key={unit}>
<input
name="defaultUnit"

View File

@ -8,7 +8,7 @@ import { DottedName } from 'Rules'
import { useNextQuestions } from './utils/useNextQuestion'
import {
answeredQuestionsSelector,
currentQuestionSelector
currentQuestionSelector,
} from 'Selectors/simulationSelectors'
export default function QuickLinks() {

View File

@ -9,7 +9,7 @@ export default () => (
color: '#333350',
margin: '15% auto',
width: '15em',
textAlign: 'center'
textAlign: 'center',
}}
>
<p>

View File

@ -1,7 +1,7 @@
import { setSimulationConfig } from 'Actions/actions'
import {
defineDirectorStatus,
isAutoentrepreneur
isAutoentrepreneur,
} from 'Actions/companyStatusActions'
import classnames from 'classnames'
import Conversation from 'Components/conversation/Conversation'
@ -16,7 +16,7 @@ import {
useContext,
useMemo,
useState,
useEffect
useEffect,
} from 'react'
import emoji from 'react-easy-emoji'
import { Trans } from 'react-i18next'
@ -34,7 +34,7 @@ type SchemeComparaisonProps = {
export default function SchemeComparaison({
hideAutoEntrepreneur = false,
hideAssimiléSalarié = false
hideAssimiléSalarié = false,
}: SchemeComparaisonProps) {
const dispatch = useDispatch()
useEffect(() => {
@ -51,7 +51,7 @@ export default function SchemeComparaison({
!!Object.keys(useSelector(situationSelector)).length
)
const startConversation = useCallback(() => setConversationStarted(true), [
setConversationStarted
setConversationStarted,
])
const parsedRules = engine.getParsedRules()
@ -62,7 +62,7 @@ export default function SchemeComparaison({
() =>
new Engine<DottedName>(parsedRules).setSituation({
...situation,
dirigeant: "'assimilé salarié'"
dirigeant: "'assimilé salarié'",
}),
[situation]
)
@ -70,7 +70,7 @@ export default function SchemeComparaison({
() =>
new Engine<DottedName>(parsedRules).setSituation({
...situation,
dirigeant: "'auto-entrepreneur'"
dirigeant: "'auto-entrepreneur'",
}),
[situation]
)
@ -78,7 +78,7 @@ export default function SchemeComparaison({
() =>
new Engine<DottedName>(parsedRules).setSituation({
...situation,
dirigeant: "'indépendant'"
dirigeant: "'indépendant'",
}),
[situation]
)
@ -87,7 +87,7 @@ export default function SchemeComparaison({
<div
className={classnames('comparaison-grid', {
hideAutoEntrepreneur,
hideAssimiléSalarié
hideAssimiléSalarié,
})}
>
<h2 className="AS">

View File

@ -52,15 +52,15 @@ function highlightMatches(str: string, matches: Matches) {
key={i}
>
{currentStr}
</span>
]
</span>,
],
] as [boolean, number, Array<React.ReactNode>]
},
[false, 0, []] as [boolean, number, Array<React.ReactNode>]
)[2]
}
export default function SearchBar({
showListByDefault = false
showListByDefault = false,
}: SearchBarProps) {
const rules = useEngine().getParsedRules()
const [input, setInput] = useState('')
@ -76,19 +76,19 @@ export default function SearchBar({
() =>
Object.values(rules)
.filter(utils.ruleWithDedicatedDocumentationPage)
.map(rule => ({
.map((rule) => ({
title:
rule.title +
(rule.rawNode.acronyme ? ` (${rule.rawNode.acronyme})` : ''),
dottedName: rule.dottedName,
espace: rule.dottedName.split(' . ').reverse()
espace: rule.dottedName.split(' . ').reverse(),
})),
[rules]
)
useEffect(() => {
worker.postMessage({
rules: searchIndex
rules: searchIndex,
})
worker.onmessage = ({ data: results }) => setResults(results)
@ -104,7 +104,7 @@ export default function SearchBar({
className="ui__"
value={input}
placeholder={i18n.t('Entrez des mots clefs ici')}
onChange={e => {
onChange={(e) => {
const input = e.target.value
if (input.length > 0) worker.postMessage({ input })
setInput(input)
@ -133,8 +133,8 @@ export default function SearchBar({
>
{(showListByDefault && !results.length && !input.length
? searchIndex
.filter(item => item.espace.length === 2)
.map(item => ({ item, matches: [] }))
.filter((item) => item.espace.length === 2)
.map((item) => ({ item, matches: [] }))
: results
)
.slice(0, showListByDefault ? 100 : 6)
@ -145,19 +145,19 @@ export default function SearchBar({
style={{
width: '100%',
textDecoration: 'none',
lineHeight: '1.5rem'
lineHeight: '1.5rem',
}}
>
<small>
{item.espace
.slice(1)
.reverse()
.map(name => (
.map((name) => (
<span key={name}>
{highlightMatches(
name,
matches.filter(
m => m.key === 'espace' && m.value === name
(m) => m.key === 'espace' && m.value === name
)
)}{' '}
{' '}
@ -167,7 +167,7 @@ export default function SearchBar({
</small>
{highlightMatches(
item.title,
matches.filter(m => m.key === 'title')
matches.filter((m) => m.key === 'title')
)}
</RuleLink>
</li>

View File

@ -3,16 +3,16 @@ import Fuse from 'fuse.js'
let searchWeights = [
{
name: 'espace',
weight: 0.6
weight: 0.6,
},
{
name: 'title',
weight: 0.4
}
weight: 0.4,
},
]
let fuse = null
onmessage = function(event) {
onmessage = function (event) {
if (event.data.rules)
fuse = new Fuse(event.data.rules, {
keys: searchWeights,
@ -20,14 +20,14 @@ onmessage = function(event) {
minMatchCharLength: 2,
useExtendedSearch: true,
distance: 50,
threshold: 0.3
threshold: 0.3,
})
if (event.data.input) {
let results = [
...fuse.search(
event.data.input + '|' + event.data.input.replace(/ /g, '|')
)
),
]
postMessage(results)
}

View File

@ -7,7 +7,7 @@ type SimulateurWarningProps = {
}
export default function SimulateurWarning({
simulateur
simulateur,
}: SimulateurWarningProps) {
return (
<Warning

View File

@ -1,5 +1,5 @@
import Conversation, {
ConversationProps
ConversationProps,
} from 'Components/conversation/Conversation'
import SeeAnswersButton from 'Components/conversation/SeeAnswersButton'
import PageFeedback from 'Components/Feedback/PageFeedback'
@ -28,7 +28,7 @@ export default function Simulation({
results,
customEndMessages,
showLinkToForm,
showPeriodSwitch
showPeriodSwitch,
}: SimulationProps) {
const firstStepCompleted = useSelector(firstStepCompletedSelector)
return (
@ -59,7 +59,7 @@ export default function Simulation({
}
function Questions({
customEndMessages
customEndMessages,
}: {
customEndMessages?: ConversationProps['customEndMessages']
}) {
@ -72,7 +72,7 @@ function Questions({
display: 'flex',
justifyContent: 'space-between',
marginTop: '1.2rem',
marginBottom: '0.6rem'
marginBottom: '0.6rem',
}}
>
{progress < 1 ? (

View File

@ -63,10 +63,12 @@ function integerAndDecimalParts(value: number) {
export function roundedPercentages(values: Array<number>) {
const sum = (a = 0, b: number) => a + b
const total = values.reduce(sum, 0)
const percentages = values.map(value =>
const percentages = values.map((value) =>
integerAndDecimalParts((value / total) * 100)
)
const totalRoundedPercentage = percentages.map(v => v.integer).reduce(sum, 0)
const totalRoundedPercentage = percentages
.map((v) => v.integer)
.reduce(sum, 0)
const indexesToIncrement = percentages
.map((percentage, index) => ({ ...percentage, index }))
.sort((a, b) => b.decimal - a.decimal)
@ -90,14 +92,14 @@ type StackedBarChartProps = {
export function StackedBarChart({ data }: StackedBarChartProps) {
const [intersectionRef, displayChart] = useDisplayOnIntersecting({
threshold: 0.5
threshold: 0.5,
})
const percentages = roundedPercentages(
data.map(d => (typeof d.value === 'number' && d.value) || 0)
data.map((d) => (typeof d.value === 'number' && d.value) || 0)
)
const dataWithPercentage = data.map((data, index) => ({
...data,
percentage: percentages[index]
percentage: percentages[index],
}))
const styles = useSpring({ opacity: displayChart ? 1 : 0 })
@ -112,7 +114,7 @@ export function StackedBarChart({ data }: StackedBarChartProps) {
<BarItem
style={{
width: `${percentage}%`,
backgroundColor: color || 'green'
backgroundColor: color || 'green',
}}
key={key}
/>
@ -138,11 +140,11 @@ type StackedRulesChartProps = {
export default function StackedRulesChart({ data }: StackedRulesChartProps) {
return (
<StackedBarChart
data={data.map(rule => ({
data={data.map((rule) => ({
...rule,
key: rule.dottedName,
value: rule.nodeValue,
legend: <RuleLink dottedName={rule.dottedName} />
legend: <RuleLink dottedName={rule.dottedName} />,
}))}
/>
)

View File

@ -10,7 +10,7 @@ PrismLight.registerLanguage('yaml', yaml)
export default function SyntaxHighlighter({
source,
language
language,
}: {
source: string
language: string

View File

@ -8,7 +8,7 @@ import { ThemeColorsContext } from 'Components/utils/colors'
import {
EngineContext,
useEngine,
useInversionFail
useInversionFail,
} from 'Components/utils/EngineContext'
import { SitePathsContext } from 'Components/utils/SitePathsContext'
import {
@ -17,7 +17,7 @@ import {
EvaluatedRule,
evaluateRule,
formatValue,
reduceAST
reduceAST,
} from 'publicodes'
import { isNil } from 'ramda'
import { Fragment, useCallback, useContext } from 'react'
@ -66,12 +66,12 @@ export default function TargetSelection({ showPeriodSwitch = true }) {
60deg,
${colors.darkColor} 0%,
${colors.color} 100%
)`
)`,
}}
>
<ul className="targets">
{' '}
{targets.map(target => (
{targets.map((target) => (
<Target key={target} dottedName={target} />
))}
</ul>
@ -90,11 +90,11 @@ const Target = ({ dottedName }: TargetProps) => {
const engine = useEngine()
const target = evaluateRule(engine, dottedName, {
unité: useSelector(targetUnitSelector),
arrondi: 'oui'
arrondi: 'oui',
})
const dispatch = useDispatch()
const onSuggestionClick = useCallback(
value => {
(value) => {
dispatch(updateSituation(dottedName, value))
},
[target.dottedName, dispatch]
@ -120,7 +120,7 @@ const Target = ({ dottedName }: TargetProps) => {
<Header
{...{
target,
isActiveInput
isActiveInput,
}}
/>
{isSmallTarget && (
@ -128,7 +128,7 @@ const Target = ({ dottedName }: TargetProps) => {
style={{
flex: 1,
borderBottom: '1px dashed #ffffff91',
marginLeft: '1rem'
marginLeft: '1rem',
}}
/>
)}
@ -137,7 +137,7 @@ const Target = ({ dottedName }: TargetProps) => {
{...{
target,
isActiveInput,
isSmallTarget
isSmallTarget,
}}
/>
</div>
@ -189,7 +189,7 @@ type TargetInputOrValueProps = {
function TargetInputOrValue({
target,
isActiveInput,
isSmallTarget
isSmallTarget,
}: TargetInputOrValueProps) {
const { language } = useTranslation().i18n
const colors = useContext(ThemeColorsContext)
@ -200,16 +200,16 @@ function TargetInputOrValue({
(engine.evaluate({
valeur: target.dottedName,
unité: targetUnit,
arrondi: 'oui'
arrondi: 'oui',
}).nodeValue as number) ?? undefined
const blurValue = useInversionFail() && !isActiveInput
const onChange = useCallback(
evt =>
(evt) =>
dispatch(
updateSituation(target.dottedName, {
valeur: evt.target.value,
unité: targetUnit
unité: targetUnit,
})
),
[targetUnit, target, dispatch]
@ -225,7 +225,7 @@ function TargetInputOrValue({
<CurrencyInput
style={{
color: colors.textColor,
borderColor: colors.textColor
borderColor: colors.textColor,
}}
debounce={750}
name={target.dottedName}
@ -275,7 +275,7 @@ function TitreRestaurant() {
'contrat salarié . frais professionnels . titres-restaurant . montant',
{
unité: targetUnit,
arrondi: 'oui'
arrondi: 'oui',
}
)
@ -301,7 +301,7 @@ function AidesGlimpse() {
const engine = useEngine()
const aides = evaluateRule(engine, dottedName, {
unité: targetUnit,
arrondi: 'oui'
arrondi: 'oui',
})
if (!aides?.nodeValue) return null
@ -330,7 +330,7 @@ function AidesGlimpse() {
return (
<Animate.fromTop>
<div className="aidesGlimpse">
<RuleLink dottedName={aideLink as DottedName}>
<RuleLink dottedName={aideLink}>
<Trans>en incluant</Trans>{' '}
<strong>
<span>{formatValue(aides, { displayedUnit: '€', language })}</span>

View File

@ -1,11 +1,11 @@
import { Helmet } from 'react-helmet'
let createQueryParams = params =>
let createQueryParams = (params) =>
Object.keys(params)
.map(k => `${k}=${encodeURI(params[k])}`)
.map((k) => `${k}=${encodeURI(params[k])}`)
.join('&')
let url = hiddenVariables =>
let url = (hiddenVariables) =>
'https://embauchegouv.typeform.com/to/dvbINf?' +
createQueryParams(hiddenVariables)
@ -25,8 +25,8 @@ let TypeFormEmbed = ({ hiddenVariables }) => (
{
type: 'text/javascript',
innerHTML:
'(function() { var qs,js,q,s,d=document, gi=d.getElementById, ce=d.createElement, gt=d.getElementsByTagName, id="typef_orm_share", b="https://embed.typeform.com/"; if(!gi.call(d,id)){ js=ce.call(d,"script"); js.id=id; js.src=b+"embed.js"; q=gt.call(d,"script")[0]; q.parentNode.insertBefore(js,q) } })() '
}
'(function() { var qs,js,q,s,d=document, gi=d.getElementById, ce=d.createElement, gt=d.getElementsByTagName, id="typef_orm_share", b="https://embed.typeform.com/"; if(!gi.call(d,id)){ js=ce.call(d,"script"); js.id=id; js.src=b+"embed.js"; q=gt.call(d,"script")[0]; q.parentNode.insertBefore(js,q) } })() ',
},
]}
/>
</div>

View File

@ -1,17 +1,13 @@
import { goToQuestion, resetSimulation } from 'Actions/actions'
import Overlay from 'Components/Overlay'
import { EngineContext, useEngine } from 'Components/utils/EngineContext'
import { useEngine } from 'Components/utils/EngineContext'
import { useNextQuestions } from 'Components/utils/useNextQuestion'
import { evaluateRule, formatValue } from 'publicodes'
import { useContext } from 'react'
import { EvaluatedNode, formatValue } from 'publicodes'
import emoji from 'react-easy-emoji'
import { Trans, useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import { DottedName } from 'Rules'
import {
answeredQuestionsSelector,
situationSelector
} from 'Selectors/simulationSelectors'
import { situationSelector } from 'Selectors/simulationSelectors'
import './AnswerList.css'
type AnswerListProps = {
@ -20,10 +16,16 @@ type AnswerListProps = {
export default function AnswerList({ onClose }: AnswerListProps) {
const dispatch = useDispatch()
const answeredQuestions = Object.keys(
const engine = useEngine()
const answeredQuestions = (Object.keys(
useSelector(situationSelector)
) as Array<DottedName>
const nextSteps = useNextQuestions()
) as Array<DottedName>).map((dottedName) =>
engine.evaluateNode(engine.getParsedRules()[dottedName])
)
const nextSteps = useNextQuestions().map((dottedName) =>
engine.evaluateNode(engine.getParsedRules()[dottedName])
)
return (
<Overlay onClose={onClose} className="answer-list">
@ -63,62 +65,58 @@ export default function AnswerList({ onClose }: AnswerListProps) {
function StepsTable({
rules,
onClose
onClose,
}: {
rules: Array<DottedName>
rules: Array<EvaluatedNode & { nodeKind: 'rule'; dottedName: DottedName }>
onClose: () => void
}) {
const dispatch = useDispatch()
const engine = useEngine()
const evaluatedRules = rules.map(rule => evaluateRule(engine, rule))
const language = useTranslation().i18n.language
return (
<table>
<tbody>
{evaluatedRules
.filter(rule => rule.nodeValue !== false)
.map(rule => (
<tr
key={rule.dottedName}
css={`
background: var(--lightestColor);
`}
>
<td>
<button
className="ui__ link-button"
onClick={() => {
dispatch(goToQuestion(rule.dottedName))
onClose()
}}
>
{rule.title}
</button>
</td>
<td>
<span
css={`
{rules.map((rule) => (
<tr
key={rule.dottedName}
css={`
background: var(--lightestColor);
`}
>
<td>
<button
className="ui__ link-button"
onClick={() => {
dispatch(goToQuestion(rule.dottedName))
onClose()
}}
>
{rule.title}
</button>
</td>
<td>
<span
css={`
display: inline-block;
padding: 0.2rem;
color: inherit;
font-size: inherit;
width: 100%;
text-align: start;
font-weight: 600;
> span {
border-bottom-color: var(--textColorOnWhite);
padding: 0.05em 0em;
display: inline-block;
padding: 0.2rem;
color: inherit;
font-size: inherit;
width: 100%;
text-align: start;
font-weight: 600;
> span {
border-bottom-color: var(--textColorOnWhite);
padding: 0.05em 0em;
display: inline-block;
}
`}
>
<span className="answerContent">
{formatValue(rule, { language })}
</span>
</span>{' '}
</td>
</tr>
))}
}
`}
>
<span className="answerContent">
{formatValue(rule, { language })}
</span>
</span>{' '}
</td>
</tr>
))}
</tbody>
</table>
)

View File

@ -1,7 +1,7 @@
import {
goToQuestion,
updateSituation,
validateStepWithValue
validateStepWithValue,
} from 'Actions/actions'
import RuleInput, { RuleInputProps } from 'Components/conversation/RuleInput'
import QuickLinks from 'Components/QuickLinks'
@ -14,7 +14,7 @@ import { Trans } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import {
answeredQuestionsSelector,
situationSelector
situationSelector,
} from 'Selectors/simulationSelectors'
import Aide from './Aide'
import './conversation.css'
@ -55,11 +55,11 @@ export default function Conversation({ customEndMessages }: ConversationProps) {
type: 'STEP_ACTION',
name: 'fold',
step: currentQuestion,
source
source,
})
}
const onChange: RuleInputProps['onChange'] = value => {
const onChange: RuleInputProps['onChange'] = (value) => {
dispatch(updateSituation(currentQuestion, value))
}

View File

@ -1,6 +1,6 @@
import {
InputCommonProps,
RuleInputProps
RuleInputProps,
} from 'Components/conversation/RuleInput'
import { EvaluatedRule } from 'publicodes'
import { useCallback, useMemo } from 'react'
@ -20,7 +20,7 @@ export default function DateInput({
onChange,
id,
onSubmit,
value
value,
}: DateInputProps) {
const dateValue = useMemo(() => {
if (!value || typeof value !== 'string') return undefined
@ -29,7 +29,7 @@ export default function DateInput({
}, [value])
const handleDateChange = useCallback(
evt => {
(evt) => {
if (!evt.target.value) {
return
}
@ -40,7 +40,7 @@ export default function DateInput({
if (year.length > 4) {
return
}
if ([day, month, year].some(x => Number.isNaN(+x))) {
if ([day, month, year].some((x) => Number.isNaN(+x))) {
return
}
onChange(`${day}/${month}/${year}`)
@ -53,7 +53,7 @@ export default function DateInput({
{suggestions && (
<InputSuggestions
suggestions={suggestions}
onFirstClick={value => {
onFirstClick={(value) => {
onChange(value)
}}
onSecondClick={() => onSubmit?.('suggestion')}

View File

@ -25,7 +25,7 @@ export function ExplicableRule({ dottedName }: { dottedName: DottedName }) {
return (
<button
className="ui__ link-button"
onClick={e => {
onClick={(e) => {
tracker.push(['trackEvent', 'help', dottedName])
dispatch(explainVariable(dottedName))
e.preventDefault()

View File

@ -1,9 +1,7 @@
import { formatValue } from 'publicodes'
import { Evaluation, Unit } from 'publicodes/dist/types/AST/types'
import { formatValue, Evaluation, Unit } from 'publicodes'
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import NumberFormat from 'react-number-format'
import { serialize } from 'storage/serializeSimulation'
import { currencyFormat, debounce } from '../../utils'
import InputSuggestions from './InputSuggestions'
import { InputCommonProps } from './RuleInput'
@ -17,7 +15,7 @@ export default function Input({
value,
missing,
unit,
autoFocus
autoFocus,
}: InputCommonProps & {
onSubmit: (source: string) => void
unit: Unit | undefined
@ -35,7 +33,7 @@ export default function Input({
<div>
<InputSuggestions
suggestions={suggestions}
onFirstClick={value => {
onFirstClick={(value) => {
onChange(value)
}}
onSecondClick={() => onSubmit?.('suggestion')}
@ -51,11 +49,13 @@ export default function Input({
// re-render with a new "value" prop from the outside.
onValueChange={({ floatValue }) => {
if (floatValue !== value) {
debouncedOnChange({ valeur: floatValue, unité })
debouncedOnChange(
floatValue != undefined ? { valeur: floatValue, unité } : {}
)
}
}}
autoComplete="off"
{...{ [missing ? 'placeholder' : 'value']: value || '' }}
{...{ [missing ? 'placeholder' : 'value']: value ?? '' }}
/>
<span className="suffix">&nbsp;{unité}</span>
</div>

View File

@ -11,8 +11,8 @@ type InputSuggestionsProps = {
export default function InputSuggestions({
suggestions = {},
onSecondClick = x => x,
onFirstClick
onSecondClick = (x) => x,
onFirstClick,
}: InputSuggestionsProps) {
const [suggestion, setSuggestion] = useState<ASTNode>()
const { t, i18n } = useTranslation()

View File

@ -8,7 +8,7 @@ export default function ParagrapheInput({
value,
id,
missing,
autoFocus
autoFocus,
}: InputCommonProps & { value: Evaluation<string> }) {
const debouncedOnChange = useCallback(debounce(1000, onChange), [])
@ -26,7 +26,7 @@ export default function ParagrapheInput({
{...{
[missing ? 'placeholder' : 'defaultValue']: (
(value as string) || ''
).replace('\\n', '\n')
).replace('\\n', '\n'),
}}
autoComplete="off"
/>

View File

@ -40,13 +40,13 @@ export default function Question({
dottedName: questionDottedName,
missing,
onChange,
value: currentValue
value: currentValue,
}: QuestionProps) {
const [currentSelection, setCurrentSelection] = useState(
missing ? null : `'${currentValue}'`
)
const handleChange = useCallback(
value => {
(value) => {
setCurrentSelection(value)
},
[setCurrentSelection]
@ -89,7 +89,7 @@ export default function Question({
currentSelection,
onSubmit: handleSubmit,
name: questionDottedName,
onChange: handleChange
onChange: handleChange,
}}
/>
</span>
@ -112,7 +112,7 @@ export default function Question({
name: questionDottedName,
onSubmit: handleSubmit,
dottedName: null,
onChange: handleChange
onChange: handleChange,
}}
/>
</li>
@ -123,7 +123,7 @@ export default function Question({
title,
dottedName,
rawNode: { description, icônes, références },
children
children,
}) =>
children ? (
<li key={dottedName} className="variant">
@ -143,7 +143,7 @@ export default function Question({
onSubmit: handleSubmit,
description,
références,
onChange: handleChange
onChange: handleChange,
}}
/>
</li>
@ -215,7 +215,7 @@ function RadioLabelContent({
currentSelection,
icônes,
onChange,
onSubmit
onSubmit,
}: RadioLabelContentProps) {
const labelStyle = value === '_' ? ({ fontWeight: 'bold' } as const) : {}
const selected = value === currentSelection
@ -228,14 +228,14 @@ function RadioLabelContent({
}}
style={labelStyle}
className={classnames('userAnswerButton ui__ button', {
selected
selected,
})}
>
<input
type="radio"
name={name}
value={value}
onChange={evt => onChange(evt.target.value)}
onChange={(evt) => onChange(evt.target.value)}
checked={selected}
/>
<span>

View File

@ -10,6 +10,7 @@ import {
ASTNode,
EvaluatedRule,
evaluateRule,
formatValue,
ParsedRules,
reduceAST,
} from 'publicodes'
@ -17,6 +18,7 @@ import { Evaluation } from 'publicodes/dist/types/AST/types'
import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { DottedName } from 'Rules'
import { serialize } from 'storage/serializeSimulation'
import DateInput from './DateInput'
import ParagrapheInput from './ParagrapheInput'
import SelectEuropeCountry from './select/SelectEuropeCountry'
@ -67,6 +69,7 @@ export default function RuleInput<Name extends string = DottedName>({
}: RuleInputProps<Name>) {
const engine = useContext(EngineContext)
const rule = evaluateRule(engine, dottedName)
const language = useTranslation().i18n.language
const value = rule.nodeValue
const commonProps: InputCommonProps<Name> = {
@ -120,7 +123,7 @@ export default function RuleInput<Name extends string = DottedName>({
) {
return useSwitch ? (
<ToggleSwitch
defaultChecked={value === 'oui'}
defaultChecked={value === true}
onChange={(evt: React.ChangeEvent<HTMLInputElement>) =>
onChange(evt.target.checked ? 'oui' : 'non')
}
@ -137,12 +140,13 @@ export default function RuleInput<Name extends string = DottedName>({
)
}
commonProps.value =
typeof commonProps.value === 'string'
? engine.evaluate(commonProps.value as DottedName).nodeValue
: commonProps.value
if (rule.unit?.numerators.includes('€') && isTarget) {
const unité = formatValue(
{ nodeValue: value ?? 0, unit: rule.unit },
{ language }
)
.replace(/[\d,.]/g, '')
.trim()
return (
<>
<CurrencyInput
@ -152,7 +156,7 @@ export default function RuleInput<Name extends string = DottedName>({
value={value as string}
name={dottedName}
className="targetInput"
onChange={(evt) => onChange(evt.target.value)}
onChange={(evt) => onChange({ valeur: evt.target.value, unité })}
/>
</>
)
@ -160,7 +164,6 @@ export default function RuleInput<Name extends string = DottedName>({
if (rule.unit?.numerators.includes('%') && isTarget) {
return <PercentageField {...commonProps} debounce={600} />
}
if (rule.type === 'texte') {
return <TextInput {...commonProps} value={value as Evaluation<string>} />
}

View File

@ -8,10 +8,9 @@ export default function TextInput({
value,
id,
missing,
autoFocus
autoFocus,
}: InputCommonProps & { value: Evaluation<string> }) {
const debouncedOnChange = useCallback(debounce(1000, onChange), [])
return (
<div className="step input">
<input
@ -23,7 +22,7 @@ export default function TextInput({
debouncedOnChange(`'${target.value}'`)
}}
{...{
[missing ? 'placeholder' : 'defaultValue']: (value as string) || ''
[missing ? 'placeholder' : 'defaultValue']: (value as string) || '',
}}
autoComplete="off"
/>

View File

@ -56,14 +56,19 @@ async function searchCommunes(input: string): Promise<Array<Commune> | null> {
.flatMap(({ codesPostaux, ...commune }) =>
codesPostaux
.sort()
.map(codePostal => ({ ...commune, codePostal }))
.map((codePostal) => ({ ...commune, codePostal }))
.filter(({ codePostal }) => codePostal.startsWith(number))
)
.slice(0, 10)
}
export default function Select({ onChange, value, id }: InputCommonProps) {
const [name, setName] = useState(formatCommune(value))
export default function Select({
onChange,
value,
id,
missing,
}: InputCommonProps) {
const [name, setName] = useState(missing ? '' : formatCommune(value))
const [searchResults, setSearchResults] = useState<null | Array<Commune>>(
null
)
@ -71,8 +76,8 @@ export default function Select({ onChange, value, id }: InputCommonProps) {
const [isLoading, setLoadingState] = useState(false)
const handleSearch = useCallback(
function(value) {
searchCommunes(value).then(results => {
function (value) {
searchCommunes(value).then((results) => {
setLoadingState(false)
setSearchResults(results)
})
@ -80,7 +85,7 @@ export default function Select({ onChange, value, id }: InputCommonProps) {
[setSearchResults, setLoadingState]
)
const debouncedHandleSearch = useMemo(() => debounce(300, handleSearch), [
handleSearch
handleSearch,
])
const handleSubmit = useCallback(
@ -103,10 +108,10 @@ export default function Select({ onChange, value, id }: InputCommonProps) {
...commune,
...(taux != null
? {
'taux du versement transport': taux
'taux du versement transport': taux,
}
: {})
}
: {}),
},
})
},
[setSearchResults, setName]
@ -209,7 +214,7 @@ export default function Select({ onChange, value, id }: InputCommonProps) {
<Option
onMouseDown={
// Prevent input blur and focus elem selection
e => e.preventDefault()
(e) => e.preventDefault()
}
onClick={() => handleSubmit(result)}
role="option"
@ -247,7 +252,7 @@ const Option = styled.li<{ focused: boolean }>`
margin-bottom: 0.3rem;
font-size: 100%;
padding: 0.6rem;
${props =>
${(props) =>
props.focused &&
css`
background-color: var(--lighterColor) !important;

View File

@ -31,13 +31,13 @@ const STATES = [
'Slovaquie',
'Slovénie',
'Suède',
'Suisse'
'Suisse',
] as const
export default function SelectEuropeCountry({
value,
onChange,
id
id,
}: InputCommonProps) {
return (
<div>
@ -46,10 +46,10 @@ export default function SelectEuropeCountry({
id={id}
className="ui__"
defaultValue={value?.slice(1, -1)}
onChange={e => onChange(`'${e.target.value}'`)}
onChange={(e) => onChange(`'${e.target.value}'`)}
>
<option disabled selected hidden></option>
{STATES.map(state => (
{STATES.map((state) => (
<option key={state} value={state}>
{state}
</option>

View File

@ -5,7 +5,7 @@ const worker = new Worker()
function SelectComponent({ onChange, onSubmit, options }) {
const [searchResults, setSearchResults] = useState()
let submitOnChange = option => {
let submitOnChange = (option) => {
option.text = +option['Taux net'].replace(',', '.')
onChange(option.text)
onSubmit()
@ -13,7 +13,7 @@ function SelectComponent({ onChange, onSubmit, options }) {
const { t } = useTranslation()
useEffect(() => {
worker.postMessage({
options
options,
})
worker.onmessage = ({ data: results }) => setSearchResults(results)
@ -38,7 +38,7 @@ function SelectComponent({ onChange, onSubmit, options }) {
}
`}
placeholder={t("Saisissez votre domaine d'activité")}
onChange={e => {
onChange={(e) => {
let input = e.target.value
if (input.length < 2) {
setSearchResults(undefined)
@ -54,7 +54,7 @@ function SelectComponent({ onChange, onSubmit, options }) {
)}
{searchResults &&
searchResults.map(option => (
searchResults.map((option) => (
<div
key={JSON.stringify(option)}
css={`
@ -122,7 +122,7 @@ export default function Select(props) {
fetch(
'https://raw.githubusercontent.com/betagouv/taux-collectifs-cotisation-atmp/master/taux-2020.json'
)
.then(response => {
.then((response) => {
if (!response.ok) {
let error = new Error(response.statusText)
error.response = response
@ -130,9 +130,9 @@ export default function Select(props) {
}
return response.json()
})
.then(json => setOptions(json))
.then((json) => setOptions(json))
.catch(
error =>
(error) =>
console.warn('Erreur dans la récupération des codes risques', error) // eslint-disable-line no-console
)
}, [])

View File

@ -1,11 +1,11 @@
import Fuse from 'fuse.js'
let fuse = null
onmessage = function(event) {
onmessage = function (event) {
if (event.data.options)
fuse = new Fuse(event.data.options, {
keys: ['Nature du risque', 'Catégorie'],
shouldSort: true
shouldSort: true,
})
if (event.data.input) {

View File

@ -31,7 +31,7 @@ export default function AutoEntrepreneurExplanation() {
{ unité: targetUnit }
),
title: t("Revenu (incluant les dépenses liées à l'activité)"),
color: palettes[0][0]
color: palettes[0][0],
},
...(impôt.nodeValue
@ -44,8 +44,8 @@ export default function AutoEntrepreneurExplanation() {
{ unité: targetUnit }
),
title: t('Cotisations'),
color: palettes[1][1]
}
color: palettes[1][1],
},
]}
/>
</section>

View File

@ -39,7 +39,7 @@ export default function IndépendantExplanation() {
{
...evaluateRule(engine, 'revenu net après impôt'),
title: t('Revenu disponible'),
color: palettes[0][0]
color: palettes[0][0],
},
{ ...evaluateRule(engine, 'impôt'), color: palettes[1][0] },
{
@ -48,8 +48,8 @@ export default function IndépendantExplanation() {
'dirigeant . indépendant . cotisations et contributions'
),
title: t('Cotisations'),
color: palettes[1][1]
}
color: palettes[1][1],
},
]}
/>
</section>
@ -136,12 +136,12 @@ function CaisseRetraite() {
'CIPAV',
'CARMF',
'CNBF',
'CAVEC'
'CAVEC',
] as const
return (
<>
{caisses.map(caisse => {
{caisses.map((caisse) => {
const dottedName = `dirigeant . indépendant . PL . ${caisse}` as DottedName
const { description, références } = evaluateRule(engine, dottedName)
return (
@ -185,27 +185,27 @@ const CotisationsSection: Partial<Record<DottedName, Array<string>>> = {
'protection sociale . retraite': [
'dirigeant . indépendant . cotisations et contributions . retraite de base',
'dirigeant . indépendant . cotisations et contributions . retraite complémentaire',
'dirigeant . indépendant . cotisations et contributions . PCV'
'dirigeant . indépendant . cotisations et contributions . PCV',
],
'protection sociale . santé': [
'dirigeant . indépendant . cotisations et contributions . maladie',
'dirigeant . indépendant . cotisations et contributions . indemnités journalières maladie',
'dirigeant . indépendant . cotisations et contributions . CSG et CRDS * 5.95 / 9.2'
'dirigeant . indépendant . cotisations et contributions . CSG et CRDS * 5.95 / 9.2',
],
'protection sociale . invalidité et décès': [
'dirigeant . indépendant . cotisations et contributions . invalidité et décès'
'dirigeant . indépendant . cotisations et contributions . invalidité et décès',
],
'protection sociale . famille': [
'dirigeant . indépendant . cotisations et contributions . allocations familiales',
'dirigeant . indépendant . cotisations et contributions . CSG et CRDS * 0.95 / 9.2'
'dirigeant . indépendant . cotisations et contributions . CSG et CRDS * 0.95 / 9.2',
],
'protection sociale . autres': [
'dirigeant . indépendant . cotisations et contributions . contributions spéciales',
'dirigeant . indépendant . cotisations et contributions . CSG et CRDS * 2.3 / 9.2'
'dirigeant . indépendant . cotisations et contributions . CSG et CRDS * 2.3 / 9.2',
],
'protection sociale . formation': [
'dirigeant . indépendant . cotisations et contributions . formation professionnelle'
]
'dirigeant . indépendant . cotisations et contributions . formation professionnelle',
],
}
function Distribution() {
@ -216,11 +216,11 @@ function Distribution() {
).map(([section, cotisations]) => [
section,
(cotisations as string[])
.map(c => engine.evaluate({ valeur: c, unité: targetUnit }))
.map((c) => engine.evaluate({ valeur: c, unité: targetUnit }))
.reduce(
(acc, evaluation) => acc + ((evaluation?.nodeValue as number) || 0),
0
)
),
]) as Array<[DottedName, number]>)
.filter(([, value]) => value > 0)
.sort(([, a], [, b]) => b - a)
@ -253,7 +253,7 @@ function DistributionBranch({
dottedName,
value,
icon,
maximum
maximum,
}: DistributionBranchProps) {
const rules = useContext(EngineContext).getParsedRules()
const branche = rules[dottedName]

View File

@ -5,7 +5,7 @@ import { ThemeColorsContext } from 'Components/utils/colors'
import {
EngineContext,
useEngine,
useInversionFail
useInversionFail,
} from 'Components/utils/EngineContext'
import { useContext, useRef } from 'react'
import emoji from 'react-easy-emoji'
@ -40,7 +40,7 @@ export default function SalaryExplanation() {
onClick={() =>
distributionRef.current?.scrollIntoView({
behavior: 'smooth',
block: 'start'
block: 'start',
})
}
>
@ -85,8 +85,8 @@ function RevenueRepatitionSection() {
const data = ([
'contrat salarié . rémunération . net après impôt',
'impôt',
'contrat salarié . cotisations'
] as DottedName[]).map(r => evaluateRule(engine, r, { unité: '€/mois' }))
'contrat salarié . cotisations',
] as DottedName[]).map((r) => evaluateRule(engine, r, { unité: '€/mois' }))
return (
<section>
@ -98,17 +98,17 @@ function RevenueRepatitionSection() {
{
...data[0],
title: t('Revenu disponible'),
color: palettes[0][0]
color: palettes[0][0],
},
{
...data[1],
title: t('impôt'),
color: palettes[1][0]
color: palettes[1][0],
},
{
...data[2],
color: palettes[1][1]
}
color: palettes[1][1],
},
]}
/>
</section>

View File

@ -17,7 +17,7 @@ const formatDifference = (difference: number, language: string) => {
export default function AnimatedTargetValue({
value,
children
children,
}: AnimatedTargetValueProps) {
const previousValue = useRef<number>()
const { language } = useTranslation().i18n
@ -50,7 +50,7 @@ export default function AnimatedTargetValue({
<Evaporate
style={{
color: difference > 0 ? 'chartreuse' : 'red',
pointerEvents: 'none'
pointerEvents: 'none',
}}
>
{formatDifference(difference, language)}
@ -64,7 +64,7 @@ export default function AnimatedTargetValue({
const Evaporate = React.memo(function Evaporate({
children,
style
style,
}: {
children: string
style: React.CSSProperties

View File

@ -20,7 +20,7 @@ export function CheckItem({
name,
explanations,
onChange,
defaultChecked
defaultChecked,
}: CheckItemProps) {
const tracker = useContext(TrackerContext)
const [displayExplanations, setDisplayExplanations] = useState(false)
@ -34,7 +34,7 @@ export function CheckItem({
'trackEvent',
'CheckItem',
e.target.checked ? 'check' : 'uncheck',
name
name,
])
}
@ -56,7 +56,7 @@ export function CheckItem({
<button
className={classnames('ui__ checklist-button', {
opened: displayExplanations
opened: displayExplanations,
})}
onClick={handleClick}
>
@ -89,11 +89,11 @@ export function Checklist({
children,
onItemCheck,
onInitialization,
defaultChecked
defaultChecked,
}: ChecklistProps) {
const checklist = React.Children.toArray(children)
.filter(Boolean)
.map(child => {
.map((child) => {
if (!React.isValidElement(child)) {
throw new Error('Invalid child passed to Checklist')
}
@ -101,17 +101,17 @@ export function Checklist({
onChange: (evt: React.ChangeEvent<HTMLInputElement>) =>
onItemCheck?.(child.props.name, evt.target.checked),
defaultChecked:
child.props.defaultChecked || defaultChecked?.[child.props.name]
child.props.defaultChecked || defaultChecked?.[child.props.name],
})
})
useEffect(() => {
onInitialization?.(checklist.map(child => child.props.name))
onInitialization?.(checklist.map((child) => child.props.name))
}, [])
return (
<ul className="ui__ no-bullet checklist">
{checklist.map(checkItem => (
{checklist.map((checkItem) => (
<li key={checkItem.props.name}>{checkItem}</li>
))}
</ul>

View File

@ -10,7 +10,7 @@ type ProgressProps = {
export default function Progress({
progress,
style,
className
className,
}: ProgressProps) {
return (
<div className={'progress__container ' + className} style={style}>

View File

@ -16,7 +16,7 @@ export default function RangeSlider({ value, onChange }: RangeSliderProps) {
min="0"
max="100"
defaultValue={value}
onChange={evt => debouncedOnChange(evt.target.value)}
onChange={(evt) => debouncedOnChange(evt.target.value)}
/>
)
}

View File

@ -6,32 +6,32 @@ export const icons = {
icon:
'M34.1,47V33.3h4.6l0.7-5.3h-5.3v-3.4c0-1.5,0.4-2.6,2.6-2.6l2.8,0v-4.8c-0.5-0.1-2.2-0.2-4.1-0.2 c-4.1,0-6.9,2.5-6.9,7V28H24v5.3h4.6V47H34.1z',
mask:
'M0,0v64h64V0H0z M39.6,22l-2.8,0c-2.2,0-2.6,1.1-2.6,2.6V28h5.3l-0.7,5.3h-4.6V47h-5.5V33.3H24V28h4.6V24 c0-4.6,2.8-7,6.9-7c2,0,3.6,0.1,4.1,0.2V22z'
'M0,0v64h64V0H0z M39.6,22l-2.8,0c-2.2,0-2.6,1.1-2.6,2.6V28h5.3l-0.7,5.3h-4.6V47h-5.5V33.3H24V28h4.6V24 c0-4.6,2.8-7,6.9-7c2,0,3.6,0.1,4.1,0.2V22z',
},
twitter: {
icon:
'M48,22.1c-1.2,0.5-2.4,0.9-3.8,1c1.4-0.8,2.4-2.1,2.9-3.6c-1.3,0.8-2.7,1.3-4.2,1.6 C41.7,19.8,40,19,38.2,19c-3.6,0-6.6,2.9-6.6,6.6c0,0.5,0.1,1,0.2,1.5c-5.5-0.3-10.3-2.9-13.5-6.9c-0.6,1-0.9,2.1-0.9,3.3 c0,2.3,1.2,4.3,2.9,5.5c-1.1,0-2.1-0.3-3-0.8c0,0,0,0.1,0,0.1c0,3.2,2.3,5.8,5.3,6.4c-0.6,0.1-1.1,0.2-1.7,0.2c-0.4,0-0.8,0-1.2-0.1 c0.8,2.6,3.3,4.5,6.1,4.6c-2.2,1.8-5.1,2.8-8.2,2.8c-0.5,0-1.1,0-1.6-0.1c2.9,1.9,6.4,2.9,10.1,2.9c12.1,0,18.7-10,18.7-18.7 c0-0.3,0-0.6,0-0.8C46,24.5,47.1,23.4,48,22.1z',
mask:
'M0,0v64h64V0H0z M44.7,25.5c0,0.3,0,0.6,0,0.8C44.7,35,38.1,45,26.1,45c-3.7,0-7.2-1.1-10.1-2.9 c0.5,0.1,1,0.1,1.6,0.1c3.1,0,5.9-1,8.2-2.8c-2.9-0.1-5.3-2-6.1-4.6c0.4,0.1,0.8,0.1,1.2,0.1c0.6,0,1.2-0.1,1.7-0.2 c-3-0.6-5.3-3.3-5.3-6.4c0,0,0-0.1,0-0.1c0.9,0.5,1.9,0.8,3,0.8c-1.8-1.2-2.9-3.2-2.9-5.5c0-1.2,0.3-2.3,0.9-3.3 c3.2,4,8.1,6.6,13.5,6.9c-0.1-0.5-0.2-1-0.2-1.5c0-3.6,2.9-6.6,6.6-6.6c1.9,0,3.6,0.8,4.8,2.1c1.5-0.3,2.9-0.8,4.2-1.6 c-0.5,1.5-1.5,2.8-2.9,3.6c1.3-0.2,2.6-0.5,3.8-1C47.1,23.4,46,24.5,44.7,25.5z'
'M0,0v64h64V0H0z M44.7,25.5c0,0.3,0,0.6,0,0.8C44.7,35,38.1,45,26.1,45c-3.7,0-7.2-1.1-10.1-2.9 c0.5,0.1,1,0.1,1.6,0.1c3.1,0,5.9-1,8.2-2.8c-2.9-0.1-5.3-2-6.1-4.6c0.4,0.1,0.8,0.1,1.2,0.1c0.6,0,1.2-0.1,1.7-0.2 c-3-0.6-5.3-3.3-5.3-6.4c0,0,0-0.1,0-0.1c0.9,0.5,1.9,0.8,3,0.8c-1.8-1.2-2.9-3.2-2.9-5.5c0-1.2,0.3-2.3,0.9-3.3 c3.2,4,8.1,6.6,13.5,6.9c-0.1-0.5-0.2-1-0.2-1.5c0-3.6,2.9-6.6,6.6-6.6c1.9,0,3.6,0.8,4.8,2.1c1.5-0.3,2.9-0.8,4.2-1.6 c-0.5,1.5-1.5,2.8-2.9,3.6c1.3-0.2,2.6-0.5,3.8-1C47.1,23.4,46,24.5,44.7,25.5z',
},
linkedin: {
icon:
'M20.4,44h5.4V26.6h-5.4V44z M23.1,18c-1.7,0-3.1,1.4-3.1,3.1c0,1.7,1.4,3.1,3.1,3.1 c1.7,0,3.1-1.4,3.1-3.1C26.2,19.4,24.8,18,23.1,18z M39.5,26.2c-2.6,0-4.4,1.4-5.1,2.8h-0.1v-2.4h-5.2V44h5.4v-8.6 c0-2.3,0.4-4.5,3.2-4.5c2.8,0,2.8,2.6,2.8,4.6V44H46v-9.5C46,29.8,45,26.2,39.5,26.2z',
mask:
'M0,0v64h64V0H0z M25.8,44h-5.4V26.6h5.4V44z M23.1,24.3c-1.7,0-3.1-1.4-3.1-3.1c0-1.7,1.4-3.1,3.1-3.1 c1.7,0,3.1,1.4,3.1,3.1C26.2,22.9,24.8,24.3,23.1,24.3z M46,44h-5.4v-8.4c0-2,0-4.6-2.8-4.6c-2.8,0-3.2,2.2-3.2,4.5V44h-5.4V26.6 h5.2V29h0.1c0.7-1.4,2.5-2.8,5.1-2.8c5.5,0,6.5,3.6,6.5,8.3V44z'
'M0,0v64h64V0H0z M25.8,44h-5.4V26.6h5.4V44z M23.1,24.3c-1.7,0-3.1-1.4-3.1-3.1c0-1.7,1.4-3.1,3.1-3.1 c1.7,0,3.1,1.4,3.1,3.1C26.2,22.9,24.8,24.3,23.1,24.3z M46,44h-5.4v-8.4c0-2,0-4.6-2.8-4.6c-2.8,0-3.2,2.2-3.2,4.5V44h-5.4V26.6 h5.2V29h0.1c0.7-1.4,2.5-2.8,5.1-2.8c5.5,0,6.5,3.6,6.5,8.3V44z',
},
github: {
icon:
'M32,16c-8.8,0-16,7.2-16,16c0,7.1,4.6,13.1,10.9,15.2 c0.8,0.1,1.1-0.3,1.1-0.8c0-0.4,0-1.4,0-2.7c-4.5,1-5.4-2.1-5.4-2.1c-0.7-1.8-1.8-2.3-1.8-2.3c-1.5-1,0.1-1,0.1-1 c1.6,0.1,2.5,1.6,2.5,1.6c1.4,2.4,3.7,1.7,4.7,1.3c0.1-1,0.6-1.7,1-2.1c-3.6-0.4-7.3-1.8-7.3-7.9c0-1.7,0.6-3.2,1.6-4.3 c-0.2-0.4-0.7-2,0.2-4.2c0,0,1.3-0.4,4.4,1.6c1.3-0.4,2.6-0.5,4-0.5c1.4,0,2.7,0.2,4,0.5c3.1-2.1,4.4-1.6,4.4-1.6 c0.9,2.2,0.3,3.8,0.2,4.2c1,1.1,1.6,2.5,1.6,4.3c0,6.1-3.7,7.5-7.3,7.9c0.6,0.5,1.1,1.5,1.1,3c0,2.1,0,3.9,0,4.4 c0,0.4,0.3,0.9,1.1,0.8C43.4,45.1,48,39.1,48,32C48,23.2,40.8,16,32,16z',
mask:
'M0,0v64h64V0H0z M37.1,47.2c-0.8,0.2-1.1-0.3-1.1-0.8c0-0.5,0-2.3,0-4.4c0-1.5-0.5-2.5-1.1-3 c3.6-0.4,7.3-1.7,7.3-7.9c0-1.7-0.6-3.2-1.6-4.3c0.2-0.4,0.7-2-0.2-4.2c0,0-1.3-0.4-4.4,1.6c-1.3-0.4-2.6-0.5-4-0.5 c-1.4,0-2.7,0.2-4,0.5c-3.1-2.1-4.4-1.6-4.4-1.6c-0.9,2.2-0.3,3.8-0.2,4.2c-1,1.1-1.6,2.5-1.6,4.3c0,6.1,3.7,7.5,7.3,7.9 c-0.5,0.4-0.9,1.1-1,2.1c-0.9,0.4-3.2,1.1-4.7-1.3c0,0-0.8-1.5-2.5-1.6c0,0-1.6,0-0.1,1c0,0,1,0.5,1.8,2.3c0,0,0.9,3.1,5.4,2.1 c0,1.3,0,2.3,0,2.7c0,0.4-0.3,0.9-1.1,0.8C20.6,45.1,16,39.1,16,32c0-8.8,7.2-16,16-16c8.8,0,16,7.2,16,16 C48,39.1,43.4,45.1,37.1,47.2z'
'M0,0v64h64V0H0z M37.1,47.2c-0.8,0.2-1.1-0.3-1.1-0.8c0-0.5,0-2.3,0-4.4c0-1.5-0.5-2.5-1.1-3 c3.6-0.4,7.3-1.7,7.3-7.9c0-1.7-0.6-3.2-1.6-4.3c0.2-0.4,0.7-2-0.2-4.2c0,0-1.3-0.4-4.4,1.6c-1.3-0.4-2.6-0.5-4-0.5 c-1.4,0-2.7,0.2-4,0.5c-3.1-2.1-4.4-1.6-4.4-1.6c-0.9,2.2-0.3,3.8-0.2,4.2c-1,1.1-1.6,2.5-1.6,4.3c0,6.1,3.7,7.5,7.3,7.9 c-0.5,0.4-0.9,1.1-1,2.1c-0.9,0.4-3.2,1.1-4.7-1.3c0,0-0.8-1.5-2.5-1.6c0,0-1.6,0-0.1,1c0,0,1,0.5,1.8,2.3c0,0,0.9,3.1,5.4,2.1 c0,1.3,0,2.3,0,2.7c0,0.4-0.3,0.9-1.1,0.8C20.6,45.1,16,39.1,16,32c0-8.8,7.2-16,16-16c8.8,0,16,7.2,16,16 C48,39.1,43.4,45.1,37.1,47.2z',
},
email: {
icon:
'M17,22v20h30V22H17z M41.1,25L32,32.1L22.9,25H41.1z M20,39V26.6l12,9.3l12-9.3V39H20z',
mask:
'M41.1,25H22.9l9.1,7.1L41.1,25z M44,26.6l-12,9.3l-12-9.3V39h24V26.6z M0,0v64h64V0H0z M47,42H17V22h30V42z'
}
'M41.1,25H22.9l9.1,7.1L41.1,25z M44,26.6l-12,9.3l-12-9.3V39h24V26.6z M0,0v64h64V0H0z M47,42H17V22h30V42z',
},
}
export default function SocialIcon({ media }: { media: keyof typeof icons }) {
@ -44,7 +44,7 @@ export default function SocialIcon({ media }: { media: keyof typeof icons }) {
fill: 'transparent',
height: '2rem',
margin: '0.6rem',
fillRule: 'evenodd'
fillRule: 'evenodd',
}}
>
<g
@ -54,7 +54,7 @@ export default function SocialIcon({ media }: { media: keyof typeof icons }) {
height: '50px',
position: 'relative',
overflow: 'hidden',
verticalAlign: 'middle'
verticalAlign: 'middle',
}}
>
<circle cx="32" cy="32" r="31" />

View File

@ -36,7 +36,7 @@ const Switch = styled.label`
right: 0;
bottom: 0;
background-color: #ccc;
transition: 0.4s;
transition: 0.1s;
}
.slider:before {
@ -47,7 +47,7 @@ const Switch = styled.label`
left: 4px;
bottom: 4px;
background-color: white;
transition: 0.4s;
transition: 0.1s;
}
input:checked + .slider {

View File

@ -6,7 +6,7 @@ import {
Spring,
SpringConfig,
Trail,
Transition
Transition,
} from 'react-spring/renderprops'
type Props = {
@ -22,7 +22,7 @@ export const fromBottom = ({
children,
config = configPresets.stiff,
style: inheritedStyle = {},
delay = 0
delay = 0,
}: Props) => (
<Trail
keys={React.Children.map(children, (_, i) => i) ?? []}
@ -33,14 +33,14 @@ export const fromBottom = ({
to={{ opacity: 1, y: 0 }}
items={children}
>
{item => ({ y, ...style }) => (
{(item) => ({ y, ...style }) => (
<animated.div
style={{
transform: interpolate([y], y =>
transform: interpolate([y], (y) =>
y !== 0 ? `translate3d(0, ${y}px,0)` : 'none'
),
...style,
...inheritedStyle
...inheritedStyle,
}}
>
{item}
@ -52,7 +52,7 @@ export const fromTop = ({
children,
config = configPresets.stiff,
style: inheritedStyle = {},
delay = 0
delay = 0,
}: Props) => (
<Trail
keys={React.Children.map(children, (_, i) => i) ?? []}
@ -63,14 +63,14 @@ export const fromTop = ({
to={{ opacity: 1, y: 0 }}
items={children}
>
{item => ({ y, ...style }) => (
{(item) => ({ y, ...style }) => (
<animated.div
style={{
transform: interpolate([y], y =>
transform: interpolate([y], (y) =>
y !== 0 ? `translate3d(0, ${y}px,0)` : 'none'
),
...style,
...inheritedStyle
...inheritedStyle,
}}
>
{item}
@ -82,36 +82,36 @@ export const fromTop = ({
export const leftToRight = ({
children,
config = configPresets.stiff,
delay = 0
delay = 0,
}: Props) => (
<Transition
from={{
opacity: 0,
transform: 'translateX(100%)'
transform: 'translateX(100%)',
}}
native
keys={location.pathname}
enter={{
opacity: 1,
transform: 'translateX(0%)'
transform: 'translateX(0%)',
}}
config={config}
delay={delay}
leave={{
opacity: 0,
position: 'absolute' as const,
transform: 'translateX(-100%)'
transform: 'translateX(-100%)',
}}
items={children}
>
{item => style => <animated.div style={style}>{item}</animated.div>}
{(item) => (style) => <animated.div style={style}>{item}</animated.div>}
</Transition>
)
export const fadeIn = ({
children,
config = configPresets.default,
delay = 0
delay = 0,
}: Props) => (
<Spring
native={true}
@ -119,10 +119,10 @@ export const fadeIn = ({
config={config}
from={{ opacity: 0 }}
to={{
opacity: 1
opacity: 1,
}}
>
{style => <animated.div style={style}>{children}</animated.div>}
{(style) => <animated.div style={style}>{children}</animated.div>}
</Spring>
)
@ -132,7 +132,7 @@ export function appear({
unless = false,
config = configPresets.default,
delay = 0,
style
style,
}: Props & { unless?: boolean }) {
// TODO: We should rename this function Appear
// eslint-disable-next-line react-hooks/rules-of-hooks
@ -149,10 +149,10 @@ export function appear({
config={config}
to={{
opacity: show ? 1 : 0,
height: show ? 'auto' : '0px'
height: show ? 'auto' : '0px',
}}
>
{animStyle => (
{(animStyle) => (
<animated.div style={{ ...style, ...animStyle }} className={className}>
{children}
</animated.div>
@ -166,5 +166,5 @@ export default {
fromBottom,
leftToRight,
fromTop,
fadeIn
fadeIn,
}

View File

@ -14,7 +14,7 @@ export default function Meta({
description,
ogDescription,
ogTitle,
ogImage
ogImage,
}: PropType) {
const { pathname } = useLocation()
return (

View File

@ -9,7 +9,7 @@ const forEachParent = (node: Node | null, fn: (node: Node) => void) => {
}
export function ScrollToTop({
behavior = 'auto'
behavior = 'auto',
}: {
behavior?: ScrollBehavior
}) {
@ -20,11 +20,11 @@ export function ScrollToTop({
;(window as any).parentIFrame.scrollToOffset(0, 0)
return
}
forEachParent(ref.current, elem => ((elem as any).scrollTop = 0))
forEachParent(ref.current, (elem) => ((elem as any).scrollTop = 0))
try {
window.scroll({
top: 0,
behavior
behavior,
})
} catch (e) {
window.scroll(0, 0)
@ -62,11 +62,11 @@ export function ScrollToElement({
ref.current?.scrollIntoView({
behavior,
block: 'nearest',
inline: 'nearest'
inline: 'nearest',
})
} catch (error) {
ref.current?.scrollIntoView({
behavior
behavior,
})
}
}
@ -77,7 +77,7 @@ export function ScrollToElement({
{...otherProps}
style={{
...style,
...(!children ? { position: 'absolute' } : {})
...(!children ? { position: 'absolute' } : {}),
}}
ref={ref}
>
@ -88,5 +88,5 @@ export function ScrollToElement({
export default {
toElement: ScrollToElement,
toTop: ScrollToTop
toTop: ScrollToTop,
}

View File

@ -24,7 +24,7 @@ function findContrastedTextColor(color: string, simple: boolean) {
return r * 0.299 + g * 0.587 + b * 0.114 > 128 ? '#000000' : '#ffffff'
} // else complex formula
const uicolors = [r / 255, g / 255, b / 255],
c = uicolors.map(c =>
c = uicolors.map((c) =>
c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
),
L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2]
@ -42,7 +42,7 @@ const generateDarkenVariations = (
[h, s, l]: [number, number, number]
) => {
return [...Array(numberOfVariation).keys()].map(
i => '#' + convert.hsl.hex([h, s, l * 0.8 ** i])
(i) => '#' + convert.hsl.hex([h, s, l * 0.8 ** i])
)
}
@ -51,7 +51,7 @@ const deriveAnalogousPalettes = (hex: string) => {
return [
generateDarkenVariations(4, [(h - 45) % 360, 0.75 * s, l]),
generateDarkenVariations(4, [(h + 45) % 360, 0.75 * s, l]),
generateDarkenVariations(4, [(h + 90) % 360, 0.75 * s, l])
generateDarkenVariations(4, [(h + 90) % 360, 0.75 * s, l]),
]
}
@ -86,7 +86,7 @@ const generateTheme = (themeColor?: string) => {
lighterColor,
lightestColor,
darkestColor,
palettes
palettes,
}
}

View File

@ -1,2 +1,2 @@
import { createContext } from 'react';
export const IsEmbeddedContext = createContext(false);
import { createContext } from 'react'
export const IsEmbeddedContext = createContext(false)

View File

@ -8,7 +8,7 @@ import { SiteNameContext } from '../../Provider'
const internalURLs = {
'mon-entreprise.fr': 'mon-entreprise',
'mycompanyinfrance.fr': 'infrance',
'publi.codes': 'publicodes'
'publi.codes': 'publicodes',
} as const
export function LinkRenderer({
@ -68,7 +68,7 @@ type MarkdownProps = ReactMarkdownProps & {
const LazySyntaxHighlighter = React.lazy(() => import('../SyntaxHighlighter'))
const CodeBlock = ({
value,
language
language,
}: {
value: string
language: string
@ -106,14 +106,14 @@ export const Markdown = ({
...otherProps
}: MarkdownProps) => (
<ReactMarkdown
transformLinkUri={src => src}
transformLinkUri={(src) => src}
source={source}
className={`markdown ${className}`}
renderers={{
link: LinkRenderer,
text: TextRenderer,
code: CodeBlock,
...renderers
...renderers,
}}
{...otherProps}
/>
@ -126,7 +126,7 @@ export const MarkdownWithAnchorLinks = ({
<Markdown
renderers={{
heading: HeadingWithAnchorLink,
...renderers
...renderers,
}}
{...otherProps}
/>
@ -134,7 +134,7 @@ export const MarkdownWithAnchorLinks = ({
function HeadingWithAnchorLink({
level,
children
children,
}: {
level: number
children: React.ReactNode

View File

@ -1,10 +1,10 @@
import { useEffect, useRef, useState } from 'react'
export default function({
export default function ({
root = null,
rootMargin,
threshold = 0,
unobserve = true
unobserve = true,
}: IntersectionObserverInit & { unobserve?: boolean }): [
React.RefObject<HTMLDivElement>,
boolean
@ -26,7 +26,7 @@ export default function({
{
root,
rootMargin,
threshold
threshold,
}
)
const node = ref.current

View File

@ -20,7 +20,7 @@ import {
sortWith,
takeWhile,
toPairs,
zipWith
zipWith,
} from 'ramda'
import { useContext, useMemo } from 'react'
import { useSelector } from 'react-redux'
@ -31,7 +31,7 @@ import {
configSelector,
currentQuestionSelector,
objectifsSelector,
situationSelector
situationSelector,
} from 'Selectors/simulationSelectors'
import { EngineContext } from './EngineContext'
@ -54,7 +54,7 @@ export function getNextSteps(
// Give higher score to top level questions
([name, score]) => [
name,
score + Math.max(0, 4 - name.split('.').length)
score + Math.max(0, 4 - name.split('.').length),
]
)
)
@ -89,14 +89,14 @@ export function getNextQuestions(
const {
'non prioritaires': notPriority = [],
liste: whitelist = [],
'liste noire': blacklist = []
'liste noire': blacklist = [],
} = questionConfig
let nextSteps = difference(getNextSteps(missingVariables), answeredQuestions)
nextSteps = nextSteps.filter(
step =>
(!whitelist.length || whitelist.some(name => step.startsWith(name))) &&
(!blacklist.length || !blacklist.some(name => step.startsWith(name)))
(step) =>
(!whitelist.length || whitelist.some((name) => step.startsWith(name))) &&
(!blacklist.length || !blacklist.some((name) => step.startsWith(name)))
)
const lastStep = last(answeredQuestions)
@ -109,16 +109,17 @@ export function getNextQuestions(
.replace(/'/g, '')
.trim() as DottedName)
: lastStep
return sortBy(question => {
const indexList = whitelist.findIndex(name => question.startsWith(name)) + 1
return sortBy((question) => {
const indexList =
whitelist.findIndex((name) => question.startsWith(name)) + 1
const indexNotPriority =
notPriority.findIndex(name => question.startsWith(name)) + 1
notPriority.findIndex((name) => question.startsWith(name)) + 1
const differenceCoeff = questionDifference(question, lastStepWithAnswer)
return indexList + indexNotPriority + differenceCoeff
}, nextSteps)
}
export const useNextQuestions = function(): Array<DottedName> {
export const useNextQuestions = function (): Array<DottedName> {
const objectifs = useSelector(objectifsSelector)
const answeredQuestions = useSelector(answeredQuestionsSelector)
const currentQuestion = useSelector(currentQuestionSelector)
@ -126,7 +127,7 @@ export const useNextQuestions = function(): Array<DottedName> {
const situation = useSelector(situationSelector)
const engine = useContext(EngineContext)
const missingVariables = objectifs.map(
node => engine.evaluate(node).missingVariables ?? {}
(node) => engine.evaluate(node).missingVariables ?? {}
)
const nextQuestions = useMemo(() => {
return getNextQuestions(

View File

@ -7,9 +7,9 @@ i18next
.use(initReactI18next)
.init({
react: {
useSuspense: false
}
useSuspense: false,
},
})
.catch(err => console?.error('Error from i18n load', err))
.catch((err) => console?.error('Error from i18n load', err))
export default i18next

View File

@ -7,7 +7,7 @@ import { combineReducers } from 'redux'
import { LegalStatus } from 'Selectors/companyStatusSelectors'
import {
Action as CompanyStatusAction,
LegalStatusRequirements
LegalStatusRequirements,
} from 'Types/companyTypes'
type Action =
@ -46,7 +46,7 @@ function hiringChecklist(
case 'CHECK_HIRING_ITEM':
return {
...state,
[action.name]: action.checked
[action.name]: action.checked,
}
case 'INITIALIZE_HIRING_CHECKLIST':
return Object.keys(state).length
@ -68,7 +68,7 @@ function companyCreationChecklist(
case 'CHECK_COMPANY_CREATION_ITEM':
return {
...state,
[action.name]: action.checked
[action.name]: action.checked,
}
case 'INITIALIZE_COMPANY_CREATION_CHECKLIST':
return Object.keys(state).length
@ -157,7 +157,7 @@ function existingCompany(
...state,
siren: state.siren,
statutJuridique,
dateDeCréation: action.dateDeCréation
dateDeCréation: action.dateDeCréation,
}
}
if (state && action.type === 'EXISTING_COMPANY::SPECIFY_AUTO_ENTREPRENEUR') {
@ -180,5 +180,5 @@ export default combineReducers({
companyStatusChoice,
companyCreationChecklist,
existingCompany,
hiringChecklist
hiringChecklist,
})

View File

@ -74,14 +74,14 @@ export type Simulation = {
function getCompanySituation(company: Company | null): Situation {
return {
...(company?.localisation && {
'établissement . localisation': company.localisation
'établissement . localisation': { objet: company.localisation },
}),
...(company?.dateDeCréation && {
'entreprise . date de création': company.dateDeCréation.replace(
/(.*)-(.*)-(.*)/,
'$3/$2/$1'
)
})
),
}),
}
}
@ -106,7 +106,7 @@ function simulation(
initialSituation: companySituation,
targetUnit: config['unité par défaut'] || '€/mois',
foldedSteps: Object.keys(companySituation) as Array<DottedName>,
unfoldedStep: null
unfoldedStep: null,
}
}
if (state === null) {
@ -117,7 +117,7 @@ function simulation(
case 'HIDE_NOTIFICATION':
return {
...state,
hiddenNotifications: [...state.hiddenNotifications, action.id]
hiddenNotifications: [...state.hiddenNotifications, action.id],
}
case 'RESET_SIMULATION':
return {
@ -125,7 +125,7 @@ function simulation(
hiddenNotifications: [],
situation: state.initialSituation,
foldedSteps: [],
unfoldedStep: null
unfoldedStep: null,
}
case 'UPDATE_SITUATION': {
const targets = without(
@ -143,8 +143,8 @@ function simulation(
...(targets.includes(dottedName)
? omit(targets, situation)
: situation),
[dottedName]: value
}
[dottedName]: value,
},
}
}
case 'STEP_ACTION': {
@ -153,13 +153,13 @@ function simulation(
return {
...state,
foldedSteps: [...state.foldedSteps, step],
unfoldedStep: null
unfoldedStep: null,
}
if (name === 'unfold') {
return {
...state,
foldedSteps: without([step], state.foldedSteps),
unfoldedStep: step
unfoldedStep: step,
}
}
return state
@ -167,7 +167,7 @@ function simulation(
case 'UPDATE_TARGET_UNIT':
return {
...state,
targetUnit: action.targetUnit
targetUnit: action.targetUnit,
}
}
return state
@ -180,9 +180,9 @@ const existingCompanyReducer = (state: RootState, action: Action) => {
...state.simulation,
situation: {
...state.simulation.situation,
...getCompanySituation(state.inFranceApp.existingCompany)
}
}
...getCompanySituation(state.inFranceApp.existingCompany),
},
},
}
}
return state
@ -196,7 +196,7 @@ const mainReducer = (state: any, action: Action) =>
previousSimulation: defaultTo(null) as Reducer<SavedSimulation | null>,
situationBranch,
activeTargetInput,
inFranceApp: inFranceAppReducer
inFranceApp: inFranceAppReducer,
})(state, action)
export default reduceReducers<RootState>(

View File

@ -7,12 +7,12 @@ export default (state: RootState, action: Action): RootState => {
case 'LOAD_PREVIOUS_SIMULATION':
return {
...state,
...createStateFromSavedSimulation(state)
...createStateFromSavedSimulation(state),
}
case 'DELETE_PREVIOUS_SIMULATION':
return {
...state,
previousSimulation: null
previousSimulation: null,
}
default:
return state

View File

@ -1,15 +1,16 @@
artiste-auteur:
description: Le régime des artistes-auteurs
icônes: 👩‍🎨
formule: oui
artiste-auteur . revenus:
artiste-auteur . revenus: oui
artiste-auteur . revenus . traitements et salaires:
titre: Revenu en traitements et salaires
par défaut: 0 €/an
résumé: Le montant brut hors TVA de vos droits d'auteur (recettes précomptées)
artiste-auteur . revenus . BNC:
unité: €/an
formule:
allègement:
assiette: recettes
@ -33,6 +34,7 @@ artiste-auteur . revenus . BNC . micro-bnc . contrôle micro-bnc:
- recettes > 72500 €/an
artiste-auteur . revenus . BNC . recettes:
titre: Revenu en BNC
par défaut: 0 €/an
résumé: Le montant de vos recettes brutes hors TVA

View File

@ -41,7 +41,7 @@ const rules = {
...CCSport,
...CCCompta,
...situationPersonnelle,
...chômagePartiel
...chômagePartiel,
}
export default rules

View File

@ -10,7 +10,7 @@ import {
map,
mergeAll,
mergeWith,
sortBy
sortBy,
} from 'ramda'
import { RootState } from 'Reducers/rootReducer'
import { LegalStatusRequirements, State } from '../types/companyTypes'
@ -21,41 +21,41 @@ const LEGAL_STATUS_DETAILS = {
directorStatus: 'SELF_EMPLOYED',
minorityDirector: false,
multipleAssociates: false,
autoEntrepreneur: true
autoEntrepreneur: true,
},
EIRL: {
soleProprietorship: true,
directorStatus: 'SELF_EMPLOYED',
multipleAssociates: false,
autoEntrepreneur: false,
minorityDirector: false
minorityDirector: false,
},
'auto-entrepreneur-EIRL': {
soleProprietorship: true,
directorStatus: 'SELF_EMPLOYED',
multipleAssociates: false,
minorityDirector: false,
autoEntrepreneur: true
autoEntrepreneur: true,
},
EI: {
soleProprietorship: true,
directorStatus: 'SELF_EMPLOYED',
minorityDirector: false,
multipleAssociates: false,
autoEntrepreneur: false
autoEntrepreneur: false,
},
SASU: {
soleProprietorship: false,
directorStatus: 'SALARIED',
minorityDirector: false,
multipleAssociates: false,
autoEntrepreneur: false
autoEntrepreneur: false,
},
SAS: {
soleProprietorship: false,
directorStatus: 'SALARIED',
multipleAssociates: true,
autoEntrepreneur: false
autoEntrepreneur: false,
},
SARL: [
{
@ -63,29 +63,29 @@ const LEGAL_STATUS_DETAILS = {
directorStatus: 'SELF_EMPLOYED',
multipleAssociates: true,
minorityDirector: false,
autoEntrepreneur: false
autoEntrepreneur: false,
},
{
soleProprietorship: false,
directorStatus: 'SALARIED',
multipleAssociates: true,
minorityDirector: true,
autoEntrepreneur: false
}
autoEntrepreneur: false,
},
] as Array<LegalStatusRequirements>,
EURL: {
soleProprietorship: false,
directorStatus: 'SELF_EMPLOYED',
minorityDirector: false,
multipleAssociates: false,
autoEntrepreneur: false
autoEntrepreneur: false,
},
SA: {
soleProprietorship: false,
directorStatus: 'SALARIED',
multipleAssociates: true,
autoEntrepreneur: false
}
autoEntrepreneur: false,
},
}
export type LegalStatus = keyof typeof LEGAL_STATUS_DETAILS
@ -98,7 +98,7 @@ const QUESTION_LIST: Array<Question> = keys(
const isCompatibleStatusWith = (answers: any) => (
statusRequirements: LegalStatusRequirements
): boolean => {
const stringify = map(x => (!isNil(x) ? JSON.stringify(x) : x))
const stringify = map((x) => (!isNil(x) ? JSON.stringify(x) : x))
const answerCompatibility = Object.values(
mergeWith(
(answer, statusValue) =>
@ -107,14 +107,14 @@ const isCompatibleStatusWith = (answers: any) => (
stringify(answers)
)
)
const isCompatibleStatus = answerCompatibility.every(x => x !== false)
const isCompatibleStatus = answerCompatibility.every((x) => x !== false)
return isCompatibleStatus
}
const possibleStatus = (
answers: Array<LegalStatusRequirements> | LegalStatusRequirements
): Record<LegalStatus, boolean> =>
map(
statusRequirements =>
(statusRequirements) =>
Array.isArray(statusRequirements)
? any(isCompatibleStatusWith(answers as any), statusRequirements)
: isCompatibleStatusWith(answers as any)(
@ -130,9 +130,9 @@ export const possibleStatusSelector = (state: {
export const nextQuestionSelector = (state: RootState): Question | null => {
const legalStatusRequirements = state.inFranceApp.companyLegalStatus
const questionAnswered = Object.keys(legalStatusRequirements) as Array<
Question
>
const questionAnswered = Object.keys(
legalStatusRequirements
) as Array<Question>
const possibleStatusList = flatten(
Object.values(LEGAL_STATUS_DETAILS)
).filter(isCompatibleStatusWith(legalStatusRequirements) as any)
@ -147,12 +147,12 @@ export const nextQuestionSelector = (state: RootState): Question | null => {
)
const frequencyOfAnswers = Object.values(
countBy(
x => x,
answerPopulation.filter(x => x !== undefined)
(x) => x,
answerPopulation.filter((x) => x !== undefined)
)
).map(numOccurrence => numOccurrence / answerPopulation.length)
).map((numOccurrence) => numOccurrence / answerPopulation.length)
const shannonEntropy = -frequencyOfAnswers
.map(p => p * Math.log2(p))
.map((p) => p * Math.log2(p))
.reduce(add, 0)
return [question, shannonEntropy]
})

View File

@ -5,7 +5,7 @@ import { RootState, SimulationConfig } from 'Reducers/rootReducer'
export const configSelector = (state: RootState): Partial<SimulationConfig> =>
state.simulation?.config ?? {}
export const objectifsSelector = createSelector([configSelector], config => {
export const objectifsSelector = createSelector([configSelector], (config) => {
const primaryObjectifs = (config.objectifs ?? ([] as any))
.map((obj: DottedName | { objectifs: Array<DottedName> }) =>
typeof obj === 'string' ? [obj] : obj.objectifs
@ -16,10 +16,9 @@ export const objectifsSelector = createSelector([configSelector], config => {
return objectifs
})
const emptySituation: Partial<Record<
DottedName,
string | number | Record<string, unknown>
>> = {}
const emptySituation: Partial<
Record<DottedName, string | number | Record<string, unknown>>
> = {}
export const situationSelector = (state: RootState) =>
state.simulation?.situation ?? emptySituation
@ -33,7 +32,7 @@ export const firstStepCompletedSelector = createSelector(
if (!situation) {
return false
}
return objectifs.some(objectif => {
return objectifs.some((objectif) => {
return objectif in situation
})
}

View File

@ -16,7 +16,7 @@ export const currentSimulationSelector = (
return {
situation: state.simulation?.situation ?? {},
activeTargetInput: state.activeTargetInput,
foldedSteps: state.simulation?.foldedSteps
foldedSteps: state.simulation?.foldedSteps,
}
}
@ -29,8 +29,8 @@ export const createStateFromSavedSimulation = (
simulation: {
...state.simulation,
situation: state.previousSimulation.situation || {},
foldedSteps: state.previousSimulation.foldedSteps
foldedSteps: state.previousSimulation.foldedSteps,
} as Simulation,
previousSimulation: null
previousSimulation: null,
}
: {}

View File

@ -10,12 +10,12 @@ const history = require('connect-history-api-fallback')
const { watchDottedNames } = require('../scripts/dottednames')
watchDottedNames()
const rewrite = basename => ({
const rewrite = (basename) => ({
from: new RegExp(`^/${basename}/(.*)$|^/${basename}$`),
to: `/${basename}.html`
to: `/${basename}.html`,
})
app.get('/', function(req, res) {
app.get('/', function (req, res) {
res.send(`<ul><li><a href="/mon-entreprise">mon-entreprise [fr]</a></li>
<li><a href="/infrance">infrance [en]</a></li>
<li><a href="/mon-entreprise/dev/integration-test">intégration du simulateur sur site tiers [iframe fr]</a></li><li><a href="/publicodes">publicodes</a></li></ul>`)
@ -23,7 +23,7 @@ app.get('/', function(req, res) {
app.use(
history({
rewrites: ['infrance', 'mon-entreprise', 'publicodes'].map(rewrite)
rewrites: ['infrance', 'mon-entreprise', 'publicodes'].map(rewrite),
})
)
@ -32,13 +32,13 @@ app.use(
app.use(
webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
hot: true
hot: true,
})
)
app.use(require('webpack-hot-middleware')(compiler))
app.listen(8080, function() {
app.listen(8080, function () {
// eslint-disable-next-line no-console
console.log('Mon-entreprise listening on port 8080!\n')
})

View File

@ -7,8 +7,7 @@ import {
} from 'Components/utils/EngineContext'
import { SitePathsContext } from 'Components/utils/SitePathsContext'
import 'iframe-resizer'
import Engine from 'publicodes'
import { Rule } from 'publicodes/dist/types/rule'
import Engine, { Rule } from 'publicodes'
import { useContext, useMemo } from 'react'
import { Helmet } from 'react-helmet'
import { useTranslation } from 'react-i18next'

View File

@ -29,7 +29,7 @@ const iframeAttributes = {
style: 'border: none; width: 100%; display: block; height: 500px',
allowfullscreen: true,
webkitallowfullscreen: true,
mozallowfullscreen: true
mozallowfullscreen: true,
}
for (var key in iframeAttributes) {
iframe.setAttribute(key, iframeAttributes[key])
@ -38,7 +38,7 @@ iframeResizer(
{
interval: 0,
scrolling: 'auto',
heightCalculationMethod: 'lowestElement'
heightCalculationMethod: 'lowestElement',
},
iframe
)
@ -48,7 +48,7 @@ const moduleToSitePath = {
'simulateur-embauche': '/simulateurs/salarié',
'simulateur-autoentrepreneur': '/simulateurs/auto-entrepreneur',
'simulateur-independant': '/simulateurs/indépendant',
'simulateur-dirigeantsasu': '/simulateurs/dirigeant-sasu'
'simulateur-dirigeantsasu': '/simulateurs/dirigeant-sasu',
}
const simulateurLink = (fr ? process.env.FR_SITE : process.env.EN_SITE).replace(
'${path}',

View File

@ -22,16 +22,16 @@ const useShowFeedback = () => {
[
simulators['aide-déclaration-indépendant'],
simulators['comparaison-statuts'],
simulators['demande-mobilité']
simulators['demande-mobilité'],
]
.map(s => s.path)
.map((s) => s.path)
.includes(currentPath)
) {
return true
}
return ![
sitePath.index,
...Object.values(simulators).map(s => s.path)
...Object.values(simulators).map((s) => s.path),
].includes(currentPath)
}
export default function Footer() {

View File

@ -17,7 +17,7 @@ export default function Header() {
className="ui__ container"
style={{
display: 'flex',
alignItems: 'center'
alignItems: 'center',
}}
>
<Link style={{ height: '4rem' }} to={sitePaths.index}>
@ -25,7 +25,7 @@ export default function Header() {
alt="logo mon-entreprise.fr"
style={{
padding: '0.5rem 0',
height: '100%'
height: '100%',
}}
src={language === 'fr' ? logoSvg : logoEnSvg}
/>
@ -36,7 +36,7 @@ export default function Header() {
target="_blank"
style={{
height: '4rem',
padding: '1rem'
padding: '1rem',
}}
>
<img
@ -50,7 +50,7 @@ export default function Header() {
target="_blank"
style={{
height: '4rem',
padding: '1rem'
padding: '1rem',
}}
className="landing-header__institutional-logo"
>

View File

@ -12,7 +12,7 @@ export default (tracker: Tracker) => {
'Simulator::answer',
action.source,
action.step,
situationSelector(newState)[action.step as DottedName]
situationSelector(newState)[action.step as DottedName],
])
// TODO : add tracking in UI instead ?
@ -31,7 +31,7 @@ export default (tracker: Tracker) => {
'trackEvent',
'Simulator',
'target selected',
newState.activeTargetInput
newState.activeTargetInput,
])
}
@ -45,7 +45,7 @@ export default (tracker: Tracker) => {
'update situation',
...(action.type === 'UPDATE_TARGET_UNIT'
? ['unité', action.targetUnit]
: [action.fieldName, action.value])
: [action.fieldName, action.value]),
])
}
if (action.type === 'START_CONVERSATION') {
@ -55,8 +55,8 @@ export default (tracker: Tracker) => {
'conversation started',
JSON.stringify({
target: newState.activeTargetInput,
question: action.question
})
question: action.question,
}),
])
}
if (action.type == 'STEP_ACTION' && action.name == 'unfold') {
@ -64,7 +64,7 @@ export default (tracker: Tracker) => {
'trackEvent',
'Simulator',
'change answer',
action.step
action.step,
])
}
@ -76,7 +76,7 @@ export default (tracker: Tracker) => {
'trackEvent',
'Creation',
'status chosen',
action.statusName
action.statusName,
])
}
}

View File

@ -16,12 +16,12 @@ const [
intro,
ressources2019,
ressources2020,
ressourcesDescription
ressourcesDescription,
] = prose.split(/\r?\n-{3,}\r?\n/)
const ressources = {
2019: ressources2019,
2020: ressources2020
2020: ressources2020,
}
export default function Budget() {
@ -30,7 +30,7 @@ export default function Budget() {
const [selectedYear, setSelectedYear] = useState<typeof years[number]>('2020')
const categories = uniq(
quarters
.map(q => Object.keys(budget[2020][q] ?? {}))
.map((q) => Object.keys(budget[2020][q] ?? {}))
.reduce((acc, curr) => [...acc, ...curr], [])
)
@ -44,11 +44,11 @@ export default function Budget() {
{emoji('📅')} Année{' '}
<select
value={selectedYear}
onChange={event =>
onChange={(event) =>
setSelectedYear(event.target.value as typeof years[number])
}
>
{years.map(year => (
{years.map((year) => (
<option key={year}>{year}</option>
))}
</select>
@ -61,24 +61,24 @@ export default function Budget() {
<thead>
<tr>
<td>2020</td>
{quarters.map(q => (
{quarters.map((q) => (
<td key={q}>{q}</td>
))}
<td>Total</td>
</tr>
</thead>
<tbody>
{categories.map(label => (
{categories.map((label) => (
<tr key={label}>
<td>{label}</td>
{quarters.map(q => {
{quarters.map((q) => {
const value = budget[2020]?.[q]?.[label]
return (
<td key={q}>
{value
? formatValue(value, {
displayedUnit: '€',
language
language,
})
: '-'}
</td>
@ -86,10 +86,10 @@ export default function Budget() {
})}
<td>
{formatValue(
sum(quarters.map(q => budget[2020]?.[q]?.[label] ?? 0)),
sum(quarters.map((q) => budget[2020]?.[q]?.[label] ?? 0)),
{
displayedUnit: '€',
language
language,
}
)}
</td>
@ -99,14 +99,14 @@ export default function Budget() {
<tfoot>
<tr>
<td>Total</td>
{quarters.map(q => {
{quarters.map((q) => {
const value = sum(Object.values(budget[2020]?.[q] ?? {}))
return (
<td key={q}>
{value
? formatValue(value, {
displayedUnit: '€',
language
language,
})
: '-'}
</td>
@ -115,13 +115,13 @@ export default function Budget() {
<td>
{formatValue(
sum(
quarters.map(q =>
quarters.map((q) =>
sum(Object.values(budget[2020]?.[q] ?? {}))
)
),
{
displayedUnit: '€',
language
language,
}
)}
</td>

View File

@ -38,7 +38,7 @@ export default function AfterRegistration() {
{{
statutChoisi: isAutoentrepreneur
? t('auto-entreprise')
: statutChoisi || t(['après.entreprise', 'entreprise'])
: statutChoisi || t(['après.entreprise', 'entreprise']),
}}{' '}
créée, vous recevez les informations suivantes :
</Trans>

View File

@ -1,6 +1,6 @@
import {
checkCompanyCreationItem,
initializeCompanyCreationChecklist
initializeCompanyCreationChecklist,
} from 'Actions/companyCreationChecklistActions'
import { goToCompanyStatusChoice } from 'Actions/companyStatusActions'
import Scroll from 'Components/utils/Scroll'
@ -40,14 +40,14 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
? t(
[
'entreprise.page.autoEntrepreneur.titre',
'Devenir {{autoEntrepreneur}}'
'Devenir {{autoEntrepreneur}}',
],
{
autoEntrepreneur: statut
autoEntrepreneur: statut,
}
)
: t(['entreprise.page.entreprise.titre', 'Créer une {{status}}'], {
status: statut
status: statut,
})
return (
<Animate.fromBottom>
@ -60,14 +60,14 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
? t(
[
'entreprise.page.autoEntrepreneur.description',
'La liste complète des démarches à faire pour devenir {{autoEntrepreneur}}.'
'La liste complète des démarches à faire pour devenir {{autoEntrepreneur}}.',
],
{ autoEntrepreneur: t(statut) }
)
: t(
[
'entreprise.page.description',
"La liste complète des démarches à faire pour créer une {{statut}} auprès de l'administration française."
"La liste complète des démarches à faire pour créer une {{statut}} auprès de l'administration française.",
],
{ statut: t(statut) }
)
@ -104,7 +104,7 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
</p>
<Checklist
key={statut}
onInitialization={items =>
onInitialization={(items) =>
dispatch(initializeCompanyCreationChecklist(statut, items))
}
onItemCheck={(name, isChecked) =>
@ -205,7 +205,7 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
capital.{' '}
<span
style={{
display: multipleAssociates ? 'visible' : 'none'
display: multipleAssociates ? 'visible' : 'none',
}}
>
Dans le cas d'une création d'entreprise avec plusieurs
@ -458,7 +458,7 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
className="ui__ interactive card small box lighter-bg"
to={{
pathname: sitePaths.simulateurs['auto-entrepreneur'],
state: { fromCréer: true }
state: { fromCréer: true },
}}
>
<Trans i18nKey="entreprise.ressources.simu.autoEntrepreneur">
@ -475,7 +475,7 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
className="ui__ interactive card small box lighter-bg"
to={{
pathname: sitePaths.simulateurs.indépendant,
state: { fromCréer: true }
state: { fromCréer: true },
}}
>
<Trans i18nKey="entreprise.ressources.simu.indépendant">
@ -492,7 +492,7 @@ export default function CreateCompany({ statut }: CreateCompanyProps) {
className="ui__ interactive card small box lighter-bg"
to={{
pathname: sitePaths.simulateurs.SASU,
state: { fromCréer: true }
state: { fromCréer: true },
}}
>
<Trans i18nKey="entreprise.ressources.simu.assimilé">
@ -547,7 +547,7 @@ type StatutsExampleProps = {
const StatutsExample = ({ statut }: StatutsExampleProps) => {
const links = {
SARL: 'https://bpifrance-creation.fr/file/109068/download?token=rmc93Ve3',
EURL: 'https://bpifrance-creation.fr/file/109070/download?token=Ul-rT6Z0'
EURL: 'https://bpifrance-creation.fr/file/109070/download?token=Ul-rT6Z0',
}
if (!(statut in links)) return null

View File

@ -7,7 +7,7 @@ import { useSelector } from 'react-redux'
import { Link } from 'react-router-dom'
import {
LegalStatus,
possibleStatusSelector
possibleStatusSelector,
} from 'Selectors/companyStatusSelectors'
import StatutDescription from '../StatutDescription'

View File

@ -12,7 +12,7 @@ export default function SoleProprietorship() {
<title>
{t([
'responsabilité.page.titre',
'Choisir entre société ou entreprise individuelle'
'Choisir entre société ou entreprise individuelle',
])}
</title>
<meta

Some files were not shown because too many files have changed in this diff Show More