diff --git a/package.json b/package.json index 13dbe0b1c..de4599708 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "reduce-reducers": "^0.1.2", "redux": "^3.7.2", "redux-form": "^7.4.2", + "redux-thunk": "^2.3.0", "reselect": "^3.0.1", "screenfull": "^3.3.2" }, diff --git a/source/Provider.js b/source/Provider.js index 02f82d929..9225c552f 100644 --- a/source/Provider.js +++ b/source/Provider.js @@ -7,6 +7,7 @@ import { Provider } from 'react-redux' import { Router } from 'react-router-dom' import reducers from 'Reducers/rootReducer' import { applyMiddleware, compose, createStore } from 'redux' +import thunk from 'redux-thunk' import computeThemeColours from 'Ui/themeColours' import trackDomainActions from './middlewares/trackDomainActions' import { @@ -43,10 +44,7 @@ let initialStore = { } const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose -let enhancer = composeEnhancers(applyMiddleware(trackDomainActions(tracker))) -let store = createStore(reducers, initialStore, enhancer) -persistSimulation(store) if (process.NODE_ENV === 'production' && 'serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker @@ -61,17 +59,27 @@ if (process.NODE_ENV === 'production' && 'serviceWorker' in navigator) { } export default class Layout extends PureComponent { - state = { - history: createHistory({ + constructor(props) { + super(props) + this.history = createHistory({ basename: process.env.NODE_ENV === 'production' ? '' : this.props.basename }) + const storeEnhancer = composeEnhancers( + applyMiddleware( + // Allows us to painlessly do route transition in action creators + thunk.withExtraArgument(this.history), + trackDomainActions(tracker) + ) + ) + this.store = createStore(reducers, initialStore, storeEnhancer) + persistSimulation(this.store) } render() { return ( - + - + <>{this.props.children} diff --git a/source/actions/companyStatusActions.js b/source/actions/companyStatusActions.js index ef64e5fd9..7db154400 100644 --- a/source/actions/companyStatusActions.js +++ b/source/actions/companyStatusActions.js @@ -2,34 +2,47 @@ import type { ChooseCompanyLiabilityAction, CompanyLiability, - CompanyHaveMultipleAssociateAction, + CompanyHaveMultipleAssociatesAction, DirectorStatus, + CompanyIsMicroenterpriseAction, DefineDirectorStatusAction } from 'Types/companyStatusTypes' +import type { RouterHistory } from 'react-router' +import { nextQuestionUrlSelector } from 'Selectors/companyStatusSelectors' -export function chooseCompanyLiability( - setup: CompanyLiability -): ChooseCompanyLiabilityAction { - return { +const thenGoToNextQuestion = actionCreator => (...args: any) => ( + dispatch: any => void, + getState: () => any, + history: RouterHistory +) => { + dispatch(actionCreator(...args)) + history.push(nextQuestionUrlSelector(getState())) +} + +export const chooseCompanyLiability = thenGoToNextQuestion( + (setup: ?CompanyLiability): ChooseCompanyLiabilityAction => ({ type: 'CHOOSE_COMPANY_LEGAL_SETUP', setup - } -} + }) +) -export function defineDirectorStatus( - status: DirectorStatus -): DefineDirectorStatusAction { - return { +export const defineDirectorStatus = thenGoToNextQuestion( + (status: ?DirectorStatus): DefineDirectorStatusAction => ({ type: 'DEFINE_DIRECTOR_STATUS', status - } -} + }) +) -export function companyHaveMultipleAssociate( - multipleAssociate: boolean -): CompanyHaveMultipleAssociateAction { - return { - type: 'COMPANY_HAVE_MULTIPLE_ASSOCIATE', - multipleAssociate - } -} +export const companyHaveMultipleAssociates = thenGoToNextQuestion( + (multipleAssociates: ?boolean): CompanyHaveMultipleAssociatesAction => ({ + type: 'COMPANY_HAVE_MULTIPLE_ASSOCIATES', + multipleAssociates + }) +) + +export const companyIsMicroenterprise = thenGoToNextQuestion( + (microenterprise: ?boolean): CompanyIsMicroenterpriseAction => ({ + type: 'COMPANY_IS_MICROENTERPRISE', + microenterprise + }) +) diff --git a/source/components/ui/Button/button.css b/source/components/ui/Button/button.css index 19f2866c6..cf6caa9e4 100644 --- a/source/components/ui/Button/button.css +++ b/source/components/ui/Button/button.css @@ -32,12 +32,12 @@ border-color: rgb(41, 117, 209); color: rgb(41, 117, 209); background: linear-gradient( - 45deg, + 50deg, rgba(39, 69, 195, 0.87) 5%, rgba(41, 117, 209, 1) 50%, rgba(255, 255, 255, 0.52) 55% ); - background-size: 250%; + background-size: 260%; background-position-x: 99%; } .ui__.button:not(:disabled):hover, diff --git a/source/reducers/inFranceAppReducer.js b/source/reducers/inFranceAppReducer.js index 1e767cd0b..57a2b5b61 100644 --- a/source/reducers/inFranceAppReducer.js +++ b/source/reducers/inFranceAppReducer.js @@ -17,8 +17,10 @@ function companyLegalStatus( case 'DEFINE_DIRECTOR_STATUS': return { ...state, directorStatus: action.status } - case 'COMPANY_HAVE_MULTIPLE_ASSOCIATE': - return { ...state, multipleAssociate: action.multipleAssociate } + case 'COMPANY_HAVE_MULTIPLE_ASSOCIATES': + return { ...state, multipleAssociates: action.multipleAssociates } + case 'COMPANY_IS_MICROENTERPRISE': + return { ...state, microenterprise: action.microenterprise } } return state } diff --git a/source/selectors/companyStatusSelectors.js b/source/selectors/companyStatusSelectors.js index f71f65810..dd0fd89e4 100644 --- a/source/selectors/companyStatusSelectors.js +++ b/source/selectors/companyStatusSelectors.js @@ -1,74 +1,150 @@ /* @flow */ -import type { - State, - CompanyLegalStatus, - DirectorStatus -} from 'Types/companyStatusTypes' -import { map, whereEq } from 'ramda' +import type { State, CompanyLegalStatus } from 'Types/companyStatusTypes' +import { + add, + countBy, + difference, + filter, + map, + pick, + sortBy, + whereEq +} from 'ramda' const LEGAL_STATUS_DETAILS: { [status: string]: CompanyLegalStatus } = { + Microenterprise: { + liability: 'SOLE_PROPRIETORSHIP', + directorStatus: 'SELF_EMPLOYED', + multipleAssociates: false, + microenterprise: true, + }, + 'Microenterprise (option EIRL)': { + liability: 'LIMITED_LIABILITY', + directorStatus: 'SELF_EMPLOYED', + multipleAssociates: false, + microenterprise: true + }, EI: { liability: 'SOLE_PROPRIETORSHIP', directorStatus: 'SELF_EMPLOYED', - multipleAssociate: false + multipleAssociates: false, + microenterprise: false }, EURL: { liability: 'LIMITED_LIABILITY', directorStatus: 'SELF_EMPLOYED', - multipleAssociate: false + multipleAssociates: false, + microenterprise: false }, EIRL: { liability: 'LIMITED_LIABILITY', directorStatus: 'SELF_EMPLOYED', - multipleAssociate: false + multipleAssociates: false, + microenterprise: false }, SARL: { liability: 'LIMITED_LIABILITY', directorStatus: 'SELF_EMPLOYED', - multipleAssociate: true + multipleAssociates: true, + microenterprise: false }, SAS: { liability: 'LIMITED_LIABILITY', directorStatus: 'SALARIED', - multipleAssociate: true + multipleAssociates: true, + microenterprise: false }, SA: { liability: 'LIMITED_LIABILITY', directorStatus: 'SALARIED', - multipleAssociate: true + multipleAssociates: true, + microenterprise: false }, SNC: { liability: 'SOLE_PROPRIETORSHIP', directorStatus: 'SELF_EMPLOYED', - multipleAssociate: true + multipleAssociates: true, + microenterprise: false }, SASU: { liability: 'LIMITED_LIABILITY', - directorStatus: 'SELF_EMPLOYED', - multipleAssociate: false + directorStatus: 'SALARIED', + multipleAssociates: false, + microenterprise: false } } export type LegalStatus = $Keys const possibleStatus = ( companyLegalStatus: CompanyLegalStatus ): { [LegalStatus]: boolean } => - // $FlowFixMe - map(whereEq(companyLegalStatus), LEGAL_STATUS_DETAILS) + map( + // $FlowFixMe + whereEq(filter(x => x !== null, companyLegalStatus)), + LEGAL_STATUS_DETAILS + ) export const possibleStatusSelector = (state: { inFranceApp: State }): { [LegalStatus]: boolean } => possibleStatus(state.inFranceApp.companyLegalStatus) -export const disabledDirectorStatusSelector = (state: { +type Question = $Keys + +const QUESTION_LIST: Array = Object.keys(LEGAL_STATUS_DETAILS.SA); +export const nextQuestionSelector = (state: { inFranceApp: State -}): Array => - ['SALARIED', 'SELF_EMPLOYED'].filter(directorStatus => - Object.values( - possibleStatus({ - ...state.inFranceApp.companyLegalStatus, - directorStatus - }) - ).every(x => x === false) +}): ?Question => { + const companyLegalStatus = state.inFranceApp.companyLegalStatus + const questionAnswered = Object.keys(companyLegalStatus) + const possibleStatusList = pick( + Object.keys(filter(Boolean, possibleStatus(companyLegalStatus))), + LEGAL_STATUS_DETAILS ) + + const unansweredQuestions = difference(QUESTION_LIST, questionAnswered) + const shannonEntropyByQuestion = unansweredQuestions.map(question => { + const answerPopulation = Object.values(possibleStatusList).map( + // $FlowFixMe + status => status[question] + ) + const frequencyOfAnswers = Object.values( + countBy(x => x, answerPopulation) + ).map( + numOccurrence => + // $FlowFixMe + numOccurrence / answerPopulation.length + ) + const shannonEntropy = -frequencyOfAnswers + .map(p => p * Math.log2(p)) + // $FlowFixMe + .reduce(add, 0) + return [question, shannonEntropy] + }) + const sortedPossibleNextQuestions = sortBy( + ([, entropy]) => -entropy, + shannonEntropyByQuestion.filter(([, entropy]) => entropy !== 0) + ).map(([question]) => question) + if (sortedPossibleNextQuestions.length === 0) { + return null + } + return sortedPossibleNextQuestions[0] +} + +export const nextQuestionUrlSelector = (state: { inFranceApp: State }) => { + const nextQuestion = nextQuestionSelector(state) + if (!nextQuestion) { + return '/register/pick-legal-status' + } + return ( + '/register/' + + nextQuestion + .replace(/[^a-zA-Z0-9]+/g, '-') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2') + .replace(/([a-z])([A-Z])/g, '$1-$2') + .replace(/([0-9])([^0-9])/g, '$1-$2') + .replace(/([^0-9])([0-9])/g, '$1-$2') + .replace(/-+/g, '-') + .toLowerCase() + ) +} diff --git a/source/sites/mycompanyinfrance.fr/entry.js b/source/sites/mycompanyinfrance.fr/entry.js index edd6be903..f1203aecf 100644 --- a/source/sites/mycompanyinfrance.fr/entry.js +++ b/source/sites/mycompanyinfrance.fr/entry.js @@ -2,5 +2,46 @@ import React from 'react' import { render } from 'react-dom' import App from './App' +// Avoid `console` errors in browsers that lack a console. +;(function() { + var method + var noop = function() {} + var methods = [ + 'assert', + 'clear', + 'count', + 'debug', + 'dir', + 'dirxml', + 'error', + 'exception', + 'group', + 'groupCollapsed', + 'groupEnd', + 'info', + 'log', + 'markTimeline', + 'profile', + 'profileEnd', + 'table', + 'time', + 'timeEnd', + 'timeStamp', + 'trace', + 'warn' + ] + var length = methods.length + var console = (window.console = window.console || {}) + + while (length--) { + method = methods[length] + + // Only stub undefined methods. + if (!console[method]) { + console[method] = noop + } + } +})() + let anchor = document.querySelector('#js') render(, anchor) diff --git a/source/sites/mycompanyinfrance.fr/history.js b/source/sites/mycompanyinfrance.fr/history.js new file mode 100644 index 000000000..e69de29bb diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/DirectorStatus.js b/source/sites/mycompanyinfrance.fr/pages/Company/DirectorStatus.js index 4af403b07..b9fa6a062 100644 --- a/source/sites/mycompanyinfrance.fr/pages/Company/DirectorStatus.js +++ b/source/sites/mycompanyinfrance.fr/pages/Company/DirectorStatus.js @@ -1,27 +1,14 @@ /* @flow */ import { defineDirectorStatus } from 'Actions/companyStatusActions' -import { equals } from 'ramda' import React from 'react' import { connect } from 'react-redux' -import { disabledDirectorStatusSelector } from 'Selectors/companyStatusSelectors' import { SkipButton } from 'Ui/Button' import type { DirectorStatus } from 'Types/companyStatusTypes' -import type { RouterHistory } from 'react-router' + type Props = { - history: RouterHistory, - defineDirectorStatus: DirectorStatus => void, - disabledDirectorStatus: Array + defineDirectorStatus: (?DirectorStatus) => void } - -const goToNextStep = (history: RouterHistory) => { - history.push('/register/set-legal-status') -} - -const DefineDirectorStatus = ({ - history, - defineDirectorStatus, - disabledDirectorStatus -}: Props) => ( +const DefineDirectorStatus = ({ defineDirectorStatus }: Props) => ( <>

Defining the director's status

@@ -47,39 +34,27 @@ const DefineDirectorStatus = ({ professional income as reported to the tax authorities. - {!!disabledDirectorStatus.length && ( -

- Because of your previous choices, you only have the following - possibility for the director status: -

- )}
- {!disabledDirectorStatus.find(equals('SALARIED')) && ( - - )} - {!disabledDirectorStatus.find(equals('SELF-EMPLOYED')) && ( - - )} - goToNextStep(history)} /> + + + defineDirectorStatus(null)} />
) export default connect( - state => ({ disabledDirectorStatus: disabledDirectorStatusSelector(state) }), + null, { defineDirectorStatus } )(DefineDirectorStatus) diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/Home.js b/source/sites/mycompanyinfrance.fr/pages/Company/Home.js index 967f3a52f..9e3091d32 100644 --- a/source/sites/mycompanyinfrance.fr/pages/Company/Home.js +++ b/source/sites/mycompanyinfrance.fr/pages/Company/Home.js @@ -1,12 +1,14 @@ /* @flow */ import React from 'react' +import { connect } from 'react-redux' import { Link } from 'react-router-dom' +import { nextQuestionUrlSelector } from 'Selectors/companyStatusSelectors' import type { Match } from 'react-router' - type Props = { - match: Match + match: Match, + nextQuestionUrl: string } -const CreateMyCompany = ({ match }: Props) => ( +const CreateMyCompany = ({ match, nextQuestionUrl }: Props) => ( <>

Register a company

@@ -21,7 +23,7 @@ const CreateMyCompany = ({ match }: Props) => (

{match.isExact && (
- + Choose the legal status @@ -32,4 +34,7 @@ const CreateMyCompany = ({ match }: Props) => ( ) -export default CreateMyCompany +export default connect( + state => ({ nextQuestionUrl: nextQuestionUrlSelector(state) }), + null +)(CreateMyCompany) diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/Liability.js b/source/sites/mycompanyinfrance.fr/pages/Company/Liability.js index 3cb277058..21286e0c6 100644 --- a/source/sites/mycompanyinfrance.fr/pages/Company/Liability.js +++ b/source/sites/mycompanyinfrance.fr/pages/Company/Liability.js @@ -3,19 +3,15 @@ import { chooseCompanyLiability } from 'Actions/companyStatusActions' import React from 'react' import { connect } from 'react-redux' import { SkipButton } from 'Ui/Button' -import type { Match, RouterHistory } from 'react-router' +import type { Match } from 'react-router' import type { CompanyLiability } from 'Types/companyStatusTypes' type Props = { match: Match, - history: RouterHistory, - chooseCompanyLiability: CompanyLiability => void + chooseCompanyLiability: (?CompanyLiability) => void } -const goToNextStep = (history: RouterHistory) => { - history.push('/register/number-of-associate') -} -const Liability = ({ chooseCompanyLiability, history }: Props) => ( +const Liability = ({ chooseCompanyLiability }: Props) => ( <>

Choosing the liability

@@ -40,7 +36,6 @@ const Liability = ({ chooseCompanyLiability, history }: Props) => (

- goToNextStep(history)} /> + chooseCompanyLiability(null)} />
{/* this is an economic activity conducted by a single natural person, in his own name ; */} {/* Company : This is an economic activity conducted by a single partner - single member company with limited liability (EURL) - or several partners (limited liability company (SARL), public limited company (SA), simplified joint-stock company (SAS)...). */} @@ -63,7 +57,5 @@ const Liability = ({ chooseCompanyLiability, history }: Props) => ( export default connect( null, - { - chooseCompanyLiability - } + { chooseCompanyLiability } )(Liability) diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/MainStatus.js b/source/sites/mycompanyinfrance.fr/pages/Company/MainStatus.js index ca3354dcd..db6a3d097 100644 --- a/source/sites/mycompanyinfrance.fr/pages/Company/MainStatus.js +++ b/source/sites/mycompanyinfrance.fr/pages/Company/MainStatus.js @@ -13,6 +13,7 @@ type Props = { setMainStatus: LegalStatus => void } + const StatusButton = ({ status }: { status: LegalStatus }) => ( Create {status} @@ -20,25 +21,16 @@ const StatusButton = ({ status }: { status: LegalStatus }) => ( ) const SetMainStatus = ({ history, possibleStatus }: Props) => { - const atLeastOneStatus = Object.values(possibleStatus).some(x => x) - return ( + const uniqStatus = (Object.values(possibleStatus).filter(Boolean).length === 1); + return ( <> -

Choosing a legal status

- {atLeastOneStatus ? ( -

- Based on your previous answers, you can choose between the following - statuses: -

- ) : ( -

- {' '} - We didn't find any status matching your need. You can go back and - change your needs, or choose a status manually from the following - list: -

- )} +

Your legal status

+ {uniqStatus?

The following status seems to be the perfect match for your need:

:

+ Based on your previous answers, you can choose between the following statuses: +

} +
    - {(!atLeastOneStatus || possibleStatus.EI) && ( + {possibleStatus.EI && (
  • EI - Entreprise individuelle (Individual business):{' '} @@ -48,7 +40,7 @@ const SetMainStatus = ({ history, possibleStatus }: Props) => { wealth are one.
  • )} - {(!atLeastOneStatus || possibleStatus.EIRL) && ( + {possibleStatus.EIRL && (
  • EIRL - Entrepreneur individuel à responsabilité limitée @@ -58,7 +50,7 @@ const SetMainStatus = ({ history, possibleStatus }: Props) => { heritage necessary for the activity.
  • )} - {(!atLeastOneStatus || possibleStatus.EURL) && ( + {possibleStatus.EURL && (
  • EURL - Entreprise unipersonnelle à responsabilité limitée (Limited @@ -68,7 +60,7 @@ const SetMainStatus = ({ history, possibleStatus }: Props) => { its contribution to the capital.
  • )} - {(!atLeastOneStatus || possibleStatus.SARL) && ( + {possibleStatus.SARL && (
  • SARL - Société à responsabilité limitée (Limited corporation):{' '} @@ -78,7 +70,7 @@ const SetMainStatus = ({ history, possibleStatus }: Props) => { capital is freely fixed in the statutes.
  • )} - {(!atLeastOneStatus || possibleStatus.SAS) && ( + {possibleStatus.SAS && (
  • SAS - Société par actions simplifiées (Simplified joint stock @@ -89,7 +81,7 @@ const SetMainStatus = ({ history, possibleStatus }: Props) => { the statutes.
  • )} - {(!atLeastOneStatus || possibleStatus.SASU) && ( + {possibleStatus.SASU && (
  • SASU - Société par action simplifiée unipersonnelle (Simplified @@ -99,24 +91,36 @@ const SetMainStatus = ({ history, possibleStatus }: Props) => { capital. The minimum capital is freely fixed in the statutes.
  • )} - {(!atLeastOneStatus || possibleStatus.SA) && ( + {possibleStatus.SA && (
  • SA - Société anonyme (Anonymous company):Company - composed of at least 2 shareholders if it is not listed. + composed of at least 2 shareholders. The only status that allows you to be listed on the stock exchange. The minimum share capital is €37.000.
  • )} - {(!atLeastOneStatus || possibleStatus.SNC) && ( + {possibleStatus.SNC && (
  • SNC - Société en nom collectif (Partnership):The partners are liable indefinitely and severally for the debts of the company.
  • )} + + {possibleStatus['Microenterprise (option EIRL)'] && ( +
  • + Microenterprise (option EIRL): The micro-enterprise is a sole proprietorship company, subject to a flat-rate scheme for the calculation of taxes and the payment of social security contributions. With the EIRL option, you have limited liability on your losses. +
  • + )} + + {possibleStatus.Microenterprise && ( +
  • + Microenterprise: The micro-enterprise is a sole proprietorship subject to a flat-rate scheme for the calculation of taxes and the payment of social security contributions. +
  • + )}
{/* $FlowFixMe */} {(Object.entries(possibleStatus): Array<[LegalStatus, boolean]>) - .filter(([, statusIsVisible]) => statusIsVisible || !atLeastOneStatus) + .filter(([, statusIsVisible]) => statusIsVisible) .map(([status]) => ( ))} diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/Microenterprise.js b/source/sites/mycompanyinfrance.fr/pages/Company/Microenterprise.js new file mode 100644 index 000000000..b46b0486d --- /dev/null +++ b/source/sites/mycompanyinfrance.fr/pages/Company/Microenterprise.js @@ -0,0 +1,43 @@ +/* @flow */ +import { companyIsMicroenterprise } from 'Actions/companyStatusActions' +import React from 'react' +import { connect } from 'react-redux' +import { SkipButton } from 'Ui/Button' + +type Props = { + companyIsMicroenterprise: (?boolean) => void +} + +const Microenterprise = ({ companyIsMicroenterprise }: Props) => ( + <> +

Microenterprise or Individual Business

+

+ The Micro entreprise is a simplified scheme of declaration and payment, whose tax and social contributions are based on the turnover achieved each month. Available for + companies whose annual turnover does not exceed (for the past year) 70 000 € for services providers or 170 000 € for micro-entrepreneurs whose main activity is the sale of goods, catering or the provision of housing. +

This is a interesting choice if you do not need lot of capital for your activity, you plan it to be small, and you want the minimum amount of paperwork to get started.

+

For all other case, it is advised to choose the standard status, which is Individual Business.

+ +
+ + + companyIsMicroenterprise(null)} /> +
+ +) + +export default connect( + null, + { companyIsMicroenterprise } +)(Microenterprise) diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/NumberOfAssociate.js b/source/sites/mycompanyinfrance.fr/pages/Company/NumberOfAssociate.js index 21b52ab25..0b86e7f5e 100644 --- a/source/sites/mycompanyinfrance.fr/pages/Company/NumberOfAssociate.js +++ b/source/sites/mycompanyinfrance.fr/pages/Company/NumberOfAssociate.js @@ -1,23 +1,14 @@ /* @flow */ -import { companyHaveMultipleAssociate } from 'Actions/companyStatusActions' +import { companyHaveMultipleAssociates } from 'Actions/companyStatusActions' import React from 'react' import { connect } from 'react-redux' import { SkipButton } from 'Ui/Button' -import type { RouterHistory } from 'react-router' type Props = { - history: RouterHistory, - companyHaveMultipleAssociate: boolean => void + companyHaveMultipleAssociates: (?boolean) => void } -const goToNextStep = (history: RouterHistory) => { - history.push('/register/define-director-status') -} - -const NumberOfAssociate = ({ - history, - companyHaveMultipleAssociate -}: Props) => ( +const NumberOfAssociate = ({ companyHaveMultipleAssociates }: Props) => ( <>

Number of associates

@@ -28,26 +19,24 @@ const NumberOfAssociate = ({

- goToNextStep(history)} /> + companyHaveMultipleAssociates(null)} />
) export default connect( null, - { companyHaveMultipleAssociate } + { companyHaveMultipleAssociates } )(NumberOfAssociate) diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/Register.js b/source/sites/mycompanyinfrance.fr/pages/Company/Register.js index 6393678f6..42b8b465f 100644 --- a/source/sites/mycompanyinfrance.fr/pages/Company/Register.js +++ b/source/sites/mycompanyinfrance.fr/pages/Company/Register.js @@ -1,75 +1,64 @@ /* @flow */ -import Checklist from 'Components/Checklist' import React from 'react' import { Link } from 'react-router-dom' -import siret from './siret.jpg' -import type { Match } from 'react-router' - -export default (match: Match) => - Checklist({ - name: 'register', - title: `Checklist to register a ${match.params.status || ''}`, - subtitle: ` - This checklist will guide you thoughout all the necessary steps to - register your company with the French administration. - `, - items: { - legalStatus: 'Choose the legal status', - corporateName: ( -

- Find a corporate name (raison sociale, the legal name of your - company) -

- ), - tradeName: 'Find a trade name (for commercial purposes)', - space: 'Find a space (or work at home)', - registerCfe: ( - - Register your company online on{' '} - - Guichet-entreprises.fr (english) - - - ), - newspaper: `Have the company's creation published in - a newspaper of legal announcements such as the Bodacc (Bulletin officiel - des annonces civiles et commerciales)`, - bankAccount: - 'Open a business bank account and follow the capital deposit procedure if needed', - accountant: 'Choose a certified accountant', - insurance: 'Check out needs of professional insurance' - }, - - conclusion: ( - <> -

- Once your business has been officially registered, you will receive : -

-
    -
  • your Siren number, which identifies your company ;
  • -
  • - the Siret number, which identifies each place of business operated - by the same company. -
  • -
- Siret and siren number -

- It also assigns the APE code for the business sector to which your - company or you as a self-employed worker belong. The APE code is used - to classify your company’s main operations in relation to the french - business nomenclature system (« NAF » code). It also determines the - applicable collective agreement as well as the industrial accident - rate in the field to which you or your company belong. -

-

- Now that you have a properly registered company, the next steps is to{' '} - hire your first employee -

-
- - Simulate hiring cost in France - -
- - ) - }) +import type { Match, RouterHistory } from 'react-router' +type Props = { + history: RouterHistory, + match: Match +} +const Register = ({ match, history }: Props) => ( + <> +

Create a {match.params.status}

+

+ + Not sure about this status? Take our guide to help you choose. + {' '} +

+

+ Register your company to the French administration is the first thing to + do. It can be done online with the following data : +

+
    +
  • + The corporate name, also called "raison sociale" in + french, is the legal name of your company, written on all of your + administrative papers. It can be different from the trade name (used for + commercial purpose). +
  • +
  • + The corporate purpose of the company, also called + "object social" is a short phrase describing the activity of your + company. As it is legally binding it must be composed with care, + possibly with the help of a lawyer. +
  • +
  • + The social security number of the director. In case you + don't have yet a french social security number... +
  • +
  • + The address, the physical space where your company will + be incorporated. In certain areas, you can benefit from substantial + government aid (exemption from charges, taxes, etc.). +
  • +
+

+ If you don't know where your going to open your company, you can discover + the French territories in our incoporation simulator. +

+ {/*

If the company director is not part of the EU, you'll need a specific visa https://www.economie.gouv.fr/entreprises/etranger-comment-creer-votre-entreprise-france

*/} +

+ history.push('/register/registration-pending')} + className="ui__ button" + href="https://translate.google.com/translate?depth=1&hl=en&rurl=translate.google.com&sl=fr&sp=nmt4&tl=en&u=https://www.guichet-entreprises.fr/en/how-to-create-your-business/" + rel="noopener noreferrer" + target="_blank"> + Register my company online + + + Do it later › + +

+ +) +export default Register diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/RegistrationPending.js b/source/sites/mycompanyinfrance.fr/pages/Company/RegistrationPending.js new file mode 100644 index 000000000..3d69b78b7 --- /dev/null +++ b/source/sites/mycompanyinfrance.fr/pages/Company/RegistrationPending.js @@ -0,0 +1,74 @@ +import React from 'react' +import { Link } from 'react-router-dom' +import siret from './siret.jpg' + +const DuringRegistration = () => ( + <> +

Registration pending

+

+ If you have trouble completing your application, we can help. +

+

+ While your application is being processed, you can focus on the following + tasks:{' '} +

+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+

+ You can also{' '} + + learn more about social security system and simulate your first employee + +

+

Application status

+

Once your business has been officially registered, you will receive:

+
    +
  • + Your Siret number + , which identifies your company +
  • +
  • + Your APE code + , which defines your business sector +
  • +
  • + Your K-bis extract + , which certifies that your company is properly registrated +
  • +
+ I've received my SIRET number +

Siren and Siret

+

+ The Siren number identifies your company while the Siret number identifies + each place of business operated by the same company. +

+ Siret and siren number +

APE Code

+

+ The APE code for the business sector to which your company belong. The APE + code is used to classify your company’s main operations in relation to the + french business nomenclature system (« NAF » code). It also determines the + applicable collective agreement as well as the industrial accident rate in + the field to which you or your company belong. +

+

Kbis extract

+ +) + +export default DuringRegistration diff --git a/source/sites/mycompanyinfrance.fr/pages/Company/index.js b/source/sites/mycompanyinfrance.fr/pages/Company/index.js index e058edbaf..62a56afe9 100644 --- a/source/sites/mycompanyinfrance.fr/pages/Company/index.js +++ b/source/sites/mycompanyinfrance.fr/pages/Company/index.js @@ -7,6 +7,8 @@ import Find from './Find' import Home from './Home' import Liability from './Liability' import MainStatus from './MainStatus' +import Microenterprise from './Microenterprise' +import RegistrationPending from './RegistrationPending' import NumberOfAssociate from './NumberOfAssociate' import Register from './Register' @@ -16,8 +18,9 @@ const CreateMyCompany = ({ match, location }) => ( + @@ -42,7 +45,7 @@ const CreateMyCompany = ({ match, location }) => ( {style => ( ( @@ -50,7 +53,7 @@ const CreateMyCompany = ({ match, location }) => ( )} /> ( @@ -58,7 +61,15 @@ const CreateMyCompany = ({ match, location }) => ( )} /> ( + + + + )} + /> + ( @@ -66,7 +77,7 @@ const CreateMyCompany = ({ match, location }) => ( )} /> ( diff --git a/source/sites/mycompanyinfrance.fr/pages/CostsAndBenefits/index.js b/source/sites/mycompanyinfrance.fr/pages/CostsAndBenefits/index.js index 80d46f4fc..d2ee18cf7 100644 --- a/source/sites/mycompanyinfrance.fr/pages/CostsAndBenefits/index.js +++ b/source/sites/mycompanyinfrance.fr/pages/CostsAndBenefits/index.js @@ -21,11 +21,16 @@ class Hiring extends Component { designed to ensure the{' '} general welfare of its people.

+

+ This easy access to health care and other services ensures that + companies can put healthy, highly skilled, and productive + employees to work in an attractive market in the heart of Europe. +

As soon as you declare and pay your employees, you automatically - entitle them to all of France’s health, maternity, disability, old - age, unemployment, occupational accidents and occupational illness - insurance programs. + entitle them to the general scheme of French Social Security + (health, maternity, disability, old age, occupational illness, + accident at work) and unemployment insurance.