thm-p3-configurator 0.0.37 → 0.0.39

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.
@@ -69,7 +69,7 @@ const App = () => {
69
69
  (0, _Experiments.default)();
70
70
  });
71
71
  return /*#__PURE__*/_react.default.createElement(_SentryWrapper.default, null, /*#__PURE__*/_react.default.createElement(_FormulaContext.FormulaController, {
72
- defaultFormula: _constants__.CONFIGURATOR_FORMULAS.THM
72
+ defaultFormula: _constants__.CONFIGURATOR_FORMULAS.THC
73
73
  }, /*#__PURE__*/_react.default.createElement(_CountryContext.CountryController, {
74
74
  defaultCountry: APP_CONFIG.country
75
75
  }, /*#__PURE__*/_react.default.createElement(_OrderSessionContext.OrderSessionController, null, /*#__PURE__*/_react.default.createElement(_reactQuery.QueryClientProvider, {
@@ -57,6 +57,9 @@ const CheckboxInput = _ref => {
57
57
  setChecked(!isChecked);
58
58
  onChange(!isChecked);
59
59
  };
60
+ (0, _react.useEffect)(() => {
61
+ setChecked(initialValue);
62
+ }, [initialValue]);
60
63
  return /*#__PURE__*/_react.default.createElement("div", {
61
64
  className: (0, _helpers__.withStyle)('form-group')
62
65
  }, /*#__PURE__*/_react.default.createElement("div", {
@@ -66,6 +69,7 @@ const CheckboxInput = _ref => {
66
69
  id: name,
67
70
  name: name,
68
71
  form: form,
72
+ checked: isChecked,
69
73
  required: isRequired,
70
74
  className: "".concat((0, _helpers__.withStyle)('form-check-input'), " ").concat(errorMessage ? (0, _helpers__.withStyle)('is-invalid') : ''),
71
75
  onChange: e => {
@@ -16,6 +16,7 @@ const ErrorMessage = _ref => {
16
16
  message
17
17
  } = _ref;
18
18
  return /*#__PURE__*/_react.default.createElement("div", {
19
+ name: 'error-message',
19
20
  className: (0, _helpers__.withStyle)('text-danger small')
20
21
  }, message);
21
22
  };
@@ -333,7 +333,7 @@ const AppointmentForm = () => {
333
333
  }), /*#__PURE__*/_react.default.createElement(_PrimaryButton.default, {
334
334
  onClick: handleSubmit,
335
335
  isDisabled: isCreatingAppointmentRequest,
336
- label: 'Afspraak maken'
336
+ label: 'Afspraak maaken'
337
337
  }))));
338
338
  };
339
339
  var _default = exports.default = AppointmentForm;
@@ -25,7 +25,6 @@ var _react = _interopRequireWildcard(require("react"));
25
25
  var _reactRouter = require("react-router");
26
26
  var _yup = require("yup");
27
27
  var _mutations = require("../__api__/mutations");
28
- var _queries = require("../__api__/queries");
29
28
  var _LinkButton = _interopRequireDefault(require("../__components__/Buttons/LinkButton"));
30
29
  var _PrimaryButton = _interopRequireDefault(require("../__components__/Buttons/PrimaryButton"));
31
30
  var _Card = _interopRequireDefault(require("../__components__/Cards/Card"));
@@ -138,18 +137,9 @@ const ExitIntentModal = () => {
138
137
  selectedDiscountedProducts = []
139
138
  }, dispatch] = (0, _OrderSessionContext.useOrderSession)();
140
139
  const formula = (0, _FormulaContext.useFormula)();
141
- const {
142
- vehicleDetails
143
- } = (0, _queries.useProductsQuery)({
144
- licensePlate,
145
- model,
146
- executionAnswer1,
147
- executionAnswer2,
148
- durationAnswer: durationAnswer,
149
- formula,
150
- discountCode,
151
- priceCalculationDate
152
- });
140
+ (0, _react.useEffect)(() => {
141
+ (0, _ui.scrollToFirstErrorMessage)();
142
+ }, [errors]);
153
143
  const handleMouseLeave = event => {
154
144
  if (document.cookie.includes('exitIntentModalShown=true')) {
155
145
  return;
@@ -58,11 +58,7 @@ function _interopRequireWildcard(e, r) {
58
58
  const ManualSelectionForm = _ref => {
59
59
  let {
60
60
  onSubmit,
61
- initialValues = {
62
- brand: null,
63
- model: null,
64
- buildYear: null
65
- }
61
+ initialValues = null
66
62
  } = _ref;
67
63
  const [{
68
64
  brand,
@@ -104,15 +100,17 @@ const ManualSelectionForm = _ref => {
104
100
  );
105
101
  };
106
102
  (0, _react.useEffect)(() => {
107
- handleBrandChange({
108
- value: initialValues.brand
109
- });
110
- handleBuildYearChange({
111
- value: initialValues.buildYear
112
- });
113
- handleModelChange({
114
- value: initialValues.model
115
- });
103
+ if (initialValues) {
104
+ handleBrandChange({
105
+ value: initialValues.brand
106
+ });
107
+ handleBuildYearChange({
108
+ value: initialValues.buildYear
109
+ });
110
+ handleModelChange({
111
+ value: initialValues.model
112
+ });
113
+ }
116
114
  }, [initialValues]);
117
115
  const handleBrandChange = brandOption => {
118
116
  dispatch({
@@ -203,7 +203,7 @@ const ProductsOverview = () => {
203
203
  key: product.articleNumber,
204
204
  id: product.articleNumber,
205
205
  description: (0, _product.formatHyperDescription)(product === null || product === void 0 ? void 0 : product.description),
206
- title: product === null || product === void 0 ? void 0 : product.title,
206
+ title: product === null || product === void 0 ? void 0 : product.subgroupName,
207
207
  price: product === null || product === void 0 ? void 0 : product.price
208
208
  });
209
209
  }
@@ -212,7 +212,7 @@ const ProductsOverview = () => {
212
212
  hasCheckbox: (productsPerCategory === null || productsPerCategory === void 0 ? void 0 : productsPerCategory.length) > 1,
213
213
  isRecommended: isRecommended,
214
214
  productId: product === null || product === void 0 ? void 0 : product.articleNumber,
215
- productTitle: product === null || product === void 0 ? void 0 : product.title,
215
+ productTitle: product === null || product === void 0 ? void 0 : product.subgroupName,
216
216
  productDescription: product === null || product === void 0 ? void 0 : product.productDescription,
217
217
  productUsps: [{
218
218
  type: 'excl',
@@ -20,7 +20,6 @@ var _react = _interopRequireWildcard(require("react"));
20
20
  var _reactRouter = require("react-router");
21
21
  var _yup = require("yup");
22
22
  var _mutations = require("../__api__/mutations");
23
- var _queries = require("../__api__/queries");
24
23
  var _NavigationButton = _interopRequireDefault(require("../__components__/Buttons/NavigationButton"));
25
24
  var _PrimaryButton = _interopRequireDefault(require("../__components__/Buttons/PrimaryButton"));
26
25
  var _Card = _interopRequireDefault(require("../__components__/Cards/Card"));
@@ -32,6 +31,7 @@ var _FormulaContext = require("../__context__/FormulaContext");
32
31
  var _OrderSessionContext = require("../__context__/OrderSessionContext");
33
32
  var _helpers__ = require("../__helpers__");
34
33
  var _product = require("../__helpers__/product");
34
+ var _ui = require("../__helpers__/ui");
35
35
  function _interopRequireDefault(e) {
36
36
  return e && e.__esModule ? e : {
37
37
  default: e
@@ -138,18 +138,9 @@ const QuotationForm = () => {
138
138
  isCreatingQuotation
139
139
  } = (0, _mutations.useCreateQuotationMutation)();
140
140
  const formula = (0, _FormulaContext.useFormula)();
141
- const {
142
- vehicleDetails,
143
- vehicleLogo
144
- } = (0, _queries.useProductsQuery)({
145
- licensePlate,
146
- model,
147
- executionAnswer1,
148
- executionAnswer2,
149
- durationAnswer: durationAnswer,
150
- formula,
151
- discountCode
152
- });
141
+ (0, _react.useEffect)(() => {
142
+ (0, _ui.scrollToFirstErrorMessage)();
143
+ }, [errors]);
153
144
  const handleSubmit = async () => {
154
145
  try {
155
146
  setErrors(null);
@@ -32,6 +32,7 @@ var _LinkButton = _interopRequireDefault(require("../../__components__/Buttons/L
32
32
  var _NavigationButton = _interopRequireDefault(require("../../__components__/Buttons/NavigationButton"));
33
33
  var _PrimaryButton = _interopRequireDefault(require("../../__components__/Buttons/PrimaryButton"));
34
34
  var _CardWide = _interopRequireDefault(require("../../__components__/Cards/CardWide"));
35
+ var _CheckboxInput = _interopRequireDefault(require("../../__components__/Form/CheckboxInput"));
35
36
  var _DatePickerInput = _interopRequireDefault(require("../../__components__/Form/DatePickerInput"));
36
37
  var _DropdownInput = _interopRequireDefault(require("../../__components__/Form/DropdownInput"));
37
38
  var _ErrorMessage = _interopRequireDefault(require("../../__components__/Form/ErrorMessage"));
@@ -44,6 +45,7 @@ var _FormulaContext = require("../../__context__/FormulaContext");
44
45
  var _OrderSessionContext = require("../../__context__/OrderSessionContext");
45
46
  var _helpers__ = require("../../__helpers__");
46
47
  var _product = require("../../__helpers__/product");
48
+ var _ui = require("../../__helpers__/ui");
47
49
  var _LicensePlateValidator = _interopRequireDefault(require("../../__services__/LicensePlateValidator"));
48
50
  var _LocalStorageWorker = require("../../__services__/LocalStorageWorker");
49
51
  var _InternalAppointmentSuccessModal = _interopRequireDefault(require("./InternalAppointmentSuccessModal"));
@@ -136,8 +138,13 @@ const internalAppointmentFormSchema = (0, _yup.object)({
136
138
  streetName: (0, _yup.string)().required(_constants__.FORM_ERROR_MESSAGES.required),
137
139
  city: (0, _yup.string)().required(_constants__.FORM_ERROR_MESSAGES.required),
138
140
  date: (0, _yup.string)().required(_constants__.FORM_ERROR_MESSAGES.required),
139
- time: (0, _yup.string)().required(_constants__.FORM_ERROR_MESSAGES.required)
141
+ time: (0, _yup.string)().required(_constants__.FORM_ERROR_MESSAGES.required),
142
+ customerAgreed: (0, _yup.boolean)().required(_constants__.FORM_ERROR_MESSAGES.required).isTrue(_constants__.FORM_ERROR_MESSAGES.required)
140
143
  });
144
+
145
+ /**
146
+ * TODO: Split this component - file is too long at the moment.
147
+ */
141
148
  const InternalAppointmentForm = _ref => {
142
149
  var _branchTypes$byId$aut, _authSession$branch;
143
150
  let {
@@ -147,6 +154,7 @@ const InternalAppointmentForm = _ref => {
147
154
  isLoading = false
148
155
  } = _ref;
149
156
  const [{
157
+ customerAgreed,
150
158
  customer,
151
159
  licensePlate,
152
160
  model,
@@ -183,8 +191,11 @@ const InternalAppointmentForm = _ref => {
183
191
  } = (0, _queries.useBranchByIdOrWidgetId)(selectedBranch);
184
192
  const history = (0, _reactRouter.useHistory)();
185
193
  const formula = (0, _FormulaContext.useFormula)();
194
+ (0, _react.useEffect)(() => {
195
+ (0, _ui.scrollToFirstErrorMessage)();
196
+ }, [errors]);
186
197
  const {
187
- vehicleDetails
198
+ products
188
199
  } = (0, _queries.useProductsQuery)({
189
200
  licensePlate,
190
201
  model,
@@ -192,9 +203,12 @@ const InternalAppointmentForm = _ref => {
192
203
  executionAnswer2,
193
204
  durationAnswer: durationAnswer,
194
205
  formula,
195
- discountCode,
196
- priceCalculationDate
206
+ priceCalculationDate,
207
+ discountCode
197
208
  });
209
+ const productSpecifications = (0, _react.useMemo)(() => {
210
+ return (0, _product.parseProductSpecifications)([products[_constants__.PRODUCT_CATEGORIES.TOWBAR].find(towbar => towbar.articleNumber === selectedTowbar), products[_constants__.PRODUCT_CATEGORIES.CABLESET].find(cableset => cableset.articleNumber === selectedCableset), products[_constants__.PRODUCT_CATEGORIES.COMBISET].find(combiset => combiset.articleNumber === selectedCombiset)]);
211
+ }, [products]);
198
212
 
199
213
  /**
200
214
  * @description Handles the validation of the license plate, if the session has not been started with a license plate
@@ -211,7 +225,7 @@ const InternalAppointmentForm = _ref => {
211
225
  const handleSubmit = async () => {
212
226
  try {
213
227
  var _ref2;
214
- setErrors(null);
228
+ setErrors([]);
215
229
 
216
230
  // Note: this does not throw on error.
217
231
  const licensePlateErrors = validateLicensePlate();
@@ -223,9 +237,15 @@ const InternalAppointmentForm = _ref => {
223
237
  }
224
238
 
225
239
  // Note: this throws on error.
226
- internalAppointmentFormSchema.validateSync(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, vehicle), customer), appointment), {}, {
227
- channelType: channel === null || channel === void 0 ? void 0 : channel.channelType,
228
- channelId: channel === null || channel === void 0 ? void 0 : channel.channelId
240
+ internalAppointmentFormSchema.validateSync(_objectSpread(_objectSpread(_objectSpread({}, vehicle), customer), {}, {
241
+ // Note: add string fallback here to prevent null check in Yup throwing weird errors
242
+ // However: dont submit empty strings to the API because the API doesnt accept empty strings in place of `undefined`
243
+ // Rule in custom API: a field can be optional (can be undefined), but once you fill it in with a value, that value has to be truthy.
244
+ date: (appointment === null || appointment === void 0 ? void 0 : appointment.date) || '',
245
+ time: (appointment === null || appointment === void 0 ? void 0 : appointment.time) || '',
246
+ channelType: (channel === null || channel === void 0 ? void 0 : channel.channelType) || '',
247
+ channelId: (channel === null || channel === void 0 ? void 0 : channel.channelId) || '',
248
+ customerAgreed: productSpecifications !== null && productSpecifications !== void 0 && productSpecifications.length ? customerAgreed : true // Note: this skips validation if no productSpecifications are found
229
249
  }), {
230
250
  strict: false,
231
251
  abortEarly: false
@@ -336,7 +356,7 @@ const InternalAppointmentForm = _ref => {
336
356
  onClick: handleAutofillButtonClicked,
337
357
  isDisabled: !branchById
338
358
  })), /*#__PURE__*/_react.default.createElement("div", {
339
- className: (0, _helpers__.withStyle)('col-12 mb-2')
359
+ className: (0, _helpers__.withStyle)('col-12 col-md-6 mb-2')
340
360
  }, /*#__PURE__*/_react.default.createElement(_DropdownInput.default, {
341
361
  options: marketingChannels === null || marketingChannels === void 0 ? void 0 : marketingChannels.map(channel => ({
342
362
  label: channel === null || channel === void 0 ? void 0 : channel.title,
@@ -372,37 +392,6 @@ const InternalAppointmentForm = _ref => {
372
392
  }
373
393
  });
374
394
  }
375
- }), /*#__PURE__*/_react.default.createElement(_RadioButtons.default, {
376
- name: "ownershipType",
377
- label: "Type:",
378
- initialValue: vehicle === null || vehicle === void 0 ? void 0 : vehicle.ownershipType,
379
- onChange: val => {
380
- dispatch({
381
- type: _OrderSessionContext.orderSessionActions.SET_VEHICLE_OWNERSHIP_TYPE,
382
- payload: {
383
- ownershipType: val
384
- }
385
- });
386
- },
387
- options: Object.values(_constants__.VEHICLE_OWNERSHIP_TYPE),
388
- isRequired: true,
389
- errorMessage: errors === null || errors === void 0 ? void 0 : errors['ownershipType']
390
- })), /*#__PURE__*/_react.default.createElement("div", {
391
- className: (0, _helpers__.withStyle)('col-12 col-md-6')
392
- }, (vehicle === null || vehicle === void 0 ? void 0 : vehicle.ownershipType) === _constants__.VEHICLE_OWNERSHIP_TYPE.Leasemaatschappij && /*#__PURE__*/_react.default.createElement(_TextInput.default, {
393
- placeholder: "",
394
- initialValue: vehicle === null || vehicle === void 0 ? void 0 : vehicle.leaseNumber,
395
- name: "leaseNumber",
396
- onChange: value => dispatch({
397
- type: _OrderSessionContext.orderSessionActions.SET_VEHICLE_LEASE_NUMBER,
398
- payload: {
399
- leaseNumber: value
400
- }
401
- }),
402
- isRequired: false,
403
- form: "quotation",
404
- label: "Code van de leasemaatschappij:",
405
- errorMessage: errors === null || errors === void 0 ? void 0 : errors['leaseNumber']
406
395
  }), /*#__PURE__*/_react.default.createElement(_TextInput.default, {
407
396
  placeholder: "",
408
397
  initialValue: customer.firstName,
@@ -526,16 +515,73 @@ const InternalAppointmentForm = _ref => {
526
515
  isRequired: true,
527
516
  label: "Stad:",
528
517
  errorMessage: errors === null || errors === void 0 ? void 0 : errors['city']
518
+ }))))), /*#__PURE__*/_react.default.createElement("div", {
519
+ className: (0, _helpers__.withStyle)('col-12 mb-4')
520
+ }, /*#__PURE__*/_react.default.createElement(_CardWide.default, null, /*#__PURE__*/_react.default.createElement("div", {
521
+ className: (0, _helpers__.withStyle)('row')
522
+ }, /*#__PURE__*/_react.default.createElement("h6", {
523
+ className: (0, _helpers__.withStyle)('modal-title col-12 mb-2')
524
+ }, "Gegevens van de klant ", /*#__PURE__*/_react.default.createElement("br", null)), /*#__PURE__*/_react.default.createElement("div", {
525
+ className: (0, _helpers__.withStyle)('col-12 mb-2')
526
+ }, /*#__PURE__*/_react.default.createElement(_RadioButtons.default, {
527
+ name: "ownershipType",
528
+ label: "Type:",
529
+ initialValue: vehicle === null || vehicle === void 0 ? void 0 : vehicle.ownershipType,
530
+ onChange: val => {
531
+ dispatch({
532
+ type: _OrderSessionContext.orderSessionActions.SET_VEHICLE_OWNERSHIP_TYPE,
533
+ payload: {
534
+ ownershipType: val
535
+ }
536
+ });
537
+ },
538
+ options: Object.values(_constants__.VEHICLE_OWNERSHIP_TYPE),
539
+ isRequired: true,
540
+ errorMessage: errors === null || errors === void 0 ? void 0 : errors['ownershipType']
541
+ })), /*#__PURE__*/_react.default.createElement("div", {
542
+ className: (0, _helpers__.withStyle)('col-12')
543
+ }, (vehicle === null || vehicle === void 0 ? void 0 : vehicle.ownershipType) === _constants__.VEHICLE_OWNERSHIP_TYPE.Leasemaatschappij && /*#__PURE__*/_react.default.createElement(_TextInput.default, {
544
+ placeholder: "",
545
+ initialValue: vehicle === null || vehicle === void 0 ? void 0 : vehicle.leaseNumber,
546
+ name: "leaseNumber",
547
+ onChange: value => dispatch({
548
+ type: _OrderSessionContext.orderSessionActions.SET_VEHICLE_LEASE_NUMBER,
549
+ payload: {
550
+ leaseNumber: value
551
+ }
552
+ }),
553
+ isRequired: false,
554
+ form: "quotation",
555
+ label: "Code van de leasemaatschappij:",
556
+ errorMessage: errors === null || errors === void 0 ? void 0 : errors['leaseNumber']
529
557
  }), !licensePlate && /*#__PURE__*/_react.default.createElement(_TextInput.default, {
530
558
  placeholder: "",
531
559
  initialValue: _licensePlate,
532
560
  name: "licensePlate",
533
561
  onChange: value => _setLicensePlate(value),
534
- isRequired: true,
562
+ isRequired: false,
535
563
  form: "quotation",
536
564
  label: "Kenteken:",
537
565
  errorMessage: errors === null || errors === void 0 ? void 0 : errors['licensePlate']
538
- }))))), /*#__PURE__*/_react.default.createElement("div", {
566
+ }), /*#__PURE__*/_react.default.createElement("div", {
567
+ className: (0, _helpers__.withStyle)('my-2 fw-bold')
568
+ }, "Opties aanwezig:"), productSpecifications !== null && productSpecifications !== void 0 && productSpecifications.length ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ' ', /*#__PURE__*/_react.default.createElement("ul", null, productSpecifications === null || productSpecifications === void 0 ? void 0 : productSpecifications.map(specification => /*#__PURE__*/_react.default.createElement("li", {
569
+ key: specification
570
+ }, specification))), /*#__PURE__*/_react.default.createElement(_CheckboxInput.default, {
571
+ isRequired: true,
572
+ name: 'customerAgreed',
573
+ initialValue: customerAgreed,
574
+ onChange: value => dispatch({
575
+ type: _OrderSessionContext.orderSessionActions.SET_CUSTOMER_AGREED,
576
+ payload: {
577
+ customerAgreed: value
578
+ }
579
+ }),
580
+ errorMessage: errors === null || errors === void 0 ? void 0 : errors['customerAgreed'],
581
+ label: /*#__PURE__*/_react.default.createElement("strong", null, "Klant gaat akkoord met bovenstaande")
582
+ })) : /*#__PURE__*/_react.default.createElement("div", {
583
+ className: (0, _helpers__.withStyle)('text-muted my-2')
584
+ }, "Geen opties gevonden..."))), ' ')), /*#__PURE__*/_react.default.createElement("div", {
539
585
  className: (0, _helpers__.withStyle)('col-12')
540
586
  }, /*#__PURE__*/_react.default.createElement(_CardWide.default, null, /*#__PURE__*/_react.default.createElement("div", {
541
587
  className: (0, _helpers__.withStyle)('row')
@@ -573,10 +619,10 @@ const InternalAppointmentForm = _ref => {
573
619
  className: (0, _helpers__.withStyle)('col-12 col-md-6')
574
620
  }, /*#__PURE__*/_react.default.createElement(_TextAreaInput.default, {
575
621
  placeholder: "",
576
- initialValue: appointment === null || appointment === void 0 ? void 0 : appointment.note,
622
+ initialValue: customer === null || customer === void 0 ? void 0 : customer.note,
577
623
  name: "note",
578
624
  onChange: value => dispatch({
579
- type: _OrderSessionContext.orderSessionActions.SET_APPOINTMENT_NOTE,
625
+ type: _OrderSessionContext.orderSessionActions.SET_CUSTOMER_NOTE,
580
626
  payload: {
581
627
  note: value
582
628
  }
@@ -601,7 +647,7 @@ const InternalAppointmentForm = _ref => {
601
647
  }), /*#__PURE__*/_react.default.createElement(_PrimaryButton.default, {
602
648
  onClick: handleSubmit,
603
649
  isDisabled: isLoading,
604
- label: 'Afspraak maken'
650
+ label: 'Afspraak maaken'
605
651
  }))), /*#__PURE__*/_react.default.createElement(_InternalAppointmentSuccessModal.default, {
606
652
  isOpen: isSuccess
607
653
  }));
@@ -39,6 +39,7 @@ var _FormulaContext = require("../../__context__/FormulaContext");
39
39
  var _OrderSessionContext = require("../../__context__/OrderSessionContext");
40
40
  var _helpers__ = require("../../__helpers__");
41
41
  var _product = require("../../__helpers__/product");
42
+ var _ui = require("../../__helpers__/ui");
42
43
  var _LicensePlateValidator = _interopRequireDefault(require("../../__services__/LicensePlateValidator"));
43
44
  var _LocalStorageWorker = require("../../__services__/LocalStorageWorker");
44
45
  var _InternalQuotationSuccessModal = _interopRequireDefault(require("./InternalQuotationSuccessModal"));
@@ -167,18 +168,9 @@ const InternalQuotationForm = _ref => {
167
168
  isLoadingMarketingChannels
168
169
  } = (0, _queries.useMarketingChannels)(branchType);
169
170
  const formula = (0, _FormulaContext.useFormula)();
170
- const {
171
- vehicleDetails
172
- } = (0, _queries.useProductsQuery)({
173
- licensePlate,
174
- model,
175
- executionAnswer1,
176
- executionAnswer2,
177
- durationAnswer: durationAnswer,
178
- formula,
179
- discountCode,
180
- priceCalculationDate
181
- });
171
+ (0, _react.useEffect)(() => {
172
+ (0, _ui.scrollToFirstErrorMessage)();
173
+ }, [errors]);
182
174
 
183
175
  /**
184
176
  * @description Handles the validation of the license plate, if the session has not been started with a license plate
@@ -211,8 +203,11 @@ const InternalQuotationForm = _ref => {
211
203
 
212
204
  // Note: this throws on error.
213
205
  internalQuotationFormSchema.validateSync(_objectSpread(_objectSpread(_objectSpread({}, vehicle), customer), {}, {
214
- channelType: channel === null || channel === void 0 ? void 0 : channel.channelType,
215
- channelId: channel === null || channel === void 0 ? void 0 : channel.channelId
206
+ // Note: add string fallback here to prevent null check in Yup throwing weird errors
207
+ // However: dont submit empty strings to the API because the API doesnt accept empty strings in place of `undefined`
208
+ // Rule in custom API: a field can be optional (can be undefined), but once you fill it in with a value, that value has to be truthy.
209
+ channelType: (channel === null || channel === void 0 ? void 0 : channel.channelType) || '',
210
+ channelId: (channel === null || channel === void 0 ? void 0 : channel.channelId) || ''
216
211
  }), {
217
212
  strict: false,
218
213
  abortEarly: false
@@ -411,7 +406,7 @@ const InternalQuotationForm = _ref => {
411
406
  initialValue: _licensePlate,
412
407
  name: "licensePlate",
413
408
  onChange: value => _setLicensePlate(value),
414
- isRequired: true,
409
+ isRequired: false,
415
410
  form: "quotation",
416
411
  label: "Kenteken:",
417
412
  errorMessage: errors === null || errors === void 0 ? void 0 : errors['licensePlate']
@@ -119,6 +119,7 @@ const INITIAL_ORDER_SESSION_STATE = {
119
119
  selectedBranch: null,
120
120
  discountCode: null,
121
121
  franchiseName: null,
122
+ customerAgreed: undefined,
122
123
  vehicle: {
123
124
  ownershipType: _constants__.VEHICLE_OWNERSHIP_TYPE.Particulier,
124
125
  leaseNumber: ''
@@ -191,7 +192,8 @@ const orderSessionActions = exports.orderSessionActions = {
191
192
  SET_DISCOUNT_PERCENTAGE: 'SET_DISCOUNT_PERCENTAGE',
192
193
  CLEAR_DISCOUNT: 'CLEAR_DISCOUNT',
193
194
  SET_FRANCHISE_NAME: 'SET_FRANCHISE_NAME',
194
- SET_PRICE_CALCULATION_DATE: 'SET_PRICE_CALCULATION_DATE'
195
+ SET_PRICE_CALCULATION_DATE: 'SET_PRICE_CALCULATION_DATE',
196
+ SET_CUSTOMER_AGREED: 'SET_CUSTOMER_AGREED'
195
197
  };
196
198
  const orderSessionReducer = (state, action) => {
197
199
  switch (action.type) {
@@ -777,6 +779,15 @@ const orderSessionReducer = (state, action) => {
777
779
  priceCalculationDate: date
778
780
  });
779
781
  }
782
+ case orderSessionActions.SET_CUSTOMER_AGREED:
783
+ {
784
+ const {
785
+ customerAgreed = false
786
+ } = action.payload;
787
+ return _objectSpread(_objectSpread({}, state), {}, {
788
+ customerAgreed
789
+ });
790
+ }
780
791
  default:
781
792
  return state;
782
793
  }
@@ -67,7 +67,7 @@ function _toPrimitive(t, r) {
67
67
  * @description Covnerts an existing hyper dossier object into a local order session
68
68
  */
69
69
  const parseDossierToOrderSession = exports.parseDossierToOrderSession = function parseDossierToOrderSession() {
70
- var _dossier$kanaal, _dossier$kanaalPartne, _dossier$vestiging, _dossier$typeEigendom, _Date, _dossier$klant, _dossier$klant2, _dossier$klant3, _dossier$klant4, _dossier$klant5, _dossier$klant6, _dossier$klant7, _dossier$klant8, _dossier$klant9;
70
+ var _dossier$kanaal, _dossier$kanaalPartne, _dossier$kanaalHoofka, _dossier$vestiging, _dossier$typeEigendom, _Date, _dossier$klant, _dossier$klant2, _dossier$klant3, _dossier$klant4, _dossier$klant5, _dossier$klant6, _dossier$klant7, _dossier$klant8, _dossier$klant9;
71
71
  let dossier = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
72
72
  return {
73
73
  licensePlate: dossier === null || dossier === void 0 ? void 0 : dossier.kenteken,
@@ -75,7 +75,7 @@ const parseDossierToOrderSession = exports.parseDossierToOrderSession = function
75
75
  // Note: only fill in when license plate is empty
76
76
  channel: {
77
77
  channelType: dossier === null || dossier === void 0 || (_dossier$kanaal = dossier.kanaal) === null || _dossier$kanaal === void 0 ? void 0 : _dossier$kanaal.entityId,
78
- channelId: dossier === null || dossier === void 0 || (_dossier$kanaalPartne = dossier.kanaalPartner) === null || _dossier$kanaalPartne === void 0 ? void 0 : _dossier$kanaalPartne.entityId
78
+ channelId: (dossier === null || dossier === void 0 || (_dossier$kanaalPartne = dossier.kanaalPartner) === null || _dossier$kanaalPartne === void 0 ? void 0 : _dossier$kanaalPartne.entityId) || (dossier === null || dossier === void 0 || (_dossier$kanaalHoofka = dossier.kanaalHoofkantoor) === null || _dossier$kanaalHoofka === void 0 ? void 0 : _dossier$kanaalHoofka.entityId)
79
79
  },
80
80
  durationAnswer: dossier === null || dossier === void 0 ? void 0 : dossier.looptijd,
81
81
  executionAnswer1: dossier === null || dossier === void 0 ? void 0 : dossier.uitvoeringTrekhaakExecuton1,
@@ -112,10 +112,11 @@ const parseDossierToOrderSession = exports.parseDossierToOrderSession = function
112
112
  appointment: {
113
113
  date: !(dossier !== null && dossier !== void 0 && dossier.geplandeTijd) ? new Date() : new Date().setTime(dossier === null || dossier === void 0 ? void 0 : dossier.geplandeTijd),
114
114
  time: !(dossier !== null && dossier !== void 0 && dossier.geplandeTijd) ? new Date() : (_Date = new Date()) === null || _Date === void 0 ? void 0 : _Date.setTime(dossier === null || dossier === void 0 ? void 0 : dossier.geplandeTijd),
115
- note: dossier === null || dossier === void 0 ? void 0 : dossier.interneOpmerking
115
+ note: dossier === null || dossier === void 0 ? void 0 : dossier.opmerkingKlant
116
116
  },
117
117
  priceCalculationDate: dossier !== null && dossier !== void 0 && dossier.prijsberekeningsdatum ? dossier === null || dossier === void 0 ? void 0 : dossier.prijsberekeningsdatum : new Date().getTime(),
118
118
  customer: {
119
+ note: dossier === null || dossier === void 0 ? void 0 : dossier.opmerkingKlant,
119
120
  firstName: (dossier === null || dossier === void 0 || (_dossier$klant = dossier.klant) === null || _dossier$klant === void 0 ? void 0 : _dossier$klant.firstName) || '',
120
121
  lastName: (dossier === null || dossier === void 0 || (_dossier$klant2 = dossier.klant) === null || _dossier$klant2 === void 0 ? void 0 : _dossier$klant2.lastName) || '',
121
122
  infix: (dossier === null || dossier === void 0 || (_dossier$klant3 = dossier.klant) === null || _dossier$klant3 === void 0 ? void 0 : _dossier$klant3.tussenvoegsel) || '',
@@ -7,12 +7,13 @@ require("core-js/modules/es.string.includes.js");
7
7
  require("core-js/modules/esnext.iterator.constructor.js");
8
8
  require("core-js/modules/esnext.iterator.filter.js");
9
9
  require("core-js/modules/esnext.iterator.flat-map.js");
10
+ require("core-js/modules/esnext.iterator.for-each.js");
10
11
  require("core-js/modules/esnext.iterator.map.js");
11
12
  require("core-js/modules/web.dom-collections.iterator.js");
12
13
  Object.defineProperty(exports, "__esModule", {
13
14
  value: true
14
15
  });
15
- exports.validateCartInput = exports.formatHyperDescription = exports.extractProductSpecsArray = exports.checkIfTowbarIsRecommended = void 0;
16
+ exports.validateCartInput = exports.parseProductSpecifications = exports.formatHyperDescription = exports.extractProductSpecsArray = exports.checkIfTowbarIsRecommended = void 0;
16
17
  require("core-js/modules/es.array.flat-map.js");
17
18
  require("core-js/modules/es.array.includes.js");
18
19
  require("core-js/modules/es.array.unscopables.flat-map.js");
@@ -20,6 +21,7 @@ require("core-js/modules/es.string.includes.js");
20
21
  require("core-js/modules/esnext.iterator.constructor.js");
21
22
  require("core-js/modules/esnext.iterator.filter.js");
22
23
  require("core-js/modules/esnext.iterator.flat-map.js");
24
+ require("core-js/modules/esnext.iterator.for-each.js");
23
25
  require("core-js/modules/esnext.iterator.map.js");
24
26
  require("core-js/modules/web.dom-collections.iterator.js");
25
27
  var _constants__ = require("../__constants__");
@@ -71,4 +73,26 @@ exports.checkIfTowbarIsRecommended = checkIfTowbarIsRecommended;
71
73
  const formatHyperDescription = description => {
72
74
  return description === null || description === void 0 ? void 0 : description.ops.map(phrase => phrase.insert).join('');
73
75
  };
74
- exports.formatHyperDescription = formatHyperDescription;
76
+
77
+ /**
78
+ * @description Parses a product EXCL/INCL/OPM orderlines
79
+ */
80
+ exports.formatHyperDescription = formatHyperDescription;
81
+ const parseProductSpecifications = exports.parseProductSpecifications = function parseProductSpecifications() {
82
+ let productLines = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
83
+ const allSpecifications = [];
84
+ productLines.forEach(line => {
85
+ if (line !== null && line !== void 0 && line.excl) {
86
+ allSpecifications.push("Niet Geschikt voor: ".concat(line === null || line === void 0 ? void 0 : line.excl));
87
+ }
88
+ if (line !== null && line !== void 0 && line.incl) {
89
+ allSpecifications.push("Geschikt voor: ".concat(line === null || line === void 0 ? void 0 : line.incl));
90
+ }
91
+ if (line !== null && line !== void 0 && line.remark) {
92
+ allSpecifications.push("Opmerking: ".concat(line === null || line === void 0 ? void 0 : line.remark));
93
+ }
94
+ });
95
+
96
+ // Note: filter non-unique values out
97
+ return [...new Set(allSpecifications)];
98
+ };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.checkIfMouseOutsideWindow = void 0;
6
+ exports.scrollToFirstErrorMessage = exports.checkIfMouseOutsideWindow = void 0;
7
7
  /**
8
8
  * @description Checks whether the mouse inside the view
9
9
  * @param {Number} mouseY the "Y" coordinate of the mouse
@@ -17,4 +17,23 @@ const checkIfMouseOutsideWindow = _ref => {
17
17
  } = _ref;
18
18
  return mouseY > window.innerHeight - offset || mouseY < offset;
19
19
  };
20
- exports.checkIfMouseOutsideWindow = checkIfMouseOutsideWindow;
20
+
21
+ /**
22
+ * @description Finds the first instance of `error-message` on the DOM and scrolls to it
23
+ */
24
+ exports.checkIfMouseOutsideWindow = checkIfMouseOutsideWindow;
25
+ const scrollToFirstErrorMessage = () => {
26
+ if (typeof window === 'undefined') {
27
+ console.warn("scrollToFirstErrorMessage() should only run in browser");
28
+ return;
29
+ }
30
+ const errorMessage = window.document.querySelector("[name=\"error-message\"]");
31
+ if (!errorMessage) {
32
+ return;
33
+ }
34
+ errorMessage.scrollIntoView({
35
+ behavior: 'smooth',
36
+ block: 'center'
37
+ });
38
+ };
39
+ exports.scrollToFirstErrorMessage = scrollToFirstErrorMessage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thm-p3-configurator",
3
- "version": "0.0.37",
3
+ "version": "0.0.39",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "author": "EnoRm.",