ublo-lib 1.0.31 → 1.0.34

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 (42) hide show
  1. package/es/common/components/admin-links/admin-links.module.css +1 -1
  2. package/es/common/components/cookie-consent/cookie-consent.module.css +3 -3
  3. package/es/common/components/custom-contact-form/attachment.module.css +5 -5
  4. package/es/common/components/custom-contact-form/custom-contact-form.module.css +4 -4
  5. package/es/common/components/custom-contact-form/field.js +21 -67
  6. package/es/common/components/custom-contact-form/field.module.css +1 -1
  7. package/es/common/components/custom-contact-form/messages.js +4 -2
  8. package/es/common/components/custom-contact-form/utils.js +5 -3
  9. package/es/common/components/date-picker/calendar.module.css +2 -2
  10. package/es/common/components/date-picker/date-picker.module.css +2 -2
  11. package/es/common/components/date-picker/helper.module.css +2 -2
  12. package/es/common/components/date-picker/modes.module.css +2 -2
  13. package/es/common/components/date-picker/month.module.css +2 -2
  14. package/es/common/components/video-player/player.module.css +1 -1
  15. package/es/esf/components/booking-form/booking-form.js +79 -0
  16. package/es/esf/components/booking-form/booking-form.module.css +41 -0
  17. package/es/esf/components/booking-form/data.js +6 -0
  18. package/es/esf/components/booking-form/field.js +67 -91
  19. package/es/esf/components/booking-form/field.module.css +3 -0
  20. package/es/esf/components/booking-form/hooks/use-custom-fields.js +2 -2
  21. package/es/esf/components/booking-form/hooks/use-stay.js +9 -6
  22. package/es/esf/components/booking-form/index.js +1 -77
  23. package/es/esf/components/booking-form/lesson.js +11 -9
  24. package/es/esf/components/booking-form/lesson.module.css +46 -0
  25. package/es/esf/components/booking-form/lessons.js +13 -17
  26. package/es/esf/components/booking-form/lessons.module.css +40 -0
  27. package/es/esf/components/booking-form/personal-data.js +13 -18
  28. package/es/esf/components/booking-form/personal-data.module.css +30 -0
  29. package/es/esf/components/booking-form/progress-bar.js +6 -5
  30. package/es/esf/components/booking-form/progress-bar.module.css +55 -0
  31. package/es/esf/components/booking-form/steps.js +11 -11
  32. package/es/esf/components/booking-form/steps.module.css +4 -0
  33. package/es/esf/components/booking-form/summary.js +41 -29
  34. package/es/esf/components/booking-form/summary.module.css +54 -0
  35. package/es/esf/components/booking-form/utils.js +2 -2
  36. package/es/esf/components/loyal-customers/components/student-form.module.css +1 -1
  37. package/es/esf/components/loyal-customers/loyal-customers.module.css +1 -1
  38. package/es/lbm/components/msem-linker/editor/lodging.js +3 -3
  39. package/es/lbm/components/msem-linker/msem-linker.module.css +1 -1
  40. package/package.json +1 -1
  41. package/es/esf/components/booking-form/icons.js +0 -50
  42. package/es/esf/components/booking-form/response.js +0 -42
@@ -34,7 +34,7 @@
34
34
  display: flex;
35
35
  flex-direction: column;
36
36
  padding: 16px;
37
- color: var(--cms-grey-000, #ffffff);
37
+ color: var(--cms-grey-000, #fff);
38
38
  background: var(
39
39
  --cms-blue-gradient,
40
40
  linear-gradient(
@@ -8,8 +8,8 @@
8
8
  flex-direction: column;
9
9
  gap: 20px;
10
10
  padding: 46px 15px;
11
- color: var(--ds-grey-000, #ffffff);
12
- background-color: var(--ds-grey-700, #171e30);
11
+ color: var(--ds-grey-000, #fff);
12
+ background-color: var(--ds-grey-700, #232324);
13
13
  z-index: 20;
14
14
  overflow: auto;
15
15
  scrollbar-width: thin;
@@ -99,5 +99,5 @@
99
99
  }
100
100
 
101
101
  .buttons button:last-of-type {
102
- background-color: var(--ds-grey-600, #2d303c);
102
+ background-color: var(--ds-grey-600, #383838);
103
103
  }
@@ -24,7 +24,7 @@
24
24
  position: relative;
25
25
  min-height: 130px;
26
26
  padding: 8px 10px;
27
- color: var(--ds-grey-700, #171e30);
27
+ color: var(--ds-grey-700, #232324);
28
28
  font-size: 16px;
29
29
  font-family: inherit;
30
30
  background-color: var(--ds-grey-100, #f5f5f5);
@@ -69,14 +69,14 @@
69
69
  height: 44px;
70
70
  width: 44px;
71
71
  padding: 6px;
72
- fill: var(--ds-grey-700, #171e30);
72
+ fill: var(--ds-grey-700, #232324);
73
73
  background-color: #fff;
74
74
  border-radius: var(--ds-radius-100, 3px);
75
75
  }
76
76
 
77
77
  .itemName {
78
78
  margin-top: 6px;
79
- color: var(--ds-grey-700, #171e30);
79
+ color: var(--ds-grey-700, #232324);
80
80
  font-size: 14px;
81
81
  cursor: text;
82
82
  word-break: break-all;
@@ -111,7 +111,7 @@
111
111
  flex-direction: column;
112
112
  align-items: center;
113
113
  justify-content: center;
114
- color: var(--ds-grey-700, #171e30);
114
+ color: var(--ds-grey-700, #232324);
115
115
  font-size: 15px;
116
116
  font-style: italic;
117
117
  text-align: center;
@@ -192,7 +192,7 @@
192
192
 
193
193
  .helper {
194
194
  margin-top: 6px;
195
- color: var(--ds-grey-700, #171e30);
195
+ color: var(--ds-grey-700, #232324);
196
196
  font-size: 11px;
197
197
  text-transform: uppercase;
198
198
  letter-spacing: 1px;
@@ -7,7 +7,7 @@
7
7
  }
8
8
 
9
9
  .title {
10
- color: var(--ds-grey-700, #171e30);
10
+ color: var(--ds-grey-700, #232324);
11
11
  font-size: 18px;
12
12
  line-height: 1.2em;
13
13
  text-transform: uppercase;
@@ -47,7 +47,7 @@
47
47
 
48
48
  .message {
49
49
  font-size: 14px;
50
- color: var(--ds-grey-700, #171e30);
50
+ color: var(--ds-grey-700, #232324);
51
51
  }
52
52
 
53
53
  @media (min-width: 480px) {
@@ -88,7 +88,7 @@
88
88
  width: 30px;
89
89
  height: 30px;
90
90
  margin-bottom: 20px;
91
- fill: var(--ds-grey-700, #171e30);
91
+ fill: var(--ds-grey-700, #232324);
92
92
  animation: icon-loading-spin 1280ms
93
93
  var(--ds-transition-easing, cubic-bezier(0.4, 0, 0.2, 1)) infinite;
94
94
  }
@@ -101,7 +101,7 @@
101
101
 
102
102
  .sendingMessage {
103
103
  max-width: 420px;
104
- color: var(--ds-grey-700, #171e30);
104
+ color: var(--ds-grey-700, #232324);
105
105
  font-size: 12px;
106
106
  text-align: center;
107
107
  }
@@ -5,6 +5,7 @@ import Attachment from "./attachment";
5
5
  import Input from "dt-design-system/es/input";
6
6
  import Textarea from "dt-design-system/es/textarea";
7
7
  import Select from "dt-design-system/es/select";
8
+ import MultipleSelect from "dt-design-system/es/multiple-select";
8
9
  import Checkbox from "dt-design-system/es/checkbox";
9
10
  import NumberPicker from "dt-design-system/es/number-picker";
10
11
  import * as Fetcher from "../../utils/fetcher";
@@ -12,20 +13,22 @@ import { FIELD_TESTS_ERROR_CODES, validate } from "./utils";
12
13
  import * as Messages from "./messages";
13
14
  import styles from "./field.module.css";
14
15
  import { jsx as _jsx } from "react/jsx-runtime";
15
- import { jsxs as _jsxs } from "react/jsx-runtime";
16
16
 
17
17
  const getTag = type => {
18
- switch (true) {
19
- case type === "textarea":
18
+ switch (type) {
19
+ case "textarea":
20
20
  return Textarea;
21
21
 
22
- case type === "select":
22
+ case "multiple-select":
23
+ return MultipleSelect;
24
+
25
+ case "select":
23
26
  return Select;
24
27
 
25
- case type === "checkbox":
28
+ case "checkbox":
26
29
  return Checkbox;
27
30
 
28
- case type === "number":
31
+ case "number":
29
32
  return NumberPicker;
30
33
 
31
34
  default:
@@ -49,6 +52,15 @@ const getProps = (type, name, className, data, required, placeholder, autoSizing
49
52
  };
50
53
  }
51
54
 
55
+ if (type === "multiple-select") {
56
+ return {
57
+ onChange,
58
+ ...commonProps,
59
+ values: commonProps.value,
60
+ onBlur: undefined
61
+ };
62
+ }
63
+
52
64
  if (type === "select") {
53
65
  return {
54
66
  onValueChange: onChange,
@@ -71,29 +83,6 @@ const getProps = (type, name, className, data, required, placeholder, autoSizing
71
83
  };
72
84
  };
73
85
 
74
- const Checkboxes = ({
75
- checkboxes,
76
- data,
77
- name,
78
- onChange,
79
- disabled
80
- }) => {
81
- if (!checkboxes.length) return null;
82
- return checkboxes.map((checkbox, i) => {
83
- const {
84
- value = checkbox,
85
- label = checkbox
86
- } = checkbox;
87
- const checked = data[name].value.includes(value);
88
- return _jsx(Checkbox, {
89
- label: label,
90
- onValueChange: onChange,
91
- value: checked,
92
- disabled: disabled
93
- }, i);
94
- });
95
- };
96
-
97
86
  const getLabel = (lang, label, required) => {
98
87
  if (!required) return `${label} (${Messages.get(lang, "optionnal")})`;
99
88
  return label;
@@ -128,29 +117,10 @@ const Inner = ({
128
117
  [className]: className,
129
118
  [classes]: classes
130
119
  });
131
- const fieldsetRef = React.useRef();
132
120
  const Tag = getTag(type);
133
- const onChange = React.useCallback((value, event) => {
134
- const isAutoFilled = document.activeElement !== event?.target;
135
-
136
- if (fieldsetRef.current) {
137
- const values = Array.from(fieldsetRef.current.querySelectorAll("input")).reduce((acc, checkbox) => {
138
- const parent = checkbox.closest("label");
139
- const value = parent.textContent.trim();
140
- const {
141
- checked
142
- } = checkbox;
143
- return checked ? [...acc, value] : acc;
144
- }, []);
145
- setData(data => ({ ...data,
146
- [name]: {
147
- value: values,
148
- valid: true
149
- }
150
- }));
151
- setValid(true);
152
- return;
153
- }
121
+ const onChange = React.useCallback(eventOrValue => {
122
+ const value = eventOrValue?.target?.value || eventOrValue;
123
+ const isAutoFilled = document.activeElement !== eventOrValue?.target;
154
124
 
155
125
  if (type === "number" || isAutoFilled) {
156
126
  const isValid = validate(type, value, required);
@@ -207,22 +177,6 @@ const Inner = ({
207
177
  getSubjects();
208
178
  }
209
179
  }, [kind, name, onChange, site]);
210
-
211
- if (type === "checkbox-group") {
212
- return _jsxs("fieldset", {
213
- ref: fieldsetRef,
214
- children: [label && _jsx("legend", {
215
- children: label
216
- }), _jsx(Checkboxes, {
217
- checkboxes: options,
218
- data: data,
219
- name: name,
220
- onChange: onChange,
221
- disabled: disabled
222
- })]
223
- });
224
- }
225
-
226
180
  const fieldLabel = getLabel(lang, label, required);
227
181
  const isInputValid = required && activated && valid;
228
182
  const errorMessage = required && activated && !valid && Messages.get(lang, FIELD_TESTS_ERROR_CODES[type]);
@@ -10,7 +10,7 @@
10
10
  }
11
11
 
12
12
  .title {
13
- color: var(--ds-grey-700, #171e30);
13
+ color: var(--ds-grey-700, #232324);
14
14
  font-size: 14px;
15
15
  text-transform: uppercase;
16
16
  font-weight: 700;
@@ -33,6 +33,7 @@ const locales = {
33
33
  TESTS_PHONE_ERROR: 'Le téléphone doit être au format "0612345678" ou "+33612345678"',
34
34
  TESTS_TEXTAREA_ERROR: "Ce champ ne doit pas être vide",
35
35
  TESTS_SELECT_ERROR: "Ce champ ne doit pas être vide",
36
+ TESTS_MULTIPLE_SELECT_ERROR: "Ce champ ne doit pas être vide",
36
37
  optionnal: "optionnel"
37
38
  },
38
39
  en: {
@@ -66,8 +67,9 @@ const locales = {
66
67
  TESTS_EMAIL_ERROR: 'The email must be in the format "john.doe@domain.com"',
67
68
  TESTS_DATE_ERROR: 'The date must be in the following format: "YYYY-MM-DD"',
68
69
  TESTS_PHONE_ERROR: 'The date must be in the following formats: "0612345678" or "+33612345678"',
69
- TESTS_TEXTAREA_ERROR: "this field cannot be empty",
70
- TESTS_SELECT_ERROR: "this field cannot be empty",
70
+ TESTS_TEXTAREA_ERROR: "This field cannot be empty",
71
+ TESTS_SELECT_ERROR: "This field cannot be empty",
72
+ TESTS_MULTIPLE_SELECT_ERROR: "This field cannot be empty",
71
73
  optionnal: "optionnal"
72
74
  }
73
75
  };
@@ -13,9 +13,10 @@ export const FIELD_TESTS_ERROR_CODES = {
13
13
  email: "TESTS_EMAIL_ERROR",
14
14
  phone: "TESTS_PHONE_ERROR",
15
15
  textarea: "TESTS_TEXTAREA_ERROR",
16
- select: "TESTS_SELECT_ERROR"
16
+ select: "TESTS_SELECT_ERROR",
17
+ "multiple-select": "TESTS_MULTIPLE_SELECT_ERROR"
17
18
  };
18
- const IGNORED_FIELDS = ["title", "subject", "attachment", "checkbox", "checkbox-group"];
19
+ const IGNORED_FIELDS = ["title", "subject", "attachment", "checkbox"];
19
20
  export const getInitialFormState = (fields, presets) => Object.keys(fields).reduce((acc, key) => {
20
21
  const field = fields[key];
21
22
  const {
@@ -54,7 +55,7 @@ export const getInitialFormState = (fields, presets) => Object.keys(fields).redu
54
55
  };
55
56
  }
56
57
 
57
- if (type === "checkbox-group") {
58
+ if (type === "multiple-select") {
58
59
  const value = presets?.[key].length || [];
59
60
  return { ...acc,
60
61
  [key]: {
@@ -74,6 +75,7 @@ export const getInitialFormState = (fields, presets) => Object.keys(fields).redu
74
75
  }, {});
75
76
  export const validate = (type, value, required) => {
76
77
  if (IGNORED_FIELDS.includes(type) || !required) return true;
78
+ if (type === "multiple-select") return value.length > 0;
77
79
  if (type === "number") return value >= 0;
78
80
  if (!value) return false;
79
81
  const regex = TESTS[type];
@@ -81,7 +81,7 @@ button.submit {
81
81
  }
82
82
 
83
83
  .confirmDateChangeMessage {
84
- color: var(--ds-grey-700, #171e30);
84
+ color: var(--ds-grey-700, #232324);
85
85
  font-size: 13px;
86
86
  }
87
87
 
@@ -111,7 +111,7 @@ button.submit {
111
111
  font-weight: 700;
112
112
  text-align: center;
113
113
  text-transform: uppercase;
114
- background-color: var(--ds-grey-700, #171e30);
114
+ background-color: var(--ds-grey-700, #232324);
115
115
  border: 0;
116
116
  border-radius: var(--ds-radius-100, 3px);
117
117
  cursor: pointer;
@@ -57,7 +57,7 @@ div.popup {
57
57
  }
58
58
 
59
59
  .specialRuleTitle {
60
- color: var(--ds-grey-700, #171e30);
60
+ color: var(--ds-grey-700, #232324);
61
61
  font-size: 13px;
62
62
  font-weight: 700;
63
63
  }
@@ -75,7 +75,7 @@ div.popup {
75
75
  }
76
76
 
77
77
  .specialRuleMessage {
78
- color: var(--ds-grey-700, #171e30);
78
+ color: var(--ds-grey-700, #232324);
79
79
  font-size: 13px;
80
80
  }
81
81
 
@@ -30,7 +30,7 @@
30
30
  align-items: center;
31
31
  justify-content: center;
32
32
  padding: 10px;
33
- color: var(--ds-grey-600, #2d303c);
33
+ color: var(--ds-grey-600, #383838);
34
34
  font-size: 14px;
35
35
  text-transform: uppercase;
36
36
  border-radius: var(--ds-radius-100, 3px);
@@ -77,5 +77,5 @@
77
77
  .helperRemove > svg {
78
78
  width: 18px;
79
79
  height: 18px;
80
- fill: var(--ds-grey-700, #171e30);
80
+ fill: var(--ds-grey-700, #232324);
81
81
  }
@@ -22,7 +22,7 @@
22
22
  align-items: center;
23
23
  text-align: left;
24
24
  padding: 20px 35px 20px 25px;
25
- color: var(--ds-grey-600, #2d303c);
25
+ color: var(--ds-grey-600, #383838);
26
26
  font-size: 16px;
27
27
  background-color: var(--ds-grey-100, #f5f5f5);
28
28
  border-radius: var(--ds-radius-100, 3px);
@@ -79,7 +79,7 @@
79
79
  }
80
80
 
81
81
  .inner > span {
82
- color: var(--ds-grey-600, #2d303c);
82
+ color: var(--ds-grey-600, #383838);
83
83
  font-size: 19px;
84
84
  white-space: nowrap;
85
85
  font-weight: 700;
@@ -5,7 +5,7 @@
5
5
 
6
6
  .title {
7
7
  margin-bottom: 10px;
8
- color: var(--ds-grey-600, #2d303c);
8
+ color: var(--ds-grey-600, #383838);
9
9
  font-size: 15px;
10
10
  font-weight: 700;
11
11
  text-transform: uppercase;
@@ -28,7 +28,7 @@
28
28
  }
29
29
 
30
30
  .day {
31
- color: var(--ds-grey-400, #d2d2d2);
31
+ color: var(--ds-grey-400, #bbbbbb);
32
32
  font-size: 11px;
33
33
  text-align: center;
34
34
  font-weight: 700;
@@ -1,5 +1,5 @@
1
1
  .player {
2
- --vp-default-grey-000: #ffffff;
2
+ --vp-default-grey-000: #fff;
3
3
  --vp-default-grey-300: #bebebe;
4
4
  --vp-default-grey-500: #5e5e5e;
5
5
 
@@ -0,0 +1,79 @@
1
+ import * as React from "react";
2
+ import { SnackbarProvider } from "dt-design-system/es/snackbar";
3
+ import ProgressBar from "./progress-bar";
4
+ import Steps from "./steps";
5
+ import useCustomFields from "./hooks/use-custom-fields";
6
+ import { FIELDS, STEPS } from "./data";
7
+ import css from "./booking-form.module.css";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsxs as _jsxs } from "react/jsx-runtime";
10
+
11
+ const BookingFormWithSnackbar = props => {
12
+ return _jsx(SnackbarProvider, {
13
+ children: _jsx(BookingForm, { ...props
14
+ })
15
+ });
16
+ };
17
+
18
+ const BookingForm = ({
19
+ lang,
20
+ resort,
21
+ channel = "ESF",
22
+ merchant,
23
+ integration = false,
24
+ uat = false,
25
+ noInitialScroll
26
+ }) => {
27
+ const ref = React.useRef();
28
+ const [fields, setFields] = React.useState(FIELDS);
29
+ const [step, setStep] = React.useState(STEPS.LESSONS);
30
+ const [lessons, setLessons] = React.useState([]);
31
+ const [personalData, setPersonalData] = React.useState({});
32
+
33
+ const _lang = lang === "fr" ? "fr" : "en";
34
+
35
+ const clearForm = () => {
36
+ setStep(STEPS.LESSONS);
37
+ setLessons([]);
38
+ setPersonalData({});
39
+ };
40
+
41
+ React.useEffect(() => {
42
+ const bookinForm = ref.current;
43
+ if (noInitialScroll || !bookinForm) return;
44
+ bookinForm.scrollIntoView(true);
45
+ }, [noInitialScroll, step]);
46
+ useCustomFields(FIELDS, setFields);
47
+ return _jsxs("div", {
48
+ className: css.root,
49
+ children: [_jsx("div", {
50
+ ref: ref,
51
+ className: css.anchor
52
+ }), _jsxs("div", {
53
+ className: css.inner,
54
+ children: [_jsx(ProgressBar, {
55
+ lang: _lang,
56
+ step: step
57
+ }), _jsx(Steps, {
58
+ lang: lang,
59
+ step: step,
60
+ setStep: setStep,
61
+ fields: fields,
62
+ lessons: lessons,
63
+ setLessons: setLessons,
64
+ personalData: personalData,
65
+ setPersonalData: setPersonalData,
66
+ clearForm: clearForm,
67
+ config: {
68
+ channel,
69
+ resort,
70
+ merchant,
71
+ integration,
72
+ uat
73
+ }
74
+ })]
75
+ })]
76
+ });
77
+ };
78
+
79
+ export default BookingFormWithSnackbar;
@@ -0,0 +1,41 @@
1
+ .root {
2
+ position: relative;
3
+ width: 100%;
4
+ }
5
+
6
+ .root hr {
7
+ width: 100%;
8
+ height: 2px;
9
+ display: block;
10
+ background-color: var(--ds-grey-100, #f5f5f5);
11
+ border: 0;
12
+ border-radius: 2px;
13
+ }
14
+
15
+ .anchor {
16
+ position: absolute;
17
+ bottom: 0;
18
+ left: 0;
19
+ height: calc(100% + 180px);
20
+ width: 100%;
21
+ pointer-events: none;
22
+ touch-action: none;
23
+ }
24
+
25
+ .inner {
26
+ width: 800px;
27
+ max-width: 100%;
28
+ display: flex;
29
+ flex-direction: column;
30
+ gap: 46px;
31
+ margin: 30px auto;
32
+ padding: 25px 10px;
33
+ background-color: var(--ds-grey-000, #ffffff);
34
+ border-radius: var(--ds-radius-100, 6px);
35
+ }
36
+
37
+ @media (min-width: 580px) {
38
+ .inner {
39
+ padding: 25px;
40
+ }
41
+ }
@@ -136,6 +136,7 @@ const data = {
136
136
  required: true
137
137
  },
138
138
  lastName: {
139
+ icon: "User",
139
140
  type: "text",
140
141
  label: {
141
142
  fr: "Nom",
@@ -144,6 +145,7 @@ const data = {
144
145
  required: true
145
146
  },
146
147
  firstName: {
148
+ icon: "User",
147
149
  type: "text",
148
150
  label: {
149
151
  fr: "Prénom",
@@ -152,6 +154,7 @@ const data = {
152
154
  required: true
153
155
  },
154
156
  email: {
157
+ icon: "AtSign",
155
158
  type: "email",
156
159
  label: {
157
160
  fr: "Email",
@@ -160,6 +163,7 @@ const data = {
160
163
  required: true
161
164
  },
162
165
  phone: {
166
+ icon: "Smartphone",
163
167
  type: "phone",
164
168
  label: {
165
169
  fr: "Téléphone",
@@ -168,6 +172,7 @@ const data = {
168
172
  required: true
169
173
  },
170
174
  paymentMethod: {
175
+ icon: "CreditCard",
171
176
  type: "select",
172
177
  label: {
173
178
  fr: "Moyen de paiment",
@@ -185,6 +190,7 @@ const data = {
185
190
  fr: "Commentaire",
186
191
  en: "Comment"
187
192
  },
193
+ fullWidth: true,
188
194
  required: false
189
195
  }
190
196
  };