Autofix new eslint rules
parent
058702462e
commit
d0c4e69a8a
|
@ -6,4 +6,5 @@ import { Names } from './dist/names'
|
|||
|
||||
export type DottedName = Names
|
||||
declare let rules: Record<Names, Rule>
|
||||
|
||||
export default rules
|
||||
|
|
|
@ -6,4 +6,5 @@ import { Names } from './dist/names'
|
|||
|
||||
export type DottedName = Names
|
||||
declare let rules: Record<Names, Rule>
|
||||
|
||||
export default rules
|
||||
|
|
|
@ -25,7 +25,9 @@ const falsy = <T>(value: T | false): value is T => Boolean(value)
|
|||
const formatRulesToAlgolia = (rules: ParsedRules<string>) =>
|
||||
Object.entries(rules)
|
||||
.map(([n, rule]) => {
|
||||
if (!rule) return false
|
||||
if (!rule) {
|
||||
return false
|
||||
}
|
||||
const path = n.split(' . ')
|
||||
const {
|
||||
title,
|
||||
|
|
|
@ -85,6 +85,7 @@ export function createTracker(siteId?: string, doNotTrack = false) {
|
|||
super.dispatch()
|
||||
}
|
||||
}
|
||||
|
||||
return Tag
|
||||
}
|
||||
|
||||
|
@ -116,6 +117,7 @@ export class Log implements ATTracker {
|
|||
},
|
||||
getVisitorMode() {
|
||||
console.debug('ATTracker::privacy.getVisitorMode')
|
||||
|
||||
return { name: 'exempt' }
|
||||
},
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ export function toAtString(string: string): string {
|
|||
string = string.replace(/[\307\347]/g, 'c')
|
||||
string = string.replace(/[\321\361]/g, 'n')
|
||||
string = string.replace(/[^\w]/gi, '_')
|
||||
|
||||
return string
|
||||
}
|
||||
|
||||
|
@ -31,6 +32,7 @@ let chapters: {
|
|||
chapter2?: string
|
||||
chapter3?: string
|
||||
} = {}
|
||||
|
||||
export function TrackChapter(props: {
|
||||
chapter1?: Chapter1
|
||||
chapter2?: string
|
||||
|
@ -38,14 +40,17 @@ export function TrackChapter(props: {
|
|||
}) {
|
||||
if (props.chapter1) {
|
||||
chapters = { chapter2: '', chapter3: '', ...props }
|
||||
|
||||
return null
|
||||
}
|
||||
if (props.chapter2) {
|
||||
chapters = { ...chapters, chapter3: '', ...props }
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
chapters = { ...chapters, ...props }
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -73,5 +78,6 @@ export function TrackPage(props: {
|
|||
propsFormatted.chapter2,
|
||||
propsFormatted.chapter3,
|
||||
])
|
||||
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ export default function Root({
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[rules]
|
||||
)
|
||||
|
||||
return (
|
||||
<StrictMode>
|
||||
<Provider
|
||||
|
@ -105,6 +106,7 @@ const Router = () => {
|
|||
}),
|
||||
[configSituation, simulatorSituation, companySituation]
|
||||
)
|
||||
|
||||
return (
|
||||
<SituationProvider situation={situation}>
|
||||
<Switch>
|
||||
|
@ -130,6 +132,7 @@ const App = () => {
|
|||
const { t } = useTranslation()
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const isEmbedded = useIsEmbedded()
|
||||
|
||||
return (
|
||||
<StyledLayout isEmbeded={isEmbedded}>
|
||||
{!isEmbedded && <Header />}
|
||||
|
|
|
@ -28,6 +28,7 @@ export const useDispatchAndGoToNextQuestion = () => {
|
|||
history.push(nextQuestion)
|
||||
}
|
||||
}, [dispatched])
|
||||
|
||||
return (action: Action) => {
|
||||
dispatch(action)
|
||||
setDispatched(true)
|
||||
|
@ -76,6 +77,7 @@ export const resetCompanyStatusChoice = (
|
|||
|
||||
export const useSetEntreprise = () => {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
return (entreprise: FabriqueSocialEntreprise) => {
|
||||
if (entreprise === null) {
|
||||
return
|
||||
|
|
|
@ -37,6 +37,7 @@ export async function searchCommunes(
|
|||
return null
|
||||
}
|
||||
const json = (await response.json()) as Array<ApiCommuneJson>
|
||||
|
||||
return json
|
||||
.flatMap(({ codesPostaux, ...commune }) =>
|
||||
codesPostaux
|
||||
|
@ -68,6 +69,7 @@ export async function fetchCommuneDetails(
|
|||
if (taux === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
...commune,
|
||||
'taux du versement transport': taux,
|
||||
|
|
|
@ -64,5 +64,6 @@ async function searchFullText(
|
|||
}
|
||||
|
||||
const json: FabriqueSocialSearchPayload = await response.json()
|
||||
|
||||
return json.entreprises
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ export async function fetchCompanyDetails(siren: string) {
|
|||
return null
|
||||
}
|
||||
const json = await response.json()
|
||||
|
||||
return json.unite_legale
|
||||
}
|
||||
|
||||
|
@ -24,6 +25,7 @@ export async function searchDenominationOrSiren(value: string) {
|
|||
if (isSIREN(value)) {
|
||||
return [{ siren: value }]
|
||||
}
|
||||
|
||||
return searchFullText(value)
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ export default function Banner({
|
|||
const hiddenState = useSelector(firstStepCompletedSelector)
|
||||
|
||||
const hidden = hiddenProp || (hideAfterFirstStep && hiddenState)
|
||||
|
||||
return !hidden ? (
|
||||
<FadeIn className={className}>
|
||||
<Container>
|
||||
|
|
|
@ -37,6 +37,7 @@ function ChartItemBar({
|
|||
},
|
||||
flex: display ? percentage : 0,
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="distribution-chart__bar-container">
|
||||
{disableAnimation ? (
|
||||
|
|
|
@ -53,6 +53,7 @@ export default function Value<Names extends string>({
|
|||
</RuleLink>
|
||||
)
|
||||
}
|
||||
|
||||
return <span {...props}>{value}</span>
|
||||
}
|
||||
|
||||
|
@ -61,6 +62,7 @@ type ConditionProps = {
|
|||
defaultIfNotYetDefined?: boolean
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export function Condition({
|
||||
expression,
|
||||
defaultIfNotYetDefined = false,
|
||||
|
@ -82,6 +84,7 @@ export function Condition({
|
|||
if (!boolValue) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
|
@ -96,6 +99,7 @@ export function WhenApplicable({
|
|||
if (engine.evaluate(dottedName).nodeValue == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
export function WhenNotApplicable({
|
||||
|
@ -109,6 +113,7 @@ export function WhenNotApplicable({
|
|||
if (engine.evaluate(dottedName).nodeValue !== null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
|
@ -123,6 +128,7 @@ export function WhenAlreadyDefined({
|
|||
if (isNotYetDefined(engine.evaluate(dottedName).nodeValue)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
|
@ -137,5 +143,6 @@ export function WhenNotAlreadyDefined({
|
|||
if (!isNotYetDefined(engine.evaluate(dottedName).nodeValue)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ const askFeedback = (url: string) => {
|
|||
if (!previousFeedbackDate) {
|
||||
return true
|
||||
}
|
||||
|
||||
return (
|
||||
new Date(previousFeedbackDate) <
|
||||
new Date(new Date().setMonth(new Date().getMonth() - 4))
|
||||
|
|
|
@ -6,6 +6,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
|
||||
export default function LegalNotice() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<PopoverWithTrigger
|
||||
trigger={(buttonProps) => (
|
||||
|
|
|
@ -37,6 +37,7 @@ function getSection(rule: RuleNode): Section {
|
|||
if (SECTION_ORDER.includes(section)) {
|
||||
return section
|
||||
}
|
||||
|
||||
return 'protection sociale . autres'
|
||||
}
|
||||
|
||||
|
@ -75,11 +76,13 @@ export function getCotisationsBySection(
|
|||
)
|
||||
.reduce((acc, cotisation: DottedName) => {
|
||||
const sectionName = getSection(parsedRules[cotisation])
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[sectionName]: (acc[sectionName] ?? new Set()).add(cotisation),
|
||||
}
|
||||
}, {} as Record<Section, Set<DottedName>>)
|
||||
|
||||
return Object.entries(cotisations)
|
||||
.map(([section, dottedNames]) => [section, [...dottedNames.values()]])
|
||||
.sort(
|
||||
|
@ -132,6 +135,7 @@ export default function PaySlip() {
|
|||
</H4>
|
||||
{cotisationsBySection.map(([sectionDottedName, cotisations]) => {
|
||||
const section = parsedRules[sectionDottedName]
|
||||
|
||||
return (
|
||||
<Fragment key={section.dottedName}>
|
||||
<H5 className="payslip__cotisationTitle">
|
||||
|
@ -231,6 +235,7 @@ function Cotisation({ dottedName }: { dottedName: DottedName }) {
|
|||
if (!partPatronale.nodeValue && !partSalariale.nodeValue) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<RuleLink dottedName={dottedName} />
|
||||
|
|
|
@ -30,6 +30,7 @@ export const SalaireBrutSection = () => {
|
|||
|
||||
export const SalaireNetSection = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="payslip__salarySection">
|
||||
<H4 className="payslip__salaryTitle">
|
||||
|
@ -89,8 +90,9 @@ export function Line({
|
|||
// ⚠️ isNotApplicable is a bad func only here to help with further refactoring:
|
||||
isNotApplicable(evaluatedNode.nodeValue) ||
|
||||
evaluatedNode.nodeValue === 0
|
||||
)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Condition expression={`${rule} > 0`}>
|
||||
|
|
|
@ -19,6 +19,7 @@ export default function PeriodSwitch() {
|
|||
unit: '€/an',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ToggleGroup
|
||||
|
|
|
@ -15,6 +15,7 @@ export default function RuleLink(
|
|||
) {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const engine = useContext(EngineContext)
|
||||
|
||||
return (
|
||||
<EngineRuleLink
|
||||
{...props}
|
||||
|
|
|
@ -20,6 +20,7 @@ export function ShareSimulationPopup({ url }: { url: string }) {
|
|||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => setLinkCopied(false), 5000)
|
||||
|
||||
return () => {
|
||||
clearTimeout(handler)
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ export function useUrl() {
|
|||
: import.meta.env.VITE_EN_BASE_URL
|
||||
|
||||
searchParams.set('utm_source', 'sharing')
|
||||
|
||||
return siteUrl + path + '?' + searchParams.toString()
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ const QuestionsContainer = styled.div`
|
|||
`0 0 ${theme.box.borderRadius} ${theme.box.borderRadius}`};
|
||||
background: ${({ theme }) => {
|
||||
const colorPalette = theme.colors.bases.primary
|
||||
|
||||
return `linear-gradient(60deg, ${colorPalette[200]} 0%, ${colorPalette[100]} 100%);`
|
||||
}};
|
||||
`
|
||||
|
|
|
@ -77,6 +77,7 @@ export function SimulationGoal({
|
|||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Appear unless={!appear || initialRender}>
|
||||
<StyledGoal>
|
||||
|
|
|
@ -68,6 +68,7 @@ const StyledSimulationGoals = styled.div<
|
|||
const colorPalette = publique
|
||||
? theme.colors.publics[publique]
|
||||
: theme.colors.bases.primary
|
||||
|
||||
return css`linear-gradient(60deg, ${colorPalette[800]} 0%, ${colorPalette[600]} 100%);`
|
||||
}};
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export default function Simulation({
|
|||
const existingCompany = !!useSelector(companySituationSelector)[
|
||||
'entreprise . SIREN'
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
{!firstStepCompleted && <TrackPage name="accueil" />}
|
||||
|
|
|
@ -65,6 +65,7 @@ type Precision = 1 | 0.1 | 0.01
|
|||
function integerAndDecimalParts(value: number) {
|
||||
const integer = Math.floor(value)
|
||||
const decimal = value - integer
|
||||
|
||||
return { integer, decimal }
|
||||
}
|
||||
|
||||
|
@ -104,6 +105,7 @@ export function roundedPercentages(
|
|||
precision: Precision
|
||||
) {
|
||||
const logScale = Math.log10(precision)
|
||||
|
||||
return simpleRoundedPer(values, logScale).map(
|
||||
(int) => int / Math.pow(10, -logScale)
|
||||
)
|
||||
|
@ -128,6 +130,7 @@ export function StackedBarChart({
|
|||
})
|
||||
|
||||
const styles = useSpring({ opacity: displayChart ? 1 : 0 })
|
||||
|
||||
return !useContext(DisableAnimationContext) ? (
|
||||
<animated.div ref={intersectionRef} style={styles}>
|
||||
<InnerStackedBarChart data={data} precision={precision} />
|
||||
|
@ -147,6 +150,7 @@ function InnerStackedBarChart({ data, precision }: InnerStackedBarChartProps) {
|
|||
...data,
|
||||
percentage: percentages[index],
|
||||
}))
|
||||
|
||||
return (
|
||||
<>
|
||||
<BarStack className="print-background-force">
|
||||
|
@ -190,6 +194,7 @@ export default function StackedRulesChart({
|
|||
}: StackedRulesChartProps) {
|
||||
const engine = useEngine()
|
||||
const targetUnit = useSelector(targetUnitSelector)
|
||||
|
||||
return (
|
||||
<StackedBarChart
|
||||
precision={precision}
|
||||
|
|
|
@ -74,6 +74,7 @@ function highlightLabelToJSX(highlightLabel: string) {
|
|||
)
|
||||
}
|
||||
result.push(highlightLabel.slice(parsedLength))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@ function AnswerElement(
|
|||
setEditing(false)
|
||||
}
|
||||
window.addEventListener('click', onClickOutside)
|
||||
|
||||
return () => window.removeEventListener('click', onClickOutside)
|
||||
}, [])
|
||||
const situation = useSelector(situationSelector)
|
||||
|
|
|
@ -53,6 +53,7 @@ export function MultipleAnswerInput({
|
|||
// seront stockées ainsi dans le state :
|
||||
// [parent object path]: dotted fieldName relative to parent
|
||||
const { handleChange, defaultValue, currentSelection } = useSelection(props)
|
||||
|
||||
return (
|
||||
<RadioGroup onChange={handleChange} value={currentSelection ?? undefined}>
|
||||
<RadioChoice
|
||||
|
|
|
@ -14,8 +14,11 @@ export default function DateInput({
|
|||
value,
|
||||
}: InputProps) {
|
||||
const dateValue = useMemo(() => {
|
||||
if (!value || typeof value !== 'string') return undefined
|
||||
if (!value || typeof value !== 'string') {
|
||||
return undefined
|
||||
}
|
||||
const [day, month, year] = value.split('/')
|
||||
|
||||
return `${year}-${month}-${day}`
|
||||
}, [value])
|
||||
// const [currentValue, setCurrentValue] = useState(dateValue)
|
||||
|
@ -38,6 +41,7 @@ export default function DateInput({
|
|||
},
|
||||
[onChange]
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="step input">
|
||||
<div>
|
||||
|
|
|
@ -14,10 +14,14 @@ export function ExplicableRule({
|
|||
const engine = useContext(EngineContext)
|
||||
|
||||
// Rien à expliquer ici, ce n'est pas une règle
|
||||
if (dottedName == null) return null
|
||||
if (dottedName == null) {
|
||||
return null
|
||||
}
|
||||
const rule = engine.getRule(dottedName)
|
||||
|
||||
if (rule.rawNode.description == null) return null
|
||||
if (rule.rawNode.description == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
//TODO montrer les variables de type 'une possibilité'
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ export default function InputSuggestions({
|
|||
if (!suggestions || !Object.keys(suggestions).length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledInputSuggestion className={className}>
|
||||
{toPairs(suggestions).map(([text, value]: [string, ASTNode]) => {
|
||||
|
@ -32,8 +33,11 @@ export default function InputSuggestions({
|
|||
key={text}
|
||||
onPress={() => {
|
||||
onFirstClick(value)
|
||||
if (suggestion !== value) setSuggestion(value)
|
||||
else onSecondClick && onSecondClick(value)
|
||||
if (suggestion !== value) {
|
||||
setSuggestion(value)
|
||||
} else {
|
||||
onSecondClick && onSecondClick(value)
|
||||
}
|
||||
}}
|
||||
title={t('cliquez pour insérer cette suggestion')}
|
||||
>
|
||||
|
|
|
@ -52,6 +52,7 @@ export default function NumberInput({
|
|||
...formatOptions,
|
||||
}
|
||||
const debouncedOnChange = useCallback(debounce(1000, onChange), [])
|
||||
|
||||
return (
|
||||
<StyledNumberInput>
|
||||
<NumberField
|
||||
|
@ -118,6 +119,7 @@ function getSerializedUnit(
|
|||
) ?? ''
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
Intl.NumberFormat(locale, {
|
||||
unit: formatUnit,
|
||||
|
@ -161,6 +163,7 @@ function getFormatUnit(unit: Unit): Intl.NumberFormatOptions['unit'] | null {
|
|||
if (denominator) {
|
||||
formatUnit += `-per-${UNIT_MAP[denominator as keyof typeof UNIT_MAP]}`
|
||||
}
|
||||
|
||||
return formatUnit
|
||||
}
|
||||
|
||||
|
|
|
@ -101,20 +101,24 @@ export default function RuleInput({
|
|||
/>
|
||||
)
|
||||
}
|
||||
if (rule.rawNode.API && rule.rawNode.API === 'commune')
|
||||
if (rule.rawNode.API && rule.rawNode.API === 'commune') {
|
||||
return <SelectCommune {...commonProps} />
|
||||
if (rule.rawNode.API && rule.rawNode.API.startsWith('pays détachement'))
|
||||
}
|
||||
if (rule.rawNode.API && rule.rawNode.API.startsWith('pays détachement')) {
|
||||
return (
|
||||
<SelectPaysDétachement
|
||||
{...commonProps}
|
||||
plusFrance={rule.rawNode.API.endsWith('plus France')}
|
||||
/>
|
||||
)
|
||||
if (rule.rawNode.API)
|
||||
}
|
||||
if (rule.rawNode.API) {
|
||||
throw new Error("Les seules API implémentées sont 'commune'")
|
||||
}
|
||||
|
||||
if (rule.dottedName == 'contrat salarié . ATMP . taux collectif ATMP')
|
||||
if (rule.dottedName == 'contrat salarié . ATMP . taux collectif ATMP') {
|
||||
return <SelectAtmp {...commonProps} />
|
||||
}
|
||||
|
||||
if (rule.rawNode.type === 'date') {
|
||||
return <DateInput {...commonProps} />
|
||||
|
@ -162,11 +166,14 @@ export const buildVariantTree = <Name extends string>(
|
|||
path: Name
|
||||
): Choice => {
|
||||
const node = engine.getRule(path)
|
||||
if (!node) throw new Error(`La règle ${path} est introuvable`)
|
||||
if (!node) {
|
||||
throw new Error(`La règle ${path} est introuvable`)
|
||||
}
|
||||
const variant = getVariant(node)
|
||||
const canGiveUp =
|
||||
variant &&
|
||||
(!variant['choix obligatoire'] || variant['choix obligatoire'] === 'non')
|
||||
|
||||
return Object.assign(
|
||||
node,
|
||||
variant
|
||||
|
|
|
@ -13,6 +13,7 @@ export default function TextInput({
|
|||
autoFocus,
|
||||
}: InputProps & { value: Evaluation<string> }) {
|
||||
const debouncedOnChange = useCallback(debounce(1000, onChange), [])
|
||||
|
||||
return (
|
||||
<TextField
|
||||
autoFocus={autoFocus}
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
function formatCommune(value: SearchCommune) {
|
||||
return value && `${value.nom} (${value.codePostal})`
|
||||
}
|
||||
|
||||
export default function Select({
|
||||
onChange,
|
||||
value,
|
||||
|
@ -86,6 +87,7 @@ export default function Select({
|
|||
setName(value)
|
||||
if (value.length < 2) {
|
||||
setSearchResults(null)
|
||||
|
||||
return
|
||||
}
|
||||
setLoadingState(true)
|
||||
|
@ -143,6 +145,7 @@ export default function Select({
|
|||
<OptionList role="listbox" aria-expanded="true" id="liste-commune">
|
||||
{searchResults.map((result, i) => {
|
||||
const nom = formatCommune(result)
|
||||
|
||||
return (
|
||||
<Option
|
||||
as="li"
|
||||
|
|
|
@ -65,6 +65,7 @@ export default function SelectPaysDétachement({
|
|||
const valueId = value
|
||||
? statesWithID.find((s) => s.name === value)?.id
|
||||
: undefined
|
||||
|
||||
return (
|
||||
<Select
|
||||
name="country"
|
||||
|
|
|
@ -51,6 +51,7 @@ const STATES = [
|
|||
'Uruguay',
|
||||
'Autre',
|
||||
]
|
||||
|
||||
export default function SelectPaysDétachement({
|
||||
value,
|
||||
onChange,
|
||||
|
@ -66,6 +67,7 @@ export default function SelectPaysDétachement({
|
|||
const valueId = value
|
||||
? statesWithID.find((s) => s.name === value)?.id
|
||||
: undefined
|
||||
|
||||
return (
|
||||
<Select
|
||||
name="country"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import ContactImage from '@/images/contact.png'
|
||||
|
||||
const Contact = () => (
|
||||
<div className="centeredMessage">
|
||||
<p>
|
||||
|
|
|
@ -14,6 +14,7 @@ export default function Header() {
|
|||
const {
|
||||
i18n: { language },
|
||||
} = useTranslation()
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<StyledHeader>
|
||||
|
|
|
@ -37,6 +37,7 @@ export default function NewsBanner() {
|
|||
if (!showBanner) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Banner className="print-hidden" onClick={() => setShowBanner(false)}>
|
||||
<InnerBanner>
|
||||
|
|
|
@ -91,6 +91,7 @@ const InfiniteHits = styled.div`
|
|||
|
||||
const Hits = connectInfiniteHits(({ hits, hasMore, refineNext }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<InfiniteHits>
|
||||
<HitList>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { connectSearchBox } from 'react-instantsearch-dom'
|
|||
export const SearchBox = connectSearchBox(
|
||||
({ currentRefinement, isSearchStalled, refine }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<form noValidate action="" role="search">
|
||||
<SearchField
|
||||
|
|
|
@ -7,6 +7,7 @@ import { RulesInfiniteHits } from './RulesInfiniteHits'
|
|||
import { SearchBox } from './SearchBox'
|
||||
import { SearchRoot } from './SearchRoot'
|
||||
import { SimulatorHits } from './SimulatorHits'
|
||||
|
||||
const ALGOLIA_APP_ID = import.meta.env.VITE_ALGOLIA_APP_ID || ''
|
||||
const ALGOLIA_SEARCH_KEY = import.meta.env.VITE_ALGOLIA_SEARCH_KEY || ''
|
||||
const ALGOLIA_INDEX_PREFIX = import.meta.env.VITE_ALGOLIA_INDEX_PREFIX || ''
|
||||
|
|
|
@ -54,6 +54,7 @@ export const SimulatorHits = connectHits<
|
|||
AlgoliaSimulatorHit
|
||||
>(({ hits }: SimulatorHitsProps) => {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
|
||||
return (
|
||||
<>
|
||||
{hits.length > 0 && (
|
||||
|
|
|
@ -13,6 +13,7 @@ export default function CotisationsForfaitaires() {
|
|||
const rule = useEngine().getRule(
|
||||
'dirigeant . indépendant . cotisations et contributions . début activité'
|
||||
)
|
||||
|
||||
return (
|
||||
<FromBottom>
|
||||
<Message>
|
||||
|
|
|
@ -10,6 +10,7 @@ export default function CotisationsRégularisation() {
|
|||
const rule = useEngine().getRule(
|
||||
'dirigeant . indépendant . cotisations et contributions . régularisation'
|
||||
)
|
||||
|
||||
return (
|
||||
<FromBottom>
|
||||
<div>
|
||||
|
|
|
@ -170,6 +170,7 @@ function DroitsRetraite() {
|
|||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Trans i18nKey="pages.simulateurs.indépendant.retraite-droits-acquis">
|
||||
<H3 as="h2">Retraite : droits acquis sur l'année</H3>
|
||||
|
|
|
@ -23,6 +23,7 @@ import { Message } from '@/design-system'
|
|||
|
||||
export default function InstitutionsPartenaires() {
|
||||
const unit = useSelector(targetUnitSelector)
|
||||
|
||||
return (
|
||||
<section>
|
||||
<FromBottom>
|
||||
|
@ -97,6 +98,7 @@ export function CotisationsUrssaf({
|
|||
extraNotice,
|
||||
}: CotisationsUrssafProps) {
|
||||
const unit = useSelector(targetUnitSelector)
|
||||
|
||||
return (
|
||||
<InstitutionLine>
|
||||
<InstitutionLogo
|
||||
|
@ -121,6 +123,7 @@ export function CotisationsUrssaf({
|
|||
|
||||
export function ImpôtsDGFIP() {
|
||||
const unit = useSelector(targetUnitSelector)
|
||||
|
||||
return (
|
||||
<Condition expression="impôt . montant > 0">
|
||||
<InstitutionLine>
|
||||
|
@ -169,6 +172,7 @@ function CaisseRetraite() {
|
|||
const dottedName =
|
||||
`dirigeant . indépendant . PL . ${caisse}` as DottedName
|
||||
const { description, références } = engine.getRule(dottedName).rawNode
|
||||
|
||||
return (
|
||||
<Condition expression={dottedName} key={caisse}>
|
||||
<InstitutionLine>
|
||||
|
@ -205,6 +209,7 @@ export function InstitutionsPartenairesArtisteAuteur() {
|
|||
const { description: descriptionIRCEC } = useEngine().getRule(
|
||||
'artiste-auteur . cotisations . IRCEC'
|
||||
).rawNode
|
||||
|
||||
return (
|
||||
<section>
|
||||
<H3>Vos cotisations</H3>
|
||||
|
|
|
@ -11,6 +11,7 @@ type AnimatedTargetValueProps = {
|
|||
|
||||
const formatDifference = (difference: number, language: string) => {
|
||||
const prefix = difference > 0 ? '+' : ''
|
||||
|
||||
return prefix + formatValue(difference, { displayedUnit: '€', language })
|
||||
}
|
||||
|
||||
|
@ -45,6 +46,7 @@ export default function AnimatedTargetValue({
|
|||
if (!difference || Math.abs(difference) < 1) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="print-hidden"
|
||||
|
|
|
@ -96,6 +96,7 @@ const StyledLink = styled(Link)`
|
|||
margin-left: ${({ theme }) => theme.spacings.xs};
|
||||
white-space: nowrap;
|
||||
`
|
||||
|
||||
export type ChecklistProps = {
|
||||
children: React.ReactNode
|
||||
onItemCheck?: (name: string, isChecked: boolean) => void
|
||||
|
@ -114,6 +115,7 @@ export function Checklist({
|
|||
if (!React.isValidElement(child)) {
|
||||
throw new Error('Invalid child passed to Checklist')
|
||||
}
|
||||
|
||||
return React.cloneElement(child, {
|
||||
onChange: (isSelected: boolean) =>
|
||||
onItemCheck?.(child.props.name, isSelected),
|
||||
|
|
|
@ -36,6 +36,7 @@ export function FromBottom({
|
|||
return <>{children}</>
|
||||
}
|
||||
const childrenArray = React.Children.toArray(children)
|
||||
|
||||
return (
|
||||
<>
|
||||
{trail.map((style, i) => (
|
||||
|
@ -70,6 +71,7 @@ export function FromTop({
|
|||
return <>{children}</>
|
||||
}
|
||||
const childrenArray = React.Children.toArray(children)
|
||||
|
||||
return (
|
||||
<>
|
||||
{trail.map((style, i) => (
|
||||
|
@ -102,6 +104,7 @@ export const FadeIn = ({
|
|||
if (useContext(DisableAnimationContext)) {
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
return <animated.div style={style}>{children}</animated.div>
|
||||
}
|
||||
|
||||
|
|
|
@ -11,5 +11,6 @@ export default function BrowserOnly({
|
|||
if (import.meta.env.SSR) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <Appear>{children}</Appear>
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ const useIsPrintContext = () => {
|
|||
// `addEventListener` isn't supported by old versions of Safari and throws a
|
||||
// fatal error. See #1790 and https://stackoverflow.com/a/56466334
|
||||
matchMediaPrint.addEventListener?.('change', matchListener)
|
||||
|
||||
return () => {
|
||||
matchMediaPrint.removeEventListener?.('change', matchListener)
|
||||
}
|
||||
|
@ -27,6 +28,7 @@ const useIsPrintContext = () => {
|
|||
setPrintContext(true)
|
||||
})
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.onbeforeprint = null
|
||||
}
|
||||
|
@ -41,6 +43,7 @@ export function DisableAnimationOnPrintProvider({
|
|||
children: React.ReactNode
|
||||
}) {
|
||||
const isPrintContext = useIsPrintContext()
|
||||
|
||||
return (
|
||||
<DisableAnimationContext.Provider value={isPrintContext}>
|
||||
{children}
|
||||
|
|
|
@ -3,9 +3,11 @@ import { useEffect } from 'react'
|
|||
export default function DisableScroll() {
|
||||
useEffect(() => {
|
||||
document.documentElement.style.overflow = 'hidden'
|
||||
|
||||
return () => {
|
||||
document.documentElement.style.overflow = ''
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import emojiFn from 'react-easy-emoji'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type PropType = {
|
||||
emoji: string | undefined
|
||||
alt?: string
|
||||
|
@ -20,6 +21,7 @@ export default function Emoji({ emoji, alt, title }: PropType) {
|
|||
if (!emoji) {
|
||||
return null
|
||||
}
|
||||
|
||||
return emojiFn(
|
||||
emoji,
|
||||
import.meta.env.MODE === 'production'
|
||||
|
|
|
@ -11,9 +11,11 @@ const engineOptions = {
|
|||
const key = unitsTranslations
|
||||
.find(([, trans]) => trans === unit)?.[0]
|
||||
.replace(/_plural$/, '')
|
||||
|
||||
return key || unit
|
||||
},
|
||||
}
|
||||
|
||||
export function engineFactory(rules: Rules, options = {}) {
|
||||
return new Engine(rules, { ...engineOptions, ...options })
|
||||
}
|
||||
|
@ -31,12 +33,14 @@ type SituationProviderProps = {
|
|||
Record<DottedName, string | number | Record<string, unknown>>
|
||||
>
|
||||
}
|
||||
|
||||
export function SituationProvider({
|
||||
children,
|
||||
situation,
|
||||
}: SituationProviderProps) {
|
||||
const engine = useContext(EngineContext)
|
||||
engine.setSituation(situation)
|
||||
|
||||
return (
|
||||
<EngineContext.Provider value={engine}>{children}</EngineContext.Provider>
|
||||
)
|
||||
|
|
|
@ -30,6 +30,7 @@ export default function Meta({
|
|||
ogTitle: ogTitle ? t(`${page}.ogTitle`, ogTitle) || ogTitle : title,
|
||||
ogImage: ogImage ? t(`${page}.ogImage`, ogImage) || ogImage : null,
|
||||
}
|
||||
|
||||
return (
|
||||
<Helmet htmlAttributes={{ lang: i18n.language }}>
|
||||
<title>{meta.title}</title>
|
||||
|
|
|
@ -31,6 +31,7 @@ export function ScrollToTop({
|
|||
window.scroll(0, 0)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return <div ref={ref} />
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ export function IsEmbeddedProvider({
|
|||
isEmbeded?: boolean
|
||||
}) {
|
||||
const state = useState(isEmbeded)
|
||||
|
||||
return (
|
||||
<IsEmbeddedContext.Provider value={state}>
|
||||
{children}
|
||||
|
|
|
@ -18,5 +18,6 @@ export function useDebounce<T>(value: T, delay: number) {
|
|||
},
|
||||
[value, delay] // Only re-call effect if value or delay changes
|
||||
)
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ export function HeadingWithAnchorLink({
|
|||
) : (
|
||||
children
|
||||
)
|
||||
|
||||
return (
|
||||
<Heading
|
||||
id={headingId}
|
||||
|
|
|
@ -13,6 +13,7 @@ export const getInitialState = <T extends Storage>(key: string): T | null => {
|
|||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(e)
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
@ -36,5 +37,6 @@ export const usePersistingState = <T extends Storage>(
|
|||
const initialState = persistedState != null ? persistedState : defaultState
|
||||
const [state, setState] = useState<T>(initialState)
|
||||
useSafeLocaleStorage(key, state)
|
||||
|
||||
return [state, setState] as const
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ export default function ({
|
|||
useEffect(() => {
|
||||
if (typeof IntersectionObserver === 'undefined') {
|
||||
setWasOnScreen(true) // No effect for old browsers
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -38,6 +39,7 @@ export default function ({
|
|||
if (node) {
|
||||
observer.observe(node)
|
||||
}
|
||||
|
||||
return () => {
|
||||
node && unobserve && observer.unobserve(node)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ export function WatchInitialRender(props: { children: ReactNode }) {
|
|||
useEffect(() => {
|
||||
setInitialRender(false)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<InitialRenderContext.Provider value={initialRender}>
|
||||
{props.children}
|
||||
|
|
|
@ -35,6 +35,7 @@ import {
|
|||
import { EngineContext } from './EngineContext'
|
||||
|
||||
type MissingVariables = Partial<Record<DottedName, number>>
|
||||
|
||||
export function getNextSteps(
|
||||
missingVariables: Array<MissingVariables>
|
||||
): Array<DottedName> {
|
||||
|
@ -65,6 +66,7 @@ export function getNextSteps(
|
|||
),
|
||||
pairs = toPairs<number>(missingByCompound),
|
||||
sortedPairs = sortWith([descend(byCount), descend(byScore) as any], pairs)
|
||||
|
||||
return map(head, sortedPairs) as any
|
||||
}
|
||||
|
||||
|
@ -108,12 +110,14 @@ export function getNextQuestions(
|
|||
.replace(/'/g, '')
|
||||
.trim() as DottedName)
|
||||
: lastStep
|
||||
|
||||
return sortBy((question) => {
|
||||
const indexList =
|
||||
whitelist.findIndex((name) => question.startsWith(name)) + 1
|
||||
const indexNotPriority =
|
||||
notPriority.findIndex((name) => question.startsWith(name)) + 1
|
||||
const differenceCoeff = questionDifference(question, lastStepWithAnswer)
|
||||
|
||||
return indexList + indexNotPriority + differenceCoeff
|
||||
}, nextSteps)
|
||||
}
|
||||
|
@ -138,6 +142,7 @@ export const useNextQuestions = function (): Array<DottedName> {
|
|||
if (currentQuestion && currentQuestion !== next[0]) {
|
||||
next = [currentQuestion, ...next.filter((val) => val !== currentQuestion)]
|
||||
}
|
||||
|
||||
return next.filter(
|
||||
(question) => engine.evaluate(question).nodeValue !== null
|
||||
)
|
||||
|
|
|
@ -57,6 +57,7 @@ export function createSearchParams(
|
|||
? init
|
||||
: Object.keys(init).reduce((memo, key) => {
|
||||
const value = init[key]
|
||||
|
||||
return memo.concat(
|
||||
Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]]
|
||||
)
|
||||
|
|
|
@ -66,6 +66,7 @@ export default function useSearchParamsSimulationSharing() {
|
|||
|
||||
setUrlSituationIsExtracted(true)
|
||||
}
|
||||
|
||||
return
|
||||
}, [
|
||||
currentUrl,
|
||||
|
@ -92,6 +93,7 @@ export const useParamsFromSituation = (situation: Situation) => {
|
|||
() => getRulesParamNames(engine.getParsedRules()),
|
||||
[engine]
|
||||
)
|
||||
|
||||
return getSearchParamsFromSituation(engine, situation, dottedNameParamName)
|
||||
}
|
||||
|
||||
|
@ -100,6 +102,7 @@ const objectifsOfConfig = (config: Partial<SimulationConfig>) =>
|
|||
if (typeof objectifOrSection === 'string') {
|
||||
return [objectifOrSection]
|
||||
}
|
||||
|
||||
return objectifOrSection.objectifs
|
||||
})
|
||||
|
||||
|
@ -140,11 +143,13 @@ export function getSearchParamsFromSituation(
|
|||
([dottedName, value]) => {
|
||||
const paramName = dottedNameParamNameMapping[dottedName]
|
||||
const serializedValue = serializeEvaluation(engine.evaluate(value))
|
||||
if (typeof serializedValue !== 'undefined')
|
||||
if (typeof serializedValue !== 'undefined') {
|
||||
searchParams.set(paramName, serializedValue)
|
||||
}
|
||||
}
|
||||
)
|
||||
searchParams.sort()
|
||||
|
||||
return searchParams
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ const useIFrameOffset = () => {
|
|||
}
|
||||
void getIframeOffset().then(setOffset)
|
||||
}, [])
|
||||
|
||||
return offsetTop
|
||||
}
|
||||
|
||||
|
|
|
@ -58,9 +58,15 @@ export const StyledButton = styled.button<StyledButtonProps>`
|
|||
font-weight: 500;
|
||||
|
||||
padding: ${({ size }) => {
|
||||
if (size === 'XL') return '1.25rem 2rem'
|
||||
if (size === 'MD') return '0.875rem 2rem'
|
||||
if (size === 'XS') return '0.5rem 2rem'
|
||||
if (size === 'XL') {
|
||||
return '1.25rem 2rem'
|
||||
}
|
||||
if (size === 'MD') {
|
||||
return '0.875rem 2rem'
|
||||
}
|
||||
if (size === 'XS') {
|
||||
return '0.5rem 2rem'
|
||||
}
|
||||
}};
|
||||
@media (max-width: ${({ theme }) => theme.breakpointsWidth.sm}) {
|
||||
width: 100%;
|
||||
|
|
|
@ -81,6 +81,7 @@ export function getTitleProps(children: React.ReactNode, as: keyof ReactHTML) {
|
|||
as = children.type as keyof ReactHTML
|
||||
children = children.props.children ?? null
|
||||
}
|
||||
|
||||
return { as, children }
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ export default function Checkbox(
|
|||
const state = useToggleState(props)
|
||||
const ref = useRef<HTMLInputElement | null>(null)
|
||||
const { inputProps } = useCheckbox(props, state, ref)
|
||||
|
||||
return (
|
||||
<CheckboxContainer>
|
||||
<input type="checkbox" className="sr-only" ref={ref} {...inputProps} />
|
||||
|
|
|
@ -31,6 +31,7 @@ type NumberFieldProps = Omit<AriaNumberFieldProps, 'placeholder'> & {
|
|||
placeholder?: number
|
||||
onChange?: (n?: number) => void
|
||||
}
|
||||
|
||||
export default function NumberField(props: NumberFieldProps) {
|
||||
const { locale } = useLocale()
|
||||
const step = !props.step
|
||||
|
@ -82,6 +83,7 @@ export default function NumberField(props: NumberFieldProps) {
|
|||
const length = ref.current.value.length * 2
|
||||
ref.current.setSelectionRange(0, length * 2)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<StyledNumberFieldContainer>
|
||||
<StyledInputContainer
|
||||
|
@ -289,6 +291,7 @@ function useSimpleNumberFieldState(
|
|||
if (!inputValue || defaultInputValue === inputValue) {
|
||||
updateInputValue(undefined)
|
||||
updateNumberValue(undefined)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -302,6 +305,7 @@ function useSimpleNumberFieldState(
|
|||
const parsedValue = numberParser.parse(inputValue)
|
||||
if (isNaN(parsedValue)) {
|
||||
updateInputValue(numberValue)
|
||||
|
||||
return
|
||||
}
|
||||
updateNumberValue(parsedValue)
|
||||
|
@ -313,6 +317,7 @@ function useSimpleNumberFieldState(
|
|||
inputValue.match(/^[^\d]*0([0]+|[\d\s,.]+)[^\d]*$/)
|
||||
) {
|
||||
setInputValue(inputValue)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ export function Radio(props: AriaRadioProps) {
|
|||
}
|
||||
const ref = useRef(null)
|
||||
const { inputProps } = useRadio(props, state, ref)
|
||||
|
||||
return (
|
||||
<label>
|
||||
<InputRadio {...inputProps} className="sr-only" ref={ref} />
|
||||
|
|
|
@ -130,6 +130,7 @@ function Option({ item, state }: OptionProps) {
|
|||
|
||||
export function Label({ children }: { children: ReactNode }) {
|
||||
const { labelProps } = useContext(OptionContext)
|
||||
|
||||
return <div {...labelProps}>{children}</div>
|
||||
}
|
||||
|
||||
|
@ -140,5 +141,6 @@ const StyledDescription = styled.div`
|
|||
|
||||
export function Description({ children }: { children: ReactNode }) {
|
||||
const { descriptionProps } = useContext(OptionContext)
|
||||
|
||||
return <StyledDescription {...descriptionProps}>{children}</StyledDescription>
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ const Value = styled.span`
|
|||
const StyledIcon = styled(CarretDown)`
|
||||
margin: 0 4px;
|
||||
`
|
||||
|
||||
export const Wrapper = styled.div<{
|
||||
hasError: boolean
|
||||
hasLabel: boolean
|
||||
|
@ -196,6 +197,7 @@ export function Select<T extends Record<string, unknown>>(
|
|||
const { buttonProps } = useButton(triggerProps, ref)
|
||||
|
||||
const { focusProps, isFocusVisible } = useFocusRing()
|
||||
|
||||
return (
|
||||
<Wrapper isOpen={state.isOpen} hasError={false} hasLabel={false}>
|
||||
<HiddenSelect
|
||||
|
|
|
@ -50,6 +50,7 @@ type ContainerProps = {
|
|||
darkMode?: boolean
|
||||
backgroundColor?: (theme: DefaultTheme) => string
|
||||
}
|
||||
|
||||
export default function Container({
|
||||
backgroundColor,
|
||||
darkMode = false,
|
||||
|
|
|
@ -14,6 +14,7 @@ type MessageProps = {
|
|||
type?: MessageType
|
||||
light?: boolean
|
||||
}
|
||||
|
||||
export function Message({
|
||||
type = 'primary',
|
||||
icon = false,
|
||||
|
@ -24,6 +25,7 @@ export function Message({
|
|||
if (typeof children !== 'object') {
|
||||
children = <Body>{children}</Body>
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={(theme) => ({ ...theme, darkMode: false })}>
|
||||
<StyledMessage type={type} border={border} light={light}>
|
||||
|
@ -78,6 +80,7 @@ const StyledMessage = styled.div<
|
|||
type === 'secondary' || type === 'primary'
|
||||
? theme.colors.bases[type]
|
||||
: theme.colors.extended[type]
|
||||
|
||||
return css`
|
||||
padding: ${theme.spacings.xs} ${theme.spacings.lg};
|
||||
background-color: ${light ? 'rgba(255,255,255,0.75)' : colorSpace[100]};
|
||||
|
|
|
@ -9,6 +9,7 @@ const baseHeading = css`
|
|||
? theme.colors.extended.grey[100]
|
||||
: theme.colors.bases.primary[700]};
|
||||
`
|
||||
|
||||
export const HeadingUnderline = css`
|
||||
::after {
|
||||
height: 1.25rem;
|
||||
|
@ -86,10 +87,21 @@ export const H6 = styled.h6`
|
|||
`
|
||||
|
||||
export const fromLevel = (level: number) => {
|
||||
if (level === 1) return H1
|
||||
if (level === 2) return H2
|
||||
if (level === 3) return H3
|
||||
if (level === 4) return H4
|
||||
if (level === 5) return H5
|
||||
if (level === 1) {
|
||||
return H1
|
||||
}
|
||||
if (level === 2) {
|
||||
return H2
|
||||
}
|
||||
if (level === 3) {
|
||||
return H3
|
||||
}
|
||||
if (level === 4) {
|
||||
return H4
|
||||
}
|
||||
if (level === 5) {
|
||||
return H5
|
||||
}
|
||||
|
||||
return H6
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ export const Link = React.forwardRef<
|
|||
GenericButtonOrLinkProps & { children: React.ReactNode }
|
||||
>(function Link(ariaButtonProps, forwardedRef) {
|
||||
const buttonOrLinkProps = useButtonOrLink(ariaButtonProps, forwardedRef)
|
||||
|
||||
return <StyledLink {...buttonOrLinkProps} />
|
||||
})
|
||||
|
||||
|
@ -137,6 +138,7 @@ export function useButtonOrLink(
|
|||
as: elementType,
|
||||
ref,
|
||||
}
|
||||
|
||||
return buttonOrLinkProps
|
||||
}
|
||||
|
||||
|
|
|
@ -28,5 +28,6 @@ export function hexToHSL(hex: string): [number, number, number] {
|
|||
}
|
||||
h /= 6
|
||||
}
|
||||
|
||||
return [h * 360, s * 100, l * 100].map(Math.round) as [number, number, number]
|
||||
}
|
||||
|
|
|
@ -18,5 +18,6 @@ export function useDebounce<T>(value: T, delay: number) {
|
|||
},
|
||||
[value, delay] // Only re-call effect if value or delay changes
|
||||
)
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ const translateProp =
|
|||
}
|
||||
let propTrans = translation[prop + '.' + lang]
|
||||
propTrans = propTrans?.replace(/^\[automatic\] /, '')
|
||||
|
||||
return propTrans ? assoc(prop, propTrans, rule) : rule
|
||||
}
|
||||
|
||||
|
@ -61,6 +62,7 @@ function translateRule<Names extends string>(
|
|||
if (!ruleTrans) {
|
||||
return rule
|
||||
}
|
||||
|
||||
return attributesToTranslate.reduce(
|
||||
translateProp(lang, ruleTrans),
|
||||
rule ?? {}
|
||||
|
|
|
@ -42,6 +42,7 @@ export default function Budget() {
|
|||
)
|
||||
|
||||
const { language } = useTranslation().i18n
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackPage chapter1="informations" name="budget" />
|
||||
|
@ -96,6 +97,7 @@ export default function Budget() {
|
|||
<td>{label}</td>
|
||||
{quarters.map((q) => {
|
||||
const value = budget[selectedYear]?.[q]?.[label]
|
||||
|
||||
return (
|
||||
<td key={q}>
|
||||
{value
|
||||
|
@ -130,6 +132,7 @@ export default function Budget() {
|
|||
const value = sum(
|
||||
Object.values(budget[selectedYear]?.[q] ?? {})
|
||||
)
|
||||
|
||||
return (
|
||||
<td key={q}>
|
||||
{value
|
||||
|
@ -161,6 +164,7 @@ export default function Budget() {
|
|||
const value = Math.round(
|
||||
sum(Object.values(budget[selectedYear]?.[q] ?? {})) * 1.2
|
||||
)
|
||||
|
||||
return (
|
||||
<td key={q}>
|
||||
{value
|
||||
|
|
|
@ -591,7 +591,9 @@ const StatutsExample = ({ statut }: StatutsExampleProps) => {
|
|||
EURL: 'https://bpifrance-creation.fr/file/109070/download?token=Ul-rT6Z0',
|
||||
}
|
||||
|
||||
if (!(statut in links)) return null
|
||||
if (!(statut in links)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Link href={links[statut as keyof typeof links]}>
|
||||
|
@ -605,6 +607,7 @@ const StatutsExample = ({ statut }: StatutsExampleProps) => {
|
|||
|
||||
export const FAQAutoEntrepreneurArticle = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Article
|
||||
title={
|
||||
|
|
|
@ -8,6 +8,7 @@ import { TrackPage } from '../../../ATInternetTracking'
|
|||
|
||||
export default function Autoentrepreneur() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackPage name="auto-entrepreneur_ou_independant" />
|
||||
|
|
|
@ -7,6 +7,7 @@ import { TrackPage } from '../../../ATInternetTracking'
|
|||
|
||||
export default function DefineDirectorStatus() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackPage name="independant_ou_assimile-salarie" />
|
||||
|
|
|
@ -14,6 +14,7 @@ import { TrackPage } from '../../../ATInternetTracking'
|
|||
export default function MinorityDirector() {
|
||||
const { t } = useTranslation()
|
||||
const dispatch = useDispatchAndGoToNextQuestion()
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackPage name="majoritaire_ou_minoritaire" />
|
||||
|
|
|
@ -13,6 +13,7 @@ import { TrackPage } from '../../../ATInternetTracking'
|
|||
export default function NumberOfAssociates() {
|
||||
const dispatch = useDispatchAndGoToNextQuestion()
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackPage name="seul_ou_plusieurs" />
|
||||
|
|
|
@ -21,6 +21,7 @@ type StatutButtonProps = {
|
|||
const StatutButton = ({ statut }: StatutButtonProps) => {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Button to={sitePaths.créer[statut]} light size="XS">
|
||||
<>
|
||||
|
@ -90,6 +91,7 @@ const StatutTitle = ({ statut, language }: StatutTitleProps) =>
|
|||
export default function SetMainStatus() {
|
||||
const { t, i18n } = useTranslation()
|
||||
const possibleStatus = useSelector(possibleStatusSelector)
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackPage chapter2="statut" name="liste" />
|
||||
|
|
|
@ -72,6 +72,7 @@ export default function PreviousAnswers() {
|
|||
if (Object.values(legalStatus).length < 1) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<PreviousAnswersList>
|
||||
{Object.entries(legalStatus).map(
|
||||
|
|
|
@ -14,6 +14,7 @@ import { TrackPage } from '../../../ATInternetTracking'
|
|||
export default function SoleProprietorship() {
|
||||
const dispatch = useDispatchAndGoToNextQuestion()
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackPage name="societe_ou_entreprise_individuelle" />
|
||||
|
|
|
@ -51,6 +51,7 @@ export default function Créer() {
|
|||
const sitePaths = useContext(SitePathsContext)
|
||||
const location = useLocation()
|
||||
useResetFollowingAnswers()
|
||||
|
||||
return (
|
||||
<>
|
||||
<Link to={sitePaths.créer.index}>
|
||||
|
|
|
@ -24,6 +24,7 @@ export default function Créer() {
|
|||
(state: RootState) =>
|
||||
!!Object.keys(state.choixStatutJuridique.companyLegalStatus).length
|
||||
)
|
||||
|
||||
return (
|
||||
<FromBottom>
|
||||
<TrackPage name="accueil" />
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Trans } from 'react-i18next'
|
||||
import { LegalStatus } from '@/selectors/companyStatusSelectors'
|
||||
|
||||
type Props = {
|
||||
statut: LegalStatus
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import Home from './Home'
|
|||
export default function CreateMyCompany() {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
const location = useLocation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<ScrollToTop key={location.pathname} />
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Button } from '@/design-system/buttons'
|
|||
import { H2 } from '@/design-system/typography/heading'
|
||||
import { lazy, Suspense, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import useSimulatorsData from '../Simulateurs/metadata'
|
||||
|
||||
const LazyColorPicker = lazy(() => import('./ColorPicker'))
|
||||
|
||||
export default function IntegrationTest() {
|
||||
|
@ -31,6 +32,7 @@ export default function IntegrationTest() {
|
|||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [version])
|
||||
|
||||
return (
|
||||
<>
|
||||
<H2>Quel module ?</H2>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { generateSiteMap } from '../../sitePaths'
|
|||
|
||||
export default function SiteMap() {
|
||||
const sitePaths = useContext(SitePathsContext)
|
||||
|
||||
return (
|
||||
<>
|
||||
<H1>Sitemap</H1>
|
||||
|
|
|
@ -90,6 +90,7 @@ function BackToSimulation() {
|
|||
if (!url) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Spacing lg />
|
||||
|
@ -120,6 +121,7 @@ function DocumentationLanding() {
|
|||
|
||||
function DocumentationRulesList() {
|
||||
const ruleEntries = Object.keys(rules) as DottedName[]
|
||||
|
||||
return (
|
||||
<>
|
||||
<H1>Liste des règles</H1>
|
||||
|
@ -166,6 +168,7 @@ export function References({ references }: ReferencesProps) {
|
|||
<StyledReferences>
|
||||
{Object.entries(references).map(([name, link]) => {
|
||||
const domain = cleanDomain(link)
|
||||
|
||||
return (
|
||||
<li key={name}>
|
||||
<span className="imageWrapper">
|
||||
|
|
|
@ -17,6 +17,7 @@ type SubSectionProp = {
|
|||
dottedName: DottedName
|
||||
hideTitle?: boolean
|
||||
}
|
||||
|
||||
export function SubSection({
|
||||
dottedName: sectionDottedName,
|
||||
hideTitle = false,
|
||||
|
@ -38,6 +39,7 @@ export function SubSection({
|
|||
dottedName,
|
||||
rawNode: { question },
|
||||
} = engine.getRule(nextStep)
|
||||
|
||||
return !!question && dottedName.startsWith(sectionDottedName)
|
||||
})
|
||||
|
||||
|
@ -56,6 +58,7 @@ type SimpleFieldProps = {
|
|||
question?: RuleNode['rawNode']['question']
|
||||
showSuggestions?: boolean
|
||||
}
|
||||
|
||||
export function SimpleField({
|
||||
dottedName,
|
||||
question,
|
||||
|
@ -77,6 +80,7 @@ export function SimpleField({
|
|||
if (evaluation.nodeValue === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FromTop>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue