Refacto du stockage des réponses; bouton continuer correctement activé

pull/518/head
Mael 2019-05-22 10:42:50 +02:00
parent 483000a4f4
commit 179c31cbf5
5 changed files with 69 additions and 40 deletions

View File

@ -11,6 +11,8 @@ import { StoreContext } from './StoreContext'
import { NextButton } from './ActivitésSelection'
import Exonérations from './Exonérations'
let allTrue = list => list && all(item => item === true)(list)
export default withSitePaths(function LocationMeublée({
sitePaths,
match: {
@ -25,8 +27,7 @@ export default withSitePaths(function LocationMeublée({
answers = activityAnswers[title] || {}
return (
<section
>
<section>
<Animate.fromBottom>
<ScrollToTop />
<h1>
@ -41,10 +42,9 @@ export default withSitePaths(function LocationMeublée({
)}
<h2>Votre situation</h2>
<Exonérations
{...{ exonérations: data.exonérations, dispatch, title }}
{...{ exonérations: data.exonérations, answers, dispatch, title }}
/>
{answers.exonerations &&
all(item => item === true, answers.exonerations) ? (
{answers.exonérations && allTrue(answers.exonérations) ? (
<p>
{emoji('😌 ')}
En ce qui concerne les revenus de cette activité, vous n'avez pas
@ -101,19 +101,31 @@ export default withSitePaths(function LocationMeublée({
</form>
</>
)}
{JSON.stringify(data)}
{JSON.stringify(answers)}
<NextButton
{...{
activityAnswers,
selectedActivities,
disabled: false
/* Bien spécifier les cas d'activation du bouton
answers.pro == undefined &&
!answers.exoneration &&
!data['seuil pro'] === 0
*/
disabled: incompleteActivity(data, answers),
currentActivité: title,
action :
()=>
dispatch({
type: 'UPDATE_ACTIVITY',
title,
data: { ...answers, completed: true }
})
}}
/>
</Animate.fromBottom>
</section>
)
})
export let incompleteActivity = (data, answers) =>
(data['seuil pro'] > 0 &&
!allTrue(answers.exonérations) &&
answers.pro == null) ||
(data['exonérations'] && answers.exonérations == null)

View File

@ -8,6 +8,7 @@ import { Link } from 'react-router-dom'
import Animate from 'Ui/animate'
import activités from './activités.yaml'
import { StoreContext } from './StoreContext'
import { incompleteActivity } from './Activité'
export default (function ActivitésSelection() {
let { state, dispatch } = useContext(StoreContext)
@ -80,8 +81,17 @@ export default (function ActivitésSelection() {
})
export let NextButton = withSitePaths(
({ sitePaths, activityAnswers, selectedActivities, disabled }) => {
let nextActivity = selectedActivities.find(a => !activityAnswers[a]),
({
sitePaths,
activityAnswers,
selectedActivities,
disabled,
currentActivité,
action
}) => {
let nextActivity = without([currentActivité], selectedActivities).find(
a => !activityAnswers[a].completed
),
to = nextActivity
? sitePaths.économieCollaborative.activités.index + '/' + nextActivity
: sitePaths.économieCollaborative.votreSituation
@ -92,6 +102,7 @@ export let NextButton = withSitePaths(
margin-top: 1rem;
`}
to={to}
onClick={action}
className={classnames('ui__ plain button', {
disabled
})}>

View File

@ -1,38 +1,35 @@
import React from 'react'
import { createMarkdownDiv } from 'Engine/marked'
import { CheckItem } from 'Ui/Checklist'
import { update } from 'ramda'
export default ({ exonérations, dispatch, answers, title }) => {
if (!exonérations) return null
let multiple = exonérations['toutes ces conditions']
let items = Array.isArray(multiple) ? multiple : [exonérations]
return (
<div
css={`
margin: 1em 0;
`}>
{items.length > 1 && <p>Respectez-vous ces conditions ? </p>}
{exonérations.length > 1 && <p>Respectez-vous ces conditions ? </p>}
{items.map(({ titre, explication }, index) => (
{exonérations.map(({ titre, explication }, index) => (
<CheckItem
name={titre}
title={titre}
explanations={createMarkdownDiv(explication)}
onChange={checked =>
dispatch({
onChange={checked => {
let action = {
type: 'UPDATE_ACTIVITY',
title,
data: {
...answers,
exonerations: [
answers.exonerations.map((v, answerIndex) =>
answerIndex === index ? checked : v
)
]
exonérations: update(index, checked, answers.exonérations)
}
})
}
}
console.log(action)
dispatch(action)
}}
/>
))}
</div>

View File

@ -11,7 +11,7 @@
seuil pro: 23000
exonérations:
# https://www.pap.fr/bailleur/impots-taxes/location-meublee-quelle-fiscalite/a1787/location-meublee-les-exonerations
titre: Il s'agit d'une pièce dans ma résidence principale
- titre: Il s'agit d'une pièce dans ma résidence principale
explication: |
Vous donnez en location une ou plusieurs pièces de votre habitation principale : vous êtes exonéré d'impôt sous réserve que la ou les pièces louée(s) constituent la résidence principale du locataire ou sa résidence temporaire. Pour bénéficier de cette dernière condition, le locataire doit pouvoir justifier d'un contrat de travail saisonnier ou d'un CDD d'usage. Le prix de la location doit être fixé dans des limites raisonnables. Pour les baux conclus en 2019, le loyer ne doit pas dépasser 187 € par an et par mètre carré en Île-de-France et 138 € par mètre carré et par an dans les autres régions. Ces plafonds sont relevés au 1er janvier de chaque année.
> Vous louez à Paris, dans votre résidence principale, une chambre de 18 m² à un étudiant. Pour être exonéré d'impôt, le loyer mensuel hors charges ne doit pas dépasser en 2019 (187 x 18) / 12 = 280 €.
@ -52,7 +52,7 @@
- Etsy...
seuil pro: 0
exonérations:
titre: Vous vendez de façon occasionnelle des biens qui vous ont servi en premier lieu
- titre: Vous vendez de façon occasionnelle des biens qui vous ont servi en premier lieu
explication: |
Si à l'inverse, il sagit de biens que vous avez achetés ou que vous avez fabriqués en vue de les revendre (exemple : vous réalisez des bijoux, des objets de décoration…), votre activité est alors à caractère professionnel et elle doit être déclarée.
@ -66,16 +66,15 @@
- Blablacar
exonérations:
toutes ces conditions:
- titre: Vous profitez du service proposé
explication: |
Les revenus que vous réalisez au titre du partage des frais sont perçus dans le cadre dune « co-consommation », ce qui signifie que vous bénéficiez également de la prestation de service proposée au même titre que les personnes avec lesquelles les frais sont partagés ;
- titre: Les revenus ne font que couvrir vos frais
explication: |
Les revenus perçus nexcèdent pas le montant des coûts directs engagés à loccasion de la prestation. Ils ne doivent couvrir que les frais supportés à loccasion du service rendu (hors frais liés à lacquisition, lentretien ou lutilisation personnelle du bien partagé).
- titre: Si co-voiturage, attention au barème kilométrique
explication: |
Lorsquil sagit de co-voiturage, il existe une troisième condition : le tarif complet ne doit pas excéder le barème kilométrique en vigueur et doit être divisé par le nombre de personnes transportées, le propriétaire de la voiture inclus.<Paste>
- titre: Vous profitez du service proposé
explication: |
Les revenus que vous réalisez au titre du partage des frais sont perçus dans le cadre dune « co-consommation », ce qui signifie que vous bénéficiez également de la prestation de service proposée au même titre que les personnes avec lesquelles les frais sont partagés ;
- titre: Les revenus ne font que couvrir vos frais
explication: |
Les revenus perçus nexcèdent pas le montant des coûts directs engagés à loccasion de la prestation. Ils ne doivent couvrir que les frais supportés à loccasion du service rendu (hors frais liés à lacquisition, lentretien ou lutilisation personnelle du bien partagé).
- titre: Si co-voiturage, attention au barème kilométrique
explication: |
Lorsquil sagit de co-voiturage, il existe une troisième condition : le tarif complet ne doit pas excéder le barème kilométrique en vigueur et doit être divisé par le nombre de personnes transportées, le propriétaire de la voiture inclus.<Paste>

View File

@ -1,8 +1,18 @@
import { without } from 'ramda'
import { without, map, pipe, mergeAll } from 'ramda'
import data from './activités.yaml'
let initialState = {
selectedActivities: [],
activityAnswers: {}
activityAnswers: pipe(
map(a => ({
[a.titre]: a.exonérations
? { exonérations: a.exonérations.map(() => null) }
: {}
})),
mergeAll
)(data)
}
console.log(initialState)
let reducer = (state = initialState, action) => {
switch (action.type) {