# Architecture création d'annonce App
## Redux
```json=
const createAdd = createSlice({
name: 'CREATE_ADD',
initialState: fromJS({
isUpdating: false,
statusType: void 0,
statusText: '',
step1: [],
step2: [],
step3: [],
...
}),
...
)]
```
Les listes step1,2..etc contiennent des élément de type `FormItem`. Chaque liste va sérvir à décrire les champs qui composent les steps de base. Tous les champs d'une étape (même ceux conditinnels) sont présant dans ces listes.
## FormItem object
Chaque item qui compose le formulaire a la forme suivante:
```json=
{
id: 'Title',
component: 'mon composant',
isDisplayed: false,
}
```
## setInputVisibility
Ce reducer va nous sérvir à changer la visibilité d'un élément `FormItem` contenu dans une des liste `step` de notre store redux.
```javascript=
const setInputVisibility = (state, step, formItemId, bool) => {
//trouve l'objet et update son attribut isDisplayed
}
```
A chaque fois qu'un input est changé il faudra passer par ce reducer pour update les champs visibles ou non. Pour l'instant je vois pas de façon plus "générique" de faire . Pour plus de visibilité, les régles de validation propre à chaque input peuvent être stockés au sein de ces mêmes composant input. (avec un R.cond par exemple).
## Initialisation du state redux CreateAdd
Ici il faudrait ajouter la gestion des étapes et faire en sorte que la fonction getCategoryInput return une liste de `FormInput` pour chaque étape.
```javascript=
const categoryInputs = [
{
category: 'REALESTATE_BUY',
extraInputs: ['rooms', 'surface'],
conditionalInputs: {
type: {
offer: ['charges', 'beds'],
looking_for: ['sharingAllowed', 'capacity'],
},
},
},
{
category: 'REALESTATE_RENT',
extraInputs: ['rooms'],
},
];
const getCategoryInputs = (categoryInputs, category, type) => {
const categoryObject = categoryInputs.find(c => c.category === category);
const categoryExtraInput = categoryObject?.extraInputs ?? [];
const conditionalTypeInputs = categoryObject?.conditionalInputs?.type[type] ?? [];
return [...categoryExtraInput, ...conditionalTypeInputs];
}
getCategoryInputs(categoryInputs, 'REALESTATE_BUY', 'looking_for');
// => ['rooms', 'surface', 'sharingAllowed', 'capacity']
```
## Screen
Dans chaque screen il suffirat de .map() sur la liste `step` qui correspond à l'écran et d'afficher l'élément seulement si l'attribut `isDisplayed`est égal à `true`