project-booster-vue 9.56.2 → 9.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/package.json +1 -1
  2. package/src/components/mozaic/text-input/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-mozaic-components-m-text-input-/342/232/233/357/270/217-showcase-type-1-snap.png +0 -0
  3. package/src/components/pedagogy/PbPedagogy.vue +2 -2
  4. package/src/components/pedagogy/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-components-pedagogy-pb-pedagogy-/360/237/246/240-with-instruction-1-snap.png +0 -0
  5. package/src/components/pedagogy/default-payload.json +1 -0
  6. package/src/components/rework/alert/MPbAlert.stories.mdx +48 -0
  7. package/src/components/rework/alert/MPbAlert.vue +135 -0
  8. package/src/components/rework/alert/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-rework-alert-m-pb-alert-/360/237/246/240-101-sandbox-1-snap.png +0 -0
  9. package/src/components/rework/alert/default-payload.json +38 -0
  10. package/src/components/rework/cards/MPbCards.vue +1 -3
  11. package/src/components/rework/exit-options/MPbExitOptions.stories.mdx +75 -0
  12. package/src/components/rework/exit-options/MPbExitOptions.vue +181 -0
  13. package/src/components/rework/exit-options/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-rework-exit-options-m-pb-exit-options-/360/237/246/240-101-sandbox-1-snap.png +0 -0
  14. package/src/components/rework/exit-options/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-rework-exit-options-m-pb-exit-options-/360/237/246/240-with-conditionals-1-snap.png +0 -0
  15. package/src/components/rework/exit-options/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-rework-exit-options-m-pb-exit-options-/360/237/246/240-with-simple-action-1-snap.png +0 -0
  16. package/src/components/rework/exit-options/__snapshots__/storyshots-puppeteer-test-puppeteer-ts-image-storyshots-project-booster-rework-exit-options-m-pb-exit-options-/360/237/246/240-with-typeform-1-snap.png +0 -0
  17. package/src/components/rework/exit-options/default-payload.json +21 -0
  18. package/src/components/rework/exit-options/with-conditionals.json +26 -0
  19. package/src/components/rework/exit-options/with-simple-action.json +17 -0
  20. package/src/components/rework/exit-options/with-typeform.json +24 -0
  21. package/src/components/rework/media/upload/MPbMediaUpload.stories.mdx +172 -0
  22. package/src/components/rework/media/upload/MPbMediaUpload.vue +874 -0
  23. package/src/components/rework/media/upload/document-upload-payload.json +76 -0
  24. package/src/components/rework/media/upload/mediaValidator.ts +144 -0
  25. package/src/components/rework/question/MPbQuestion.vue +13 -3
  26. package/src/components/scenario/PbScenario-Estimator-Bathroom.stories.mdx +1 -1
  27. package/src/components/scenario/PbScenario.vue +14 -2
  28. package/src/components/scenario/scenarii/{bathroom-estimate.json → appointment-qualification-bathroom.json} +1185 -214
  29. package/src/types/pb/Scenario.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-booster-vue",
3
- "version": "9.56.2",
3
+ "version": "9.57.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -60,7 +60,7 @@
60
60
  direction="column"
61
61
  v-if="payload.cards"
62
62
  >
63
- <div class="pb-pedagogy__content-cards-title">Pour aller plus loin</div>
63
+ <div class="pb-pedagogy__content-cards-title">{{ payload.cardsTitle }}</div>
64
64
  <pb-cards-list :cards="payload.cards" @card-click="handleCardClick" />
65
65
  </m-flex>
66
66
  </m-flex>
@@ -209,7 +209,7 @@ $responsive-breakpoint: 'm';
209
209
 
210
210
  &__input {
211
211
  margin-bottom: $mu100;
212
- width: calc(100% - 1.2rem);
212
+ width: 100%;
213
213
  padding: $mu050;
214
214
  }
215
215
  }
@@ -14,6 +14,7 @@
14
14
  "href": "https://storage.googleapis.com/project-booster-media/vad/PDF/Plan_Prise-de-mesure_Leroy-Merlin.pdf"
15
15
  }
16
16
  },
17
+ "cardsTitle": "Pour aller plus loin",
17
18
  "cards": [
18
19
  {
19
20
  "code": "CARD-2",
@@ -0,0 +1,48 @@
1
+ import { Anchor, Story, Preview, Meta, Props, ArgsTable, Source, Canvas } from '@storybook/addon-docs';
2
+ import DEFAULT_PAYLOAD from './default-payload';
3
+ import { nestedAppDecorator } from '../../../../.storybook/nested-app-decorator';
4
+ import MPbAlert from './MPbAlert';
5
+
6
+ <Meta
7
+ title="Project Booster/Rework/Alert/MPbAlert 🦠"
8
+ component={MPbAlert}
9
+ argTypes={{
10
+ payload: {
11
+ table: {
12
+ defaultValue: {
13
+ summary: 'object',
14
+ detail: JSON.stringify(DEFAULT_PAYLOAD, null, ' '),
15
+ },
16
+ },
17
+ control: {
18
+ type: 'object',
19
+ },
20
+ },
21
+ }}
22
+ parameters={{
23
+ layout: 'fullscreen',
24
+ }}
25
+ />
26
+
27
+ # 🦠 `MPbAlert` - Component
28
+
29
+ The `MPbAlert` component to display information that user needed.
30
+
31
+ export const TemplateSandbox = (args, { argTypes }) => ({
32
+ props: Object.keys(argTypes),
33
+ components: { MPbAlert },
34
+ setup() {
35
+ return { args };
36
+ },
37
+ template: `<m-pb-alert
38
+ :payload="args.payload"
39
+ />`,
40
+ });
41
+
42
+ ## showCase
43
+
44
+ <Canvas>
45
+ <Story inline={false} height="862px" name="101 Sandbox" args={{ payload: DEFAULT_PAYLOAD }}>
46
+ {TemplateSandbox.bind({})}
47
+ </Story>
48
+ </Canvas>
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <div class="m-pb-alert">
3
+ <div class="m-pb-alert__title">
4
+ {{ payload.viewModel.title }}
5
+ </div>
6
+ <m-notification title="Composant en cours de construction" :type="payload.viewModel.type">
7
+ <p>Le composant est actuellement en cours de développement, et sera disponible prochainement !</p>
8
+ </m-notification>
9
+
10
+ <div class="m-pb-alert__exit-options">
11
+ <div class="m-pb-alert__exit-options__title">
12
+ {{ payload.viewModel.exitOptionsTitle }}
13
+ </div>
14
+
15
+ <div class="m-pb-alert__exit-options__content row-flex">
16
+ <m-card
17
+ v-for="options in payload.viewModel.exitOptions"
18
+ class="m-pb-alert__exit-options__content__card"
19
+ :title="options.viewModel.title"
20
+ :subtitle="options.viewModel.subtitle"
21
+ :imgSrc="options.viewModel.image"
22
+ >
23
+ <template #footer>
24
+ <m-button label="This is a button" size="s" theme="bordered-primary-02" />
25
+ </template>
26
+ </m-card>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="m-pb-alert__buttons" v-if="payload">
31
+ <div v-for="button in payload.callToActions" class="m-pb-alert__buttons__button row-flex">
32
+ <m-button
33
+ :label="button.label"
34
+ @click="callAction(button.nextStep)"
35
+ :theme="button.theme"
36
+ style="margin-left: 1rem"
37
+ />
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </template>
42
+
43
+ <script lang="ts" setup>
44
+ import { MNotification, MButton, MCard } from '@mozaic-ds/vue-3';
45
+ import { PayloadAction } from '../types/genericPayload';
46
+ const emit = defineEmits(['go-back', 'step-completed']);
47
+
48
+ const props = defineProps({
49
+ /**
50
+ * The component view model and business data as an object. The provided prop
51
+ * is merged with the default payload value so only overriden values will change
52
+ * from the default ones.
53
+ */
54
+ payload: {
55
+ type: Object,
56
+ default: () => ({}),
57
+ },
58
+ });
59
+
60
+ /**
61
+ * Send action to completed step
62
+ * @param action
63
+ */
64
+ const callAction = (action: PayloadAction) => {
65
+ emit('step-completed', {
66
+ answers: [],
67
+ nextStep: action,
68
+ });
69
+ };
70
+ </script>
71
+
72
+ <style lang="scss">
73
+ @import 'pb-variables';
74
+ @import '../styles/global.scss';
75
+ @import 'components/_c.card';
76
+
77
+ .m-pb-alert {
78
+ width: 719px;
79
+ margin: $mu200 auto 0 auto;
80
+
81
+ &__buttons {
82
+ display: flex;
83
+ align-items: flex-end;
84
+ justify-content: flex-end;
85
+ margin: $mu250 0 0 0;
86
+
87
+ button {
88
+ margin-left: 0 !important;
89
+ }
90
+
91
+ &__button {
92
+ width: 50%;
93
+
94
+ &:first-child {
95
+ justify-content: flex-start;
96
+ }
97
+
98
+ &:last-child {
99
+ justify-content: flex-end;
100
+ }
101
+ }
102
+ }
103
+
104
+ &__title {
105
+ @include set-font-scale('07', 'm');
106
+ @include set-font-face('semi-bold');
107
+
108
+ margin: 0 0 $mu150 0;
109
+ }
110
+
111
+ &__exit-options {
112
+ &__title {
113
+ @include set-font-scale('06', 'm');
114
+ @include set-font-face('semi-bold');
115
+
116
+ margin: $mu150 0;
117
+ }
118
+
119
+ &__content {
120
+ &__card {
121
+ max-width: 50%;
122
+ width: 50%;
123
+
124
+ &:first-child {
125
+ margin-right: $mu050;
126
+ }
127
+
128
+ &:last-child {
129
+ margin-left: $mu050;
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+ </style>
@@ -0,0 +1,38 @@
1
+ {
2
+ "viewModel": {
3
+ "title": "Voulez-vous télécharger vos plans plus tard ?",
4
+ "type": "warning",
5
+ "exitOptionsTitle": "Réaliser rapidement votre plan :",
6
+ "exitOptions": [
7
+ {
8
+ "code": "CARD-1",
9
+ "viewModel": {
10
+ "url": "https://www.leroymerlin.fr/produits/cuisine/cuisine-equipee-delinia-id/",
11
+ "image": "https://storage.googleapis.com/project-booster-media/kitchen/kitchen-range.jpeg",
12
+ "title": "Découvrir nos gammes de cuisines",
13
+ "subtitle": "Découvrir nos gammes de cuisines"
14
+ }
15
+ },
16
+ {
17
+ "code": "CARD-2",
18
+ "viewModel": {
19
+ "url": "https://www.leroymerlin.fr/produits/cuisine/cuisine-equipee-delinia-id/",
20
+ "image": "https://storage.googleapis.com/project-booster-media/kitchen/kitchen-range.jpeg",
21
+ "title": "Découvrir nos gammes de cuisines",
22
+ "subtitle": "Découvrir nos gammes de cuisines"
23
+ }
24
+ }
25
+ ]
26
+ },
27
+ "callToActions": [
28
+ {
29
+ "label": "Précédent",
30
+ "nextStep": "Code",
31
+ "theme": "bordered-primary-02"
32
+ },
33
+ {
34
+ "label": "Etape suivante",
35
+ "nextStep": "Code"
36
+ }
37
+ ]
38
+ }
@@ -100,13 +100,11 @@
100
100
 
101
101
  <script lang="ts">
102
102
  import { defineComponent } from 'vue';
103
- import MButton from '../../mozaic/buttons/MButton.vue';
104
- import MFlag from '../../mozaic/flag/MFlag.vue';
105
103
  import MImage from '../../mozaic/image/MImage.vue';
106
104
  import MPbCardSelectionIndicator from './decorators/MPbCardSelectionIndicator.vue';
107
105
  import MPbCardTypeIndicator from './decorators/MPbCardTypeIndicator.vue';
108
- import MLink from '../../mozaic/link/MLink.vue';
109
106
  import { sanitizeCerberusAttribut } from '@/services/sanitize';
107
+ import { MFlag, MButton, MLink } from '@mozaic-ds/vue-3';
110
108
 
111
109
  export const PB_CARD_VALIDATOR = {
112
110
  cardMinRatio: ['auto', '16x9', '3x2', '4x3', '1x1', '3x4', '2x3'],
@@ -0,0 +1,75 @@
1
+ import { Anchor, Story, Preview, Meta, Props, ArgsTable, Source, Canvas } from '@storybook/addon-docs';
2
+ import DEFAULT_PAYLOAD from './default-payload';
3
+ import WITH_TYPEFORM from './with-typeform';
4
+ import WITH_CONDITIONALS from './with-conditionals';
5
+ import WITH_SIMPLE_ACTION from './with-simple-action';
6
+ import { nestedAppDecorator } from '../../../../.storybook/nested-app-decorator';
7
+ import MPbExitOptions from './MPbExitOptions';
8
+
9
+ <Meta
10
+ title="Project Booster/Rework/Exit Options/MPbExitOptions 🦠"
11
+ component={MPbExitOptions}
12
+ argTypes={{
13
+ payload: {
14
+ table: {
15
+ defaultValue: {
16
+ summary: 'object',
17
+ detail: JSON.stringify(DEFAULT_PAYLOAD, null, ' '),
18
+ },
19
+ },
20
+ control: {
21
+ type: 'object',
22
+ },
23
+ },
24
+ }}
25
+ parameters={{
26
+ layout: 'fullscreen',
27
+ }}
28
+ />
29
+
30
+ # 🦠 `MPbExitOptions` - Component
31
+
32
+ The `MPbExitOptions` component to display information that user needed.
33
+
34
+ export const TemplateSandbox = (args, { argTypes }) => ({
35
+ props: Object.keys(argTypes),
36
+ components: { MPbExitOptions },
37
+ setup() {
38
+ return { args };
39
+ },
40
+ template: `<m-pb-exit-options
41
+ :payload="args.payload"
42
+ />`,
43
+ });
44
+
45
+ ## showCase
46
+
47
+ <Canvas>
48
+ <Story inline={false} height="862px" name="101 Sandbox" args={{ payload: DEFAULT_PAYLOAD }}>
49
+ {TemplateSandbox.bind({})}
50
+ </Story>
51
+ </Canvas>
52
+
53
+ ## With typeform
54
+
55
+ <Canvas>
56
+ <Story inline={false} height="862px" name="With typeform" args={{ payload: WITH_TYPEFORM }}>
57
+ {TemplateSandbox.bind({})}
58
+ </Story>
59
+ </Canvas>
60
+
61
+ ## With conditionals
62
+
63
+ <Canvas>
64
+ <Story inline={false} height="862px" name="With conditionals" args={{ payload: WITH_CONDITIONALS }}>
65
+ {TemplateSandbox.bind({})}
66
+ </Story>
67
+ </Canvas>
68
+
69
+ ## With simple action
70
+
71
+ <Canvas>
72
+ <Story inline={false} height="862px" name="With simple action" args={{ payload: WITH_SIMPLE_ACTION }}>
73
+ {TemplateSandbox.bind({})}
74
+ </Story>
75
+ </Canvas>
@@ -0,0 +1,181 @@
1
+ <template>
2
+ <div class="m-pb-exit-options">
3
+ <div v-if="!payload.viewModel.conditionals">
4
+ <h1 class="m-pb-exit-options__title">{{ payload.viewModel.title }}</h1>
5
+ <div class="m-pb-exit-options__content" v-html="payload.viewModel.content"></div>
6
+ </div>
7
+
8
+ <div v-for="condition in payload.viewModel.conditionals">
9
+ <div v-if="isValidCondition(condition.conditions)">
10
+ <h1 class="m-pb-exit-options__title">{{ condition.viewModel.title }}</h1>
11
+ <div class="m-pb-exit-options__content" v-html="condition.viewModel.content"></div>
12
+ </div>
13
+ </div>
14
+
15
+ <div class="m-pb-exit-options__typeform" v-if="payload.viewModel.typeForm">
16
+ <textarea
17
+ name=""
18
+ id=""
19
+ cols="30"
20
+ rows="10"
21
+ v-model="message"
22
+ :placeholder="payload.viewModel.typeForm.placeholder"
23
+ >
24
+ </textarea>
25
+ </div>
26
+
27
+ <div class="m-pb-exit-options__spacer"></div>
28
+
29
+ <div
30
+ class="m-pb-exit-options__buttons"
31
+ v-if="payload.viewModel.conditionals"
32
+ v-for="condition in payload.viewModel.conditionals"
33
+ >
34
+ <div class="m-pb-exit-options__buttons__button" v-if="isValidCondition(condition.conditions)">
35
+ <m-button
36
+ v-if="payload.viewModel.backButton.nextStep"
37
+ :label="payload.viewModel.backButton.label"
38
+ :theme="payload.viewModel.backButton.theme"
39
+ @click="callAction(payload.viewModel.backButton.nextStep)"
40
+ />
41
+ </div>
42
+
43
+ <div
44
+ v-if="isValidCondition(condition.conditions) && !payload.viewModel.nextStep"
45
+ class="m-pb-exit-options__buttons__button"
46
+ >
47
+ <m-button :label="condition.viewModel.nextStep.label" :href="condition.viewModel.nextStep.link" />
48
+ </div>
49
+ </div>
50
+
51
+ <div class="m-pb-exit-options__buttons" v-if="payload.viewModel.nextStep">
52
+ <div class="m-pb-exit-options__buttons__button">
53
+ <m-button
54
+ v-if="payload.viewModel.backButton.nextStep"
55
+ :label="payload.viewModel.backButton.label"
56
+ :theme="payload.viewModel.backButton.theme"
57
+ @click="callAction(payload.viewModel.backButton.nextStep)"
58
+ />
59
+ </div>
60
+
61
+ <div class="m-pb-exit-options__buttons__button">
62
+ <m-button :label="payload.viewModel.nextStep.label" @click="callAction(payload.viewModel.nextStep)" />
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </template>
67
+
68
+ <script lang="ts" setup>
69
+ import { MButton } from '@mozaic-ds/vue-3';
70
+ import { PropType, ref } from 'vue';
71
+ import { PayloadAction } from '../types/genericPayload';
72
+ import { areConditionsValid } from '../../../services/scenarioConditionals';
73
+ import { ScenarioStepAnswer } from '@/types/pb/Scenario';
74
+
75
+ const emit = defineEmits(['go-back', 'step-completed']);
76
+ const message = ref('');
77
+ const currentIndex = ref(0);
78
+
79
+ const props = defineProps({
80
+ /**
81
+ * The component view model and business data as an object. The provided prop
82
+ * is merged with the default payload value so only overriden values will change
83
+ * from the default ones.
84
+ */
85
+ payload: {
86
+ type: Object,
87
+ default: () => ({}),
88
+ },
89
+ /**
90
+ * The options provided at runtime to customize component behaviour
91
+ */
92
+ runtimeOptions: {
93
+ type: Object,
94
+ default: () => ({}),
95
+ },
96
+ /**
97
+ * The previous answers to inject
98
+ */
99
+ answers: {
100
+ type: Object as PropType<Map<string, ScenarioStepAnswer[]>>,
101
+ default: () => new Map<string, ScenarioStepAnswer[]>(),
102
+ },
103
+ });
104
+
105
+ /**
106
+ * Send action to completed step
107
+ * @param action
108
+ */
109
+ const callAction = (action: PayloadAction) => {
110
+ let answers: any = [];
111
+
112
+ if (message.value.length > 10) {
113
+ answers = [
114
+ {
115
+ message,
116
+ },
117
+ ];
118
+ }
119
+
120
+ emit('step-completed', {
121
+ answers,
122
+ nextStep: action,
123
+ });
124
+ };
125
+
126
+ const isValidCondition = (conditions: any) => {
127
+ return areConditionsValid(conditions!, props.answers, props.runtimeOptions);
128
+ };
129
+ </script>
130
+
131
+ <style lang="scss">
132
+ @import 'pb-variables';
133
+ @import '../styles/global.scss';
134
+
135
+ .m-pb-exit-options {
136
+ width: 754px;
137
+ margin: 4rem auto;
138
+
139
+ &__title {
140
+ @include set-font-scale('08', 'm');
141
+ @include set-font-face('semi-bold');
142
+ }
143
+
144
+ &__content {
145
+ margin-top: $mu150;
146
+ @include set-font-scale('06', 'm');
147
+ @include set-font-face('regular');
148
+ }
149
+
150
+ &__spacer {
151
+ margin-top: $mu250;
152
+ }
153
+
154
+ &__buttons {
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: stretch;
158
+
159
+ &__button {
160
+ display: flex;
161
+ width: 50%;
162
+
163
+ &:last-child {
164
+ justify-content: flex-end;
165
+ }
166
+ }
167
+ }
168
+
169
+ &__typeform {
170
+ textarea {
171
+ width: calc(100% - 20px);
172
+ height: 215px;
173
+ border-radius: 5px;
174
+ @include set-font-scale('06', 'm');
175
+ @include set-font-face('regular');
176
+
177
+ padding: 10px;
178
+ }
179
+ }
180
+ }
181
+ </style>
@@ -0,0 +1,21 @@
1
+ {
2
+ "viewModel": {
3
+ "title": "Votre projet concerne uniquement une baignoire ?",
4
+ "content": "<strong>Pour votre projet, nous vous attendons directement dans votre magasin.</strong><p>La planification de rendez-vous, est dédiée à la rénovation complète de la salle de bains</p>",
5
+ "callToActions": [
6
+ {
7
+ "label": "Précédent",
8
+ "theme": "bordered-neutral",
9
+ "nextStep": {
10
+ "code": "LMFR_BATHROOM_BATHTUB_BUDGET"
11
+ }
12
+ },
13
+ {
14
+ "label": "Etape suivante",
15
+ "nextStep": {
16
+ "code": "BATHROOM_END"
17
+ }
18
+ }
19
+ ]
20
+ }
21
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "viewModel": {
3
+ "title": "Votre projet concerne uniquement une baignoire ?",
4
+ "content": "<strong>Pour votre projet, nous vous attendons directement dans votre magasin.</strong><p>La planification de rendez-vous, est dédiée à la rénovation complète de la salle de bains</p>",
5
+ "conditionals": [
6
+ {
7
+ "conditions": ["true"],
8
+ "viewModel": {
9
+ "title": "Votre projet concerne uniquement une baignoire ?",
10
+ "content": "<strong>Pour votre projet, nous vous attendons directement dans votre magasin.</strong><p>La planification de rendez-vous, est dédiée à la rénovation complète de la salle de bains</p>",
11
+ "nextStep": {
12
+ "link": "https://www.leroymerlin.fr/produits/salle-de-bains/baignoire/",
13
+ "label": "Etape suivante"
14
+ }
15
+ }
16
+ }
17
+ ],
18
+ "backButton": {
19
+ "label": "Précédent",
20
+ "theme": "bordered-neutral",
21
+ "nextStep": {
22
+ "code": "LMFR_BATHROOM_BATHTUB_BUDGET"
23
+ }
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "viewModel": {
3
+ "title": "Votre projet concerne uniquement une baignoire ?",
4
+ "content": "<strong>Pour votre projet, nous vous attendons directement dans votre magasin.</strong><p>La planification de rendez-vous, est dédiée à la rénovation complète de la salle de bains</p>",
5
+ "nextStep": {
6
+ "code": "LMFR_BATHROOM_BATHTUB_BUDGET",
7
+ "label": "Etape suivante"
8
+ },
9
+ "backButton": {
10
+ "label": "Précédent",
11
+ "theme": "bordered-neutral",
12
+ "nextStep": {
13
+ "code": "LMFR_BATHROOM_BATHTUB_BUDGET"
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "viewModel": {
3
+ "title": "Votre projet concerne uniquement une baignoire ?",
4
+ "content": "<strong>Pour votre projet, nous vous attendons directement dans votre magasin.</strong><p>La planification de rendez-vous, est dédiée à la rénovation complète de la salle de bains</p>",
5
+ "typeForm": {
6
+ "placeholder": "Par exemple : garder un miroir que vous appréciez"
7
+ },
8
+ "callToActions": [
9
+ {
10
+ "label": "Précédent",
11
+ "theme": "bordered-neutral",
12
+ "nextStep": {
13
+ "code": "LMFR_BATHROOM_BATHTUB_BUDGET"
14
+ }
15
+ },
16
+ {
17
+ "label": "Etape suivante",
18
+ "nextStep": {
19
+ "code": "BATHROOM_END"
20
+ }
21
+ }
22
+ ]
23
+ }
24
+ }