@alexsab-ru/scripts 0.15.2 → 0.16.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.
@@ -1,8 +1,75 @@
1
- export const createRequest = (routeKey, phoneValue, nameValue, verbose = false) => {
2
- return new Promise((resolve, reject) => {
3
- let errorText = '';
4
- if(window.ctw) {
5
- window.ctw.getRouteKeyData(routeKey, function(success, data){
1
+ export const createRequest = (routeKey, phoneValue, nameValue, verbose = false, modId = '') => {
2
+ return new Promise((resolve, reject) => {
3
+ let errorText = '';
4
+
5
+ // Если mod_id передан явно, пытаемся взять выделенный инстанс multi-project:
6
+ // window["ctw_<mod_id>"].
7
+ const scopedKey = modId ? `ctw_${modId}` : '';
8
+ const scopedCtw = scopedKey && window[scopedKey] ? window[scopedKey] : null;
9
+ // Fallback для старого сценария, где есть только один глобальный инстанс.
10
+ const fallbackCtw = window.ctw || null;
11
+ const ctwInstance = scopedCtw || fallbackCtw;
12
+
13
+ if (!ctwInstance || typeof ctwInstance.createRequest !== 'function') {
14
+ reject('window.ctw is not defined');
15
+ return;
16
+ }
17
+
18
+ const executeCreateRequest = () => {
19
+ let phone_ct = phoneValue.replace(/[^0-9]/gim, '');
20
+ if (phone_ct[0] == '8') { phone_ct = phone_ct.substring(1); }
21
+ if (phone_ct[0] == '7') { phone_ct = phone_ct.substring(1); }
22
+ phone_ct = '7' + phone_ct;
23
+
24
+ ctwInstance.createRequest(
25
+ routeKey,
26
+ phone_ct,
27
+ (nameValue.length > 0 ? [{ "name": "Name", "value": nameValue }] : []),
28
+ function(success, data) {
29
+ verbose && console.log(success, data);
30
+ if (success) {
31
+ verbose && console.log('Создана заявка на колбек, идентификатор: ' + data.callbackRequestId);
32
+ resolve(data);
33
+ } else {
34
+ errorText = 'Error in createRequest';
35
+ switch (data.type) {
36
+ case 'request_throttle_timeout':
37
+ case 'request_throttle_count':
38
+ errorText = 'Достигнут лимит создания заявок, попробуйте позже';
39
+ verbose && console.log(errorText);
40
+ break;
41
+ case 'request_phone_blacklisted':
42
+ errorText = 'номер телефона находится в черном списке';
43
+ verbose && console.log(errorText);
44
+ break;
45
+ case 'validation_error':
46
+ errorText = 'были переданы некорректные данные';
47
+ verbose && console.log(errorText);
48
+ break;
49
+ default:
50
+ errorText = 'Во время выполнения запроса произошла ошибка: ' + data.type;
51
+ verbose && console.log(errorText);
52
+ }
53
+ reject(errorText);
54
+ }
55
+ }
56
+ );
57
+ };
58
+
59
+ // Multi-project: если нашли window["ctw_<mod_id>"], сразу создаём заявку.
60
+ // Здесь намеренно пропускаем getRouteKeyData.
61
+ if (scopedCtw) {
62
+ executeCreateRequest();
63
+ return;
64
+ }
65
+
66
+ // Legacy-ветка: без mod_id сохраняем исходную проверку routeKey через getRouteKeyData.
67
+ if (typeof ctwInstance.getRouteKeyData !== 'function') {
68
+ reject('window.ctw.getRouteKeyData is not defined');
69
+ return;
70
+ }
71
+
72
+ ctwInstance.getRouteKeyData(routeKey, function(success, data) {
6
73
  verbose && console.log(success, data);
7
74
  if (success) {
8
75
  if (data.widgetFound) {
@@ -15,62 +82,18 @@ return new Promise((resolve, reject) => {
15
82
  verbose && console.log('колл-центр не работает, заявки в нерабочее время не собираем');
16
83
  }
17
84
  }
18
-
19
- var phone_ct = phoneValue.replace(/[^0-9]/gim, '');
20
- if (phone_ct[0] == '8') { phone_ct = phone_ct.substring(1); }
21
- if (phone_ct[0] == '7') { phone_ct = phone_ct.substring(1); }
22
- phone_ct = '7' + phone_ct;
23
-
24
- window.ctw.createRequest(
25
- routeKey,
26
- phone_ct,
27
- ( nameValue.length > 0 ? [
28
- {"name": "Name", "value": nameValue}
29
- ] : []),
30
- function (success, data) {
31
- verbose && console.log(success, data)
32
- if (success) {
33
- verbose && console.log('Создана заявка на колбек, идентификатор: ' + data.callbackRequestId);
34
- resolve(data); // Разрешаем Promise данными от createRequest
35
- }
36
- else {
37
- errorText = 'Error in createRequest';
38
- switch (data.type) {
39
- case "request_throttle_timeout":
40
- case "request_throttle_count":
41
- errorText = 'Достигнут лимит создания заявок, попробуйте позже';
42
- verbose && console.log(errorText);
43
- break;
44
- case "request_phone_blacklisted":
45
- errorText = 'номер телефона находится в черном списке';
46
- verbose && console.log(errorText);
47
- break;
48
- case "validation_error":
49
- errorText = 'были переданы некорректные данные';
50
- verbose && console.log(errorText);
51
- break;
52
- default:
53
- errorText = 'Во время выполнения запроса произошла ошибка: ' + data.type;
54
- verbose && console.log(errorText);
55
- }
56
- reject(errorText); // Отклоняем Promise в случае ошибки
57
- }
58
- }
59
- );
85
+ executeCreateRequest();
60
86
  } else {
61
- errorText = 'не найден включенный виджет '+routeKey+', либо услуга обратного звонка не активна';
87
+ errorText = 'не найден включенный виджет ' + routeKey + ', либо услуга обратного звонка не активна';
62
88
  verbose && console.log(errorText);
63
89
  reject(errorText);
64
90
  }
65
91
  } else {
66
92
  errorText = 'во время обработки произошла ошибка';
67
93
  verbose && console.log(errorText);
68
- verbose && console.log(data)
94
+ verbose && console.log(data);
69
95
  reject(errorText);
70
96
  }
71
97
  });
72
- } else {
73
- reject("window.ctw is not defined");
74
- }
75
- });
98
+ });
76
99
  };
package/lib/form.js CHANGED
@@ -22,19 +22,35 @@ export const maskphone = (e) => {
22
22
  };
23
23
 
24
24
 
25
- export const phoneChecker = (phone) => {
25
+ export const phoneChecker = (phone, options = {}) => {
26
+ // Опция silent:
27
+ // - true => функция работает в "тихом" режиме (НЕ показывает сообщения), возвращает только true|false
28
+ // - false => ведёт себя как раньше: показывает разные сообщения об ошибках
29
+ const { silent = false } = options;
30
+
26
31
  let form = phone.closest("form");
32
+
33
+ // Пустое значение
27
34
  if (!phone.value.length) {
28
- showErrorMes(form, ".phone", "Телефон является обязательным полем");
35
+ if (!silent && form) {
36
+ showErrorMes(form, ".phone", "Телефон является обязательным полем");
37
+ }
29
38
  return false;
30
- } else {
31
- const phoneRe = new RegExp(/^\+7 [0-9]{3} [0-9]{3}-[0-9]{2}-[0-9]{2}$/);
32
- if (!phoneRe.test(phone.value) || noValidPhone(phone.value)) {
39
+ }
40
+
41
+ // Формат и анти-флуд (одинаковые цифры)
42
+ const phoneRe = new RegExp(/^\+7 [0-9]{3} [0-9]{3}-[0-9]{2}-[0-9]{2}$/);
43
+ if (!phoneRe.test(phone.value) || noValidPhone(phone.value)) {
44
+ if (!silent && form) {
33
45
  showErrorMes(form, ".phone", "Введен некорректный номер телефона");
34
- return false;
35
46
  }
47
+ return false;
48
+ }
49
+
50
+ // Валидно — в шумном режиме прячем текст ошибки
51
+ if (!silent && form) {
52
+ showErrorMes(form, ".phone", "");
36
53
  }
37
- showErrorMes(form, ".phone", "");
38
54
  return true;
39
55
  };
40
56
 
@@ -106,6 +122,8 @@ export const messageModal = document.getElementById("message-modal");
106
122
  export const connectForms = (url, props = propsParams) => {
107
123
  props = {...propsParams, ...props};
108
124
 
125
+ console.log("url: ", url);
126
+ console.log("props: ", props);
109
127
 
110
128
  document.querySelectorAll("input[name=phone]").forEach(function (element) {
111
129
  // element.addEventListener("focus", maskphone);
@@ -274,20 +292,62 @@ const submitForm = async (form) => {
274
292
  });
275
293
 
276
294
  let formDataObj = {};
295
+ // Считаем значения один раз, чтобы одинаково использовать их в try/catch и логах.
296
+ const dealerRouteKey = dealer && dealer.dataset ? (dealer.dataset.ctRouteKey || '').trim() : '';
297
+ const dealerModId = dealer && dealer.dataset ? (dealer.dataset.ctModId || '').trim() : '';
298
+ const calltouchRouteKey = dealerRouteKey || props.ct_routeKey;
299
+ const scopedCtwName = dealerModId ? `ctw_${dealerModId}` : '';
300
+ const hasScopedCtw = scopedCtwName ? typeof window[scopedCtwName] !== 'undefined' : false;
301
+ const hasGlobalCtw = typeof window.ctw !== 'undefined';
302
+
277
303
  try {
278
- // Отправка заявки на обратный возов в CallTouch
279
- if(props.ct_routeKey != '') {
280
- const requestData = await createRequest(props.ct_routeKey, phone.value, name.value, props.verbose);
304
+ // Для multi-project берём routeKey/mod_id у выбранного дилера (data-атрибуты select).
305
+ // Если дилерские значения отсутствуют, используем старый глобальный props.ct_routeKey.
306
+ props.verbose && console.log('Calltouch submit debug:', {
307
+ formId: form.id || '',
308
+ phone: phone && phone.value ? phone.value : '',
309
+ name: name && name.value ? name.value : '',
310
+ dealerValue: dealer && dealer.value ? dealer.value : '',
311
+ dealerRouteKey,
312
+ dealerModId,
313
+ fallbackRouteKey: props.ct_routeKey,
314
+ calltouchRouteKey,
315
+ scopedCtwName,
316
+ hasScopedCtw,
317
+ hasGlobalCtw
318
+ });
319
+
320
+ // Отправка заявки на обратный вызов в CallTouch.
321
+ if(calltouchRouteKey != '') {
322
+ const requestData = await createRequest(calltouchRouteKey, phone.value, name.value, props.verbose, dealerModId);
281
323
  formData.append("ct_callback", true);
282
324
  formData.append("ctw_createRequest", JSON.stringify(requestData));
325
+ if (dealerModId !== '') {
326
+ // Храним mod_id в payload для отладки и серверных логов.
327
+ formData.append("ct_mod_id", dealerModId);
328
+ }
283
329
  } else {
284
330
  throw new Error('Empty ct_routeKey');
285
331
  }
286
332
  } catch (error) {
287
- if(props.ct_routeKey != '') {
333
+ if(calltouchRouteKey != '') {
288
334
  formData.append("ctw_createRequest", error);
289
335
  }
290
- props.verbose && console.error("Error during request Calltouch callback:", error);
336
+ const normalizedError = error instanceof Error ? {
337
+ name: error.name,
338
+ message: error.message,
339
+ stack: error.stack
340
+ } : error;
341
+ console.error("Error during request Calltouch callback:", normalizedError, {
342
+ formId: form.id || '',
343
+ dealerRouteKey,
344
+ dealerModId,
345
+ fallbackRouteKey: props.ct_routeKey,
346
+ calltouchRouteKey,
347
+ scopedCtwName,
348
+ hasScopedCtw,
349
+ hasGlobalCtw
350
+ });
291
351
  formDataObj = getFormDataObject(formData, form.id);
292
352
  }
293
353
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexsab-ru/scripts",
3
- "version": "0.15.2",
3
+ "version": "0.16.0",
4
4
  "description": "common libs for websites",
5
5
  "main": "index.js",
6
6
  "scripts": {