@redneckz/wildless-cms-uni-blocks 0.14.911 → 0.14.913
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.
- package/bundle/api/LeadServiceAPI.d.ts +12 -3
- package/bundle/bundle.umd.js +716 -684
- package/bundle/bundle.umd.min.js +1 -1
- package/bundle/components/ApplicationForm/VerifyPhoneDialog.d.ts +10 -0
- package/bundle/components/ApplicationForm/useVerifyPhoneDialogSubmit.d.ts +18 -0
- package/bundle/components/TariffsTable/TariffsTableCell.d.ts +1 -1
- package/bundle/retail/api/checkCode.d.ts +1 -9
- package/bundle/retail/api/sendCode.d.ts +1 -1
- package/bundle/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.d.ts +0 -4
- package/bundle/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.d.ts +1 -6
- package/bundle/ui-kit/ResponseTypeDialog/ResponseTypeDialog.d.ts +1 -1
- package/bundle/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.d.ts +16 -0
- package/bundle/utils/getTimer.d.ts +2 -0
- package/dist/api/LeadServiceAPI.d.ts +12 -3
- package/dist/api/LeadServiceAPI.js +0 -3
- package/dist/api/LeadServiceAPI.js.map +1 -1
- package/dist/components/ApplicationForm/ApplicationForm.js +1 -3
- package/dist/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/dist/components/ApplicationForm/VerifyPhoneDialog.d.ts +10 -0
- package/dist/components/ApplicationForm/VerifyPhoneDialog.js +37 -0
- package/dist/components/ApplicationForm/VerifyPhoneDialog.js.map +1 -0
- package/dist/components/ApplicationForm/useVerifyPhoneDialogSubmit.d.ts +18 -0
- package/dist/components/ApplicationForm/useVerifyPhoneDialogSubmit.js +50 -0
- package/dist/components/ApplicationForm/useVerifyPhoneDialogSubmit.js.map +1 -0
- package/dist/components/ExchangeRateTile/ExchangeCurrencyCalculator.js +2 -2
- package/dist/components/ExchangeRateTile/ExchangeCurrencyCalculator.js.map +1 -1
- package/dist/components/TariffsTable/TariffsTableCell.d.ts +1 -1
- package/dist/retail/api/checkCode.d.ts +1 -9
- package/dist/retail/api/checkCode.js +1 -22
- package/dist/retail/api/checkCode.js.map +1 -1
- package/dist/retail/api/sendCode.d.ts +1 -1
- package/dist/retail/api/sendCode.js +2 -8
- package/dist/retail/api/sendCode.js.map +1 -1
- package/dist/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.d.ts +0 -4
- package/dist/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js +5 -24
- package/dist/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js.map +1 -1
- package/dist/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.d.ts +1 -6
- package/dist/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js +7 -10
- package/dist/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js.map +1 -1
- package/dist/retail/utils/mockLocalStorage.js +2 -2
- package/dist/retail/utils/mockLocalStorage.js.map +1 -1
- package/dist/ui-kit/ResponseTypeDialog/ResponseTypeDialog.d.ts +1 -1
- package/dist/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.d.ts +16 -0
- package/dist/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js +17 -0
- package/dist/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js.map +1 -0
- package/dist/utils/getTimer.d.ts +2 -0
- package/dist/utils/getTimer.js +6 -0
- package/dist/utils/getTimer.js.map +1 -0
- package/lib/api/LeadServiceAPI.d.ts +12 -3
- package/lib/api/LeadServiceAPI.js +0 -3
- package/lib/api/LeadServiceAPI.js.map +1 -1
- package/lib/common.css +1 -1
- package/lib/components/ApplicationForm/ApplicationForm.js +1 -3
- package/lib/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/lib/components/ApplicationForm/VerifyPhoneDialog.d.ts +10 -0
- package/lib/components/ApplicationForm/VerifyPhoneDialog.js +35 -0
- package/lib/components/ApplicationForm/VerifyPhoneDialog.js.map +1 -0
- package/lib/components/ApplicationForm/useVerifyPhoneDialogSubmit.d.ts +18 -0
- package/lib/components/ApplicationForm/useVerifyPhoneDialogSubmit.js +47 -0
- package/lib/components/ApplicationForm/useVerifyPhoneDialogSubmit.js.map +1 -0
- package/lib/components/ExchangeRateTile/ExchangeCurrencyCalculator.js +2 -2
- package/lib/components/ExchangeRateTile/ExchangeCurrencyCalculator.js.map +1 -1
- package/lib/components/TariffsTable/TariffsTableCell.d.ts +1 -1
- package/lib/retail/api/checkCode.d.ts +1 -9
- package/lib/retail/api/checkCode.js +1 -22
- package/lib/retail/api/checkCode.js.map +1 -1
- package/lib/retail/api/sendCode.d.ts +1 -1
- package/lib/retail/api/sendCode.js +1 -7
- package/lib/retail/api/sendCode.js.map +1 -1
- package/lib/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.d.ts +0 -4
- package/lib/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js +5 -24
- package/lib/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js.map +1 -1
- package/lib/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.d.ts +1 -6
- package/lib/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js +5 -8
- package/lib/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js.map +1 -1
- package/lib/retail/utils/mockLocalStorage.js +2 -2
- package/lib/retail/utils/mockLocalStorage.js.map +1 -1
- package/lib/ui-kit/ResponseTypeDialog/ResponseTypeDialog.d.ts +1 -1
- package/lib/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.d.ts +16 -0
- package/lib/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js +15 -0
- package/lib/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js.map +1 -0
- package/lib/utils/getTimer.d.ts +2 -0
- package/lib/utils/getTimer.js +3 -0
- package/lib/utils/getTimer.js.map +1 -0
- package/mobile/bundle/api/LeadServiceAPI.d.ts +12 -3
- package/mobile/bundle/bundle.umd.js +716 -684
- package/mobile/bundle/bundle.umd.min.js +1 -1
- package/mobile/bundle/components/ApplicationForm/VerifyPhoneDialog.d.ts +10 -0
- package/mobile/bundle/components/ApplicationForm/useVerifyPhoneDialogSubmit.d.ts +18 -0
- package/mobile/bundle/components/TariffsTable/TariffsTableCell.d.ts +1 -1
- package/mobile/bundle/retail/api/checkCode.d.ts +1 -9
- package/mobile/bundle/retail/api/sendCode.d.ts +1 -1
- package/mobile/bundle/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.d.ts +0 -4
- package/mobile/bundle/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.d.ts +1 -6
- package/mobile/bundle/ui-kit/ResponseTypeDialog/ResponseTypeDialog.d.ts +1 -1
- package/mobile/bundle/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.d.ts +16 -0
- package/mobile/bundle/utils/getTimer.d.ts +2 -0
- package/mobile/dist/api/LeadServiceAPI.d.ts +12 -3
- package/mobile/dist/api/LeadServiceAPI.js +0 -3
- package/mobile/dist/api/LeadServiceAPI.js.map +1 -1
- package/mobile/dist/components/ApplicationForm/ApplicationForm.js +1 -3
- package/mobile/dist/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/mobile/dist/components/ApplicationForm/VerifyPhoneDialog.d.ts +10 -0
- package/mobile/dist/components/ApplicationForm/VerifyPhoneDialog.js +37 -0
- package/mobile/dist/components/ApplicationForm/VerifyPhoneDialog.js.map +1 -0
- package/mobile/dist/components/ApplicationForm/useVerifyPhoneDialogSubmit.d.ts +18 -0
- package/mobile/dist/components/ApplicationForm/useVerifyPhoneDialogSubmit.js +50 -0
- package/mobile/dist/components/ApplicationForm/useVerifyPhoneDialogSubmit.js.map +1 -0
- package/mobile/dist/components/ExchangeRateTile/ExchangeCurrencyCalculator.js +2 -2
- package/mobile/dist/components/ExchangeRateTile/ExchangeCurrencyCalculator.js.map +1 -1
- package/mobile/dist/components/TariffsTable/TariffsTableCell.d.ts +1 -1
- package/mobile/dist/retail/api/checkCode.d.ts +1 -9
- package/mobile/dist/retail/api/checkCode.js +1 -22
- package/mobile/dist/retail/api/checkCode.js.map +1 -1
- package/mobile/dist/retail/api/sendCode.d.ts +1 -1
- package/mobile/dist/retail/api/sendCode.js +2 -8
- package/mobile/dist/retail/api/sendCode.js.map +1 -1
- package/mobile/dist/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.d.ts +0 -4
- package/mobile/dist/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js +5 -24
- package/mobile/dist/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js.map +1 -1
- package/mobile/dist/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.d.ts +1 -6
- package/mobile/dist/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js +7 -10
- package/mobile/dist/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js.map +1 -1
- package/mobile/dist/retail/utils/mockLocalStorage.js +2 -2
- package/mobile/dist/retail/utils/mockLocalStorage.js.map +1 -1
- package/mobile/dist/ui-kit/ResponseTypeDialog/ResponseTypeDialog.d.ts +1 -1
- package/mobile/dist/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.d.ts +16 -0
- package/mobile/dist/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js +17 -0
- package/mobile/dist/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js.map +1 -0
- package/mobile/dist/utils/getTimer.d.ts +2 -0
- package/mobile/dist/utils/getTimer.js +6 -0
- package/mobile/dist/utils/getTimer.js.map +1 -0
- package/mobile/lib/api/LeadServiceAPI.d.ts +12 -3
- package/mobile/lib/api/LeadServiceAPI.js +0 -3
- package/mobile/lib/api/LeadServiceAPI.js.map +1 -1
- package/mobile/lib/common.css +1 -1
- package/mobile/lib/components/ApplicationForm/ApplicationForm.js +1 -3
- package/mobile/lib/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/mobile/lib/components/ApplicationForm/VerifyPhoneDialog.d.ts +10 -0
- package/mobile/lib/components/ApplicationForm/VerifyPhoneDialog.js +35 -0
- package/mobile/lib/components/ApplicationForm/VerifyPhoneDialog.js.map +1 -0
- package/mobile/lib/components/ApplicationForm/useVerifyPhoneDialogSubmit.d.ts +18 -0
- package/mobile/lib/components/ApplicationForm/useVerifyPhoneDialogSubmit.js +47 -0
- package/mobile/lib/components/ApplicationForm/useVerifyPhoneDialogSubmit.js.map +1 -0
- package/mobile/lib/components/ExchangeRateTile/ExchangeCurrencyCalculator.js +2 -2
- package/mobile/lib/components/ExchangeRateTile/ExchangeCurrencyCalculator.js.map +1 -1
- package/mobile/lib/components/TariffsTable/TariffsTableCell.d.ts +1 -1
- package/mobile/lib/retail/api/checkCode.d.ts +1 -9
- package/mobile/lib/retail/api/checkCode.js +1 -22
- package/mobile/lib/retail/api/checkCode.js.map +1 -1
- package/mobile/lib/retail/api/sendCode.d.ts +1 -1
- package/mobile/lib/retail/api/sendCode.js +1 -7
- package/mobile/lib/retail/api/sendCode.js.map +1 -1
- package/mobile/lib/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.d.ts +0 -4
- package/mobile/lib/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js +5 -24
- package/mobile/lib/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.js.map +1 -1
- package/mobile/lib/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.d.ts +1 -6
- package/mobile/lib/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js +5 -8
- package/mobile/lib/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.js.map +1 -1
- package/mobile/lib/retail/utils/mockLocalStorage.js +2 -2
- package/mobile/lib/retail/utils/mockLocalStorage.js.map +1 -1
- package/mobile/lib/ui-kit/ResponseTypeDialog/ResponseTypeDialog.d.ts +1 -1
- package/mobile/lib/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.d.ts +16 -0
- package/mobile/lib/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js +15 -0
- package/mobile/lib/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.js.map +1 -0
- package/mobile/lib/utils/getTimer.d.ts +2 -0
- package/mobile/lib/utils/getTimer.js +3 -0
- package/mobile/lib/utils/getTimer.js.map +1 -0
- package/mobile/src/api/LeadServiceAPI.ts +13 -7
- package/mobile/src/components/ApplicationForm/ApplicationForm.tsx +1 -3
- package/mobile/src/components/ApplicationForm/VerifyPhoneDialog.tsx +73 -0
- package/mobile/src/components/ApplicationForm/useVerifyPhoneDialogSubmit.tsx +63 -0
- package/mobile/src/components/ExchangeRateTile/ExchangeCurrencyCalculator.tsx +2 -2
- package/mobile/src/components/TariffsTable/TariffsTableCell.tsx +1 -1
- package/mobile/src/retail/api/checkCode.ts +2 -47
- package/mobile/src/retail/api/sendCode.ts +1 -9
- package/mobile/src/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.tsx +23 -82
- package/mobile/src/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.tsx +7 -21
- package/mobile/src/retail/utils/mockLocalStorage.ts +9 -15
- package/mobile/src/ui-kit/ResponseTypeDialog/ResponseTypeDialog.tsx +1 -1
- package/mobile/src/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.tsx +80 -0
- package/mobile/src/utils/getTimer.ts +4 -0
- package/package.json +1 -1
- package/src/api/LeadServiceAPI.ts +13 -7
- package/src/components/ApplicationForm/ApplicationForm.tsx +1 -3
- package/src/components/ApplicationForm/VerifyPhoneDialog.tsx +73 -0
- package/src/components/ApplicationForm/useVerifyPhoneDialogSubmit.tsx +63 -0
- package/src/components/ExchangeRateTile/ExchangeCurrencyCalculator.tsx +2 -2
- package/src/components/TariffsTable/TariffsTableCell.tsx +1 -1
- package/src/retail/api/checkCode.ts +2 -47
- package/src/retail/api/sendCode.ts +1 -9
- package/src/retail/components/VerifyPhoneDialog/VerifyPhoneDialog.tsx +23 -82
- package/src/retail/components/VerifyPhoneDialog/useVerifyPhoneDialogSubmit.tsx +7 -21
- package/src/retail/utils/mockLocalStorage.ts +9 -15
- package/src/ui-kit/ResponseTypeDialog/ResponseTypeDialog.tsx +1 -1
- package/src/ui-kit/VerifyPhoneDialogLayout/VerfiyPhoneDialogLayout.tsx +80 -0
- package/src/utils/getTimer.ts +4 -0
- package/bundle/model/onClose.d.ts +0 -3
- package/dist/model/onClose.d.ts +0 -3
- package/dist/model/onClose.js +0 -2
- package/dist/model/onClose.js.map +0 -1
- package/lib/model/onClose.d.ts +0 -3
- package/lib/model/onClose.js +0 -2
- package/lib/model/onClose.js.map +0 -1
- package/mobile/bundle/model/onClose.d.ts +0 -3
- package/mobile/dist/model/onClose.d.ts +0 -3
- package/mobile/dist/model/onClose.js +0 -2
- package/mobile/dist/model/onClose.js.map +0 -1
- package/mobile/lib/model/onClose.d.ts +0 -3
- package/mobile/lib/model/onClose.js +0 -2
- package/mobile/lib/model/onClose.js.map +0 -1
- package/mobile/src/model/onClose.ts +0 -3
- package/src/model/onClose.ts +0 -3
package/bundle/bundle.umd.js
CHANGED
|
@@ -1102,9 +1102,6 @@
|
|
|
1102
1102
|
};
|
|
1103
1103
|
try {
|
|
1104
1104
|
const response = await LeadServiceFetch(`${API_BASE_URI$1}/confirmCorporateLead`, submitBody);
|
|
1105
|
-
if (!response?.ok) {
|
|
1106
|
-
return null;
|
|
1107
|
-
}
|
|
1108
1105
|
return await response.json();
|
|
1109
1106
|
}
|
|
1110
1107
|
catch (e) {
|
|
@@ -1239,630 +1236,90 @@
|
|
|
1239
1236
|
setFormStateUnsafe(normalizer);
|
|
1240
1237
|
}
|
|
1241
1238
|
}, [normalizer]);
|
|
1242
|
-
return [formState, setFormState];
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
function useForm(initialState, { resetOnSubmit, formValidator, normalizer, onChange, onSubmit } = {}) {
|
|
1246
|
-
const [formState, setFormState] = useNormalizedFormState(initialState, normalizer, onChange);
|
|
1247
|
-
const fieldRefs = useRef(getRefsObject(initialState));
|
|
1248
|
-
const [isDirtyForm, { setTrue: markAsDirty, setFalse: markAsClean }] = useBool(false);
|
|
1249
|
-
const dirtyFieldsMap = useRef({});
|
|
1250
|
-
const [fieldValidatorsMap, { isValid, errors }] = useFormValidator(formState, formValidator);
|
|
1251
|
-
const field = useCallback((fieldName, options = {}) => {
|
|
1252
|
-
const { parse, format, onChange: onFieldChange } = options;
|
|
1253
|
-
const value = formState[fieldName];
|
|
1254
|
-
const isDirty = isDirtyForm || dirtyFieldsMap.current?.[String(fieldName)];
|
|
1255
|
-
const fieldValidator = options?.validator ?? fieldValidatorsMap[fieldName];
|
|
1256
|
-
const fieldErrors = isDirty && fieldValidator ? fieldValidator(value) : [];
|
|
1257
|
-
return {
|
|
1258
|
-
setFieldRef: (_) => {
|
|
1259
|
-
if (fieldRefs.current) {
|
|
1260
|
-
fieldRefs.current[fieldName] = _;
|
|
1261
|
-
}
|
|
1262
|
-
},
|
|
1263
|
-
fieldRef: fieldRefs.current?.[fieldName],
|
|
1264
|
-
value: format ? format(value) : value,
|
|
1265
|
-
isDirty,
|
|
1266
|
-
errors: fieldValidator && fieldErrors,
|
|
1267
|
-
error: fieldErrors[0],
|
|
1268
|
-
onChange: (_) => {
|
|
1269
|
-
dirtyFieldsMap.current ||= {};
|
|
1270
|
-
dirtyFieldsMap.current[String(fieldName)] = true;
|
|
1271
|
-
const fieldVal = parse ? parse(_) : _;
|
|
1272
|
-
onFieldChange?.(fieldVal);
|
|
1273
|
-
setFormState((prev) => ({ ...prev, [fieldName]: fieldVal }));
|
|
1274
|
-
},
|
|
1275
|
-
};
|
|
1276
|
-
}, [formState, isDirtyForm, fieldValidatorsMap, setFormState]);
|
|
1277
|
-
const update = useCallback((_) => {
|
|
1278
|
-
dirtyFieldsMap.current = _;
|
|
1279
|
-
setFormState(_);
|
|
1280
|
-
}, [setFormState]);
|
|
1281
|
-
const reset = useCallback(() => {
|
|
1282
|
-
dirtyFieldsMap.current = {};
|
|
1283
|
-
markAsClean();
|
|
1284
|
-
setFormState(initialState);
|
|
1285
|
-
}, [initialState, setFormState]);
|
|
1286
|
-
const handleSubmit = useCallback((ev) => {
|
|
1287
|
-
ev.preventDefault();
|
|
1288
|
-
if (isValid) {
|
|
1289
|
-
resetOnSubmit && reset();
|
|
1290
|
-
onSubmit?.(formState, ev);
|
|
1291
|
-
}
|
|
1292
|
-
else {
|
|
1293
|
-
const errorFieldName = getErrorFieldName(formState, fieldValidatorsMap);
|
|
1294
|
-
markAsDirty();
|
|
1295
|
-
field(errorFieldName).fieldRef?.scrollIntoView({ behavior: 'smooth' });
|
|
1296
|
-
}
|
|
1297
|
-
}, [resetOnSubmit, formState, isValid, reset, onSubmit]);
|
|
1298
|
-
return [formState, { errors, field, update, reset, onSubmit: handleSubmit }];
|
|
1299
|
-
}
|
|
1300
|
-
const getRefsObject = (initialState) => Object.keys(initialState).reduce((acc, key) => ({ ...acc, [key]: null }), {});
|
|
1301
|
-
const getErrorFieldName = (formState, fieldValidatorsMap = {}) => {
|
|
1302
|
-
const [errorFieldName = ''] = Object.entries(formState).find(([fieldName, value]) => {
|
|
1303
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
1304
|
-
return fieldValidatorsMap[fieldName]?.(value)?.length;
|
|
1305
|
-
}) ?? [];
|
|
1306
|
-
return errorFieldName;
|
|
1307
|
-
};
|
|
1308
|
-
|
|
1309
|
-
function copy(source, target) {
|
|
1310
|
-
for (const [k, v] of source.entries()) {
|
|
1311
|
-
if (v !== null && v !== undefined) {
|
|
1312
|
-
target.setItem(k, v);
|
|
1313
|
-
}
|
|
1314
|
-
else {
|
|
1315
|
-
target.removeItem(k);
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
function replicate(primary, secondary) {
|
|
1321
|
-
copy(primary, secondary);
|
|
1322
|
-
copy(secondary, primary);
|
|
1323
|
-
return primary.bus.watch(({ type, event }) => {
|
|
1324
|
-
if (event !== null && event !== undefined) {
|
|
1325
|
-
secondary.setItem(type, event);
|
|
1326
|
-
}
|
|
1327
|
-
else {
|
|
1328
|
-
secondary.removeItem(type);
|
|
1329
|
-
}
|
|
1330
|
-
});
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
class StorageAdapter {
|
|
1334
|
-
storage;
|
|
1335
|
-
bus;
|
|
1336
|
-
get size() {
|
|
1337
|
-
return this.storage?.length ?? 0;
|
|
1338
|
-
}
|
|
1339
|
-
constructor(storage, bus = new EventBus()) {
|
|
1340
|
-
this.storage = storage;
|
|
1341
|
-
this.bus = bus;
|
|
1342
|
-
}
|
|
1343
|
-
hasItem(key) {
|
|
1344
|
-
return Boolean(this.storage?.getItem(String(key)));
|
|
1345
|
-
}
|
|
1346
|
-
getItem(key) {
|
|
1347
|
-
const _ = this.storage?.getItem(String(key)) ?? null;
|
|
1348
|
-
try {
|
|
1349
|
-
return JSON.parse(String(_));
|
|
1350
|
-
}
|
|
1351
|
-
catch (ex) {
|
|
1352
|
-
return null;
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
entries() {
|
|
1356
|
-
return Array.from({ length: this.size }, (_, i) => {
|
|
1357
|
-
const k = String(this.storage?.key(i));
|
|
1358
|
-
return [k, this.getItem(k)];
|
|
1359
|
-
});
|
|
1360
|
-
}
|
|
1361
|
-
setItem(key, value) {
|
|
1362
|
-
if (value !== null) {
|
|
1363
|
-
this.storage?.setItem(String(key), JSON.stringify(value));
|
|
1364
|
-
}
|
|
1365
|
-
else {
|
|
1366
|
-
this.storage?.removeItem(String(key));
|
|
1367
|
-
}
|
|
1368
|
-
this.bus?.subject(key, value);
|
|
1369
|
-
}
|
|
1370
|
-
removeItem(key) {
|
|
1371
|
-
this.storage?.removeItem(String(key));
|
|
1372
|
-
this.bus?.subject(key, null);
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
class Store {
|
|
1377
|
-
bus;
|
|
1378
|
-
store = new Map();
|
|
1379
|
-
get size() {
|
|
1380
|
-
return this.store.size;
|
|
1381
|
-
}
|
|
1382
|
-
constructor(bus = new EventBus()) {
|
|
1383
|
-
this.bus = bus;
|
|
1384
|
-
}
|
|
1385
|
-
hasItem(key) {
|
|
1386
|
-
return this.store.has(key);
|
|
1387
|
-
}
|
|
1388
|
-
getItem(key) {
|
|
1389
|
-
return this.store.get(key);
|
|
1390
|
-
}
|
|
1391
|
-
entries() {
|
|
1392
|
-
return this.store.entries();
|
|
1393
|
-
}
|
|
1394
|
-
setItem(key, value) {
|
|
1395
|
-
this.store.set(key, value);
|
|
1396
|
-
this.bus.subject(key, value);
|
|
1397
|
-
}
|
|
1398
|
-
removeItem(key) {
|
|
1399
|
-
this.store.delete(key);
|
|
1400
|
-
this.bus.subject(key, null);
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
function useRerender() {
|
|
1405
|
-
const [, setCount] = useState(0);
|
|
1406
|
-
return useCallback(() => setCount(_ => (_ + 1) % (1 << 16)), []);
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
const DEFAULT_METHODS = {};
|
|
1410
|
-
/**
|
|
1411
|
-
* MobX like reactivity (simplified).
|
|
1412
|
-
* Can be used to migrate from Redux/MobX or something else
|
|
1413
|
-
*
|
|
1414
|
-
* @param store
|
|
1415
|
-
* @returns reactive proxy backed by store
|
|
1416
|
-
*/
|
|
1417
|
-
function useStore(store, methods = DEFAULT_METHODS) {
|
|
1418
|
-
const deps = useRef(null);
|
|
1419
|
-
const render = useRerender();
|
|
1420
|
-
useEffect(() => store.bus.watch(ev => {
|
|
1421
|
-
if (deps.current?.has(String(ev.type))) {
|
|
1422
|
-
render();
|
|
1423
|
-
}
|
|
1424
|
-
}), [store, render]);
|
|
1425
|
-
return useMemo(() => new Proxy(methods, {
|
|
1426
|
-
get(_, key) {
|
|
1427
|
-
deps.current ||= new Set();
|
|
1428
|
-
deps.current.add(key);
|
|
1429
|
-
return store.getItem(key);
|
|
1430
|
-
},
|
|
1431
|
-
has(_, key) {
|
|
1432
|
-
deps.current ||= new Set();
|
|
1433
|
-
deps.current.add(key);
|
|
1434
|
-
return store.hasItem(key);
|
|
1435
|
-
},
|
|
1436
|
-
set(_, key, value) {
|
|
1437
|
-
store.setItem(key, value);
|
|
1438
|
-
return true;
|
|
1439
|
-
},
|
|
1440
|
-
deleteProperty(_, key) {
|
|
1441
|
-
store.removeItem(key);
|
|
1442
|
-
return true;
|
|
1443
|
-
}
|
|
1444
|
-
}), [store]);
|
|
1445
|
-
}
|
|
1446
|
-
|
|
1447
|
-
const sessionStore = new Store(); // sessionStorage cache
|
|
1448
|
-
replicate(sessionStore, new StorageAdapter(globalThis?.sessionStorage));
|
|
1449
|
-
function useSessionStore() {
|
|
1450
|
-
return useStore(sessionStore);
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
const noop = () => {
|
|
1454
|
-
// Do nothing
|
|
1455
|
-
};
|
|
1456
|
-
|
|
1457
|
-
const themeStyle$1 = {
|
|
1458
|
-
primary: style('text-white bg-primary-main hover:bg-primary-hover active:bg-primary-active', 'group-data-secondary:text-primary-main group-data-secondary:bg-white', 'group-data-secondary:hover:text-white group-data-secondary:hover:bg-primary-hover', 'group-data-secondary:active:bg-primary-active'),
|
|
1459
|
-
secondary: style('text-primary-main bg-main-divider hover:text-white hover:bg-primary-hover active:bg-primary-active', 'group-data-secondary:text-white group-data-secondary:bg-white/20', 'group-data-secondary:hover:bg-primary-hover', 'group-data-secondary:active:bg-primary-active'),
|
|
1460
|
-
};
|
|
1461
|
-
const embeddedStyle = style('group/btn-embedded', 'bg-transparent border border-transparent outline-none');
|
|
1462
|
-
const disabledStyle = style('bg-main-gray text-main-disabled cursor-not-allowed');
|
|
1463
|
-
const Button = JSX(({ className, type = 'button', version = 'primary', shape = 'default', embedded, disabled, role, ariaLabel, data, dataTheme, children, wcmsIgnore, onClick = noop, }) => {
|
|
1464
|
-
const handleClick = useCallback(role !== 'tab' ? handlerDecorator(onClick) : onClick, [
|
|
1465
|
-
role,
|
|
1466
|
-
onClick,
|
|
1467
|
-
]);
|
|
1468
|
-
const aspectsAttrs = useMemo(() => getAspectsAttributes(data), [data]);
|
|
1469
|
-
const isRound = shape === 'round';
|
|
1470
|
-
return (jsx("button", { className: style('font-sans flex items-center gap-xs', {
|
|
1471
|
-
[themeStyle$1[version]]: !disabled && !embedded,
|
|
1472
|
-
[embeddedStyle]: embedded,
|
|
1473
|
-
[disabledStyle]: disabled,
|
|
1474
|
-
}, embedded ? 'justify-between' : 'justify-center', embedded || isRound ? 'p-0' : 'px-9 py-4', {
|
|
1475
|
-
'rounded-md': shape === 'default',
|
|
1476
|
-
'rounded-full': isRound,
|
|
1477
|
-
}, className), type: type, role: role, "aria-label": ariaLabel, disabled: disabled, "aria-disabled": disabled ? 'true' : undefined, "data-theme": dataTheme, "data-wcms-ignore": wcmsIgnore, ...aspectsAttrs, onClick: handleClick, children: children }));
|
|
1478
|
-
});
|
|
1479
|
-
|
|
1480
|
-
const ButtonTitle = JSX(({ className, children }) => (jsx("span", { className: style('inline-flex items-center text-start gap-s group-[]/btn-embedded:text-primary-main', className), children: children })));
|
|
1481
|
-
|
|
1482
|
-
const CloseButton = JSX(({ className, onClose }) => (jsx("button", { className: style('flex justify-center items-center w-12 h-12 p-2xs bg-transparent border-none', className), onClick: onClose, title: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C", type: "button", children: jsx(Icon, { name: "CloseIcon", width: "20", height: "20", iconVersion: "gray" }) })));
|
|
1483
|
-
|
|
1484
|
-
const DIALOG_STYLE = {
|
|
1485
|
-
sm: 'max-w-sm top-1/3',
|
|
1486
|
-
lg: 'max-w-lg',
|
|
1487
|
-
'4xl': 'max-w-4xl',
|
|
1488
|
-
none: 'mt-0',
|
|
1489
|
-
};
|
|
1490
|
-
const Dialog = JSX(({ head, maxWidth = '4xl', children, onClose, onClick }) => (jsxs("div", { className: style('relative bg-white p-lg pb-6xl my-6xl mx-auto rounded-lg w-full', DIALOG_STYLE[maxWidth]), role: "dialog", title: "\u0414\u0438\u0430\u043B\u043E\u0433", onClick: onClick, children: [jsxs("div", { className: "sticky py-xl top-0 bg-white z-10", children: [jsx(CloseButton, { className: "absolute top-0 right-0 z-10", onClose: onClose }), jsx("div", { className: "container", children: head })] }), jsx("div", { className: "container", children: children })] })));
|
|
1491
|
-
|
|
1492
|
-
function useDialog(Dialog, initialProps = {}) {
|
|
1493
|
-
const { open, close, ...rest } = useDialogManager();
|
|
1494
|
-
const openDialog = useCallback((props, options = {}) => open({
|
|
1495
|
-
dialog: (jsx(Dialog, { ...initialProps, ...props, onClose: () => {
|
|
1496
|
-
close();
|
|
1497
|
-
props.onClose?.();
|
|
1498
|
-
} })),
|
|
1499
|
-
...options,
|
|
1500
|
-
}), [Dialog, open, close]);
|
|
1501
|
-
return { open: openDialog, close, ...rest };
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
const Loader = JSX(({ color = 'text-primary-main', position = 'absolute', blur = true, size = 'big' }) => (jsx("div", { className: style('flex justify-center items-center h-full w-full z-50', position, {
|
|
1505
|
-
'backdrop-blur': blur,
|
|
1506
|
-
}), children: jsx("div", { className: style('inline-block', 'animate-spin rounded-full', 'border-solid border-current', 'border-r-transparent', size === 'extraSmall' && 'border-2 h-4 w-4', size === 'small' && 'border-4 h-8 w-8', size === 'big' && 'border-8 h-28 w-28', color), role: "status" }) })));
|
|
1507
|
-
|
|
1508
|
-
const Timer = JSX(({ className, seconds }) => (jsx("span", { className: className, children: formatTimer(seconds) })));
|
|
1509
|
-
const formatTimer = (seconds) => {
|
|
1510
|
-
const minutes = Math.floor(seconds / 60);
|
|
1511
|
-
return [minutes, seconds % 60].map((_) => String(_).padStart(2, '0')).join(':');
|
|
1512
|
-
};
|
|
1513
|
-
|
|
1514
|
-
const useInterval = (handler, period) => {
|
|
1515
|
-
const timer = useRef(null);
|
|
1516
|
-
const stop = useCallback(() => clearInterval(timer.current), []);
|
|
1517
|
-
const start = useCallback(() => {
|
|
1518
|
-
stop();
|
|
1519
|
-
timer.current = setInterval(() => handler(stop), period);
|
|
1520
|
-
}, [handler, period, stop]);
|
|
1521
|
-
useEffect(() => {
|
|
1522
|
-
start();
|
|
1523
|
-
return stop;
|
|
1524
|
-
}, [start, stop]);
|
|
1525
|
-
return { start, stop };
|
|
1526
|
-
};
|
|
1527
|
-
|
|
1528
|
-
function useCountDownTimer({ seconds, period = 1000, onTick, onEnd }) {
|
|
1529
|
-
const counter = useRef(seconds);
|
|
1530
|
-
const handleTick = useCallback((stop) => {
|
|
1531
|
-
counter.current ||= 0;
|
|
1532
|
-
counter.current = Math.max(0, counter.current - 1);
|
|
1533
|
-
try {
|
|
1534
|
-
onTick?.(counter.current);
|
|
1535
|
-
}
|
|
1536
|
-
finally {
|
|
1537
|
-
if (counter.current <= 0) {
|
|
1538
|
-
stop();
|
|
1539
|
-
onEnd?.();
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1542
|
-
}, [onTick, onEnd]);
|
|
1543
|
-
const { start } = useInterval(handleTick, period);
|
|
1544
|
-
return useCallback((_) => {
|
|
1545
|
-
counter.current = _;
|
|
1546
|
-
start();
|
|
1547
|
-
}, []);
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
const getTraceId = () => {
|
|
1551
|
-
const result = new Uint8Array(8);
|
|
1552
|
-
globalThis.crypto.getRandomValues(result);
|
|
1553
|
-
return result.reduce((acc, _) => `${acc}${_.toString(16).padStart(2, '0')}`, '');
|
|
1554
|
-
};
|
|
1555
|
-
|
|
1556
|
-
const fetchRetailJSON = async (url, method, body) => {
|
|
1557
|
-
try {
|
|
1558
|
-
const response = await doRequest(url, method, body);
|
|
1559
|
-
return response.json();
|
|
1560
|
-
}
|
|
1561
|
-
catch (err) {
|
|
1562
|
-
console.error(err);
|
|
1563
|
-
return null;
|
|
1564
|
-
}
|
|
1565
|
-
};
|
|
1566
|
-
async function doRequest(url, method, body) {
|
|
1567
|
-
const traceId = getTraceId();
|
|
1568
|
-
return globalThis?.fetch?.(`${RETAIL_API_BASE_URI}${url}`, {
|
|
1569
|
-
method,
|
|
1570
|
-
headers: {
|
|
1571
|
-
'Content-Type': 'application/json',
|
|
1572
|
-
'X-B3-Sampled': '1',
|
|
1573
|
-
'X-B3-Spanid': traceId,
|
|
1574
|
-
'X-B3-Traceid': traceId,
|
|
1575
|
-
...getAuthorizationHeaders(),
|
|
1576
|
-
},
|
|
1577
|
-
credentials: 'include',
|
|
1578
|
-
body: body ? JSON.stringify(body) : null,
|
|
1579
|
-
});
|
|
1580
|
-
}
|
|
1581
|
-
const getAuthorizationHeaders = () => {
|
|
1582
|
-
const token = sessionStorage.getItem('accessToken');
|
|
1583
|
-
return token ? { Authorization: `Bearer ${token}` } : null;
|
|
1584
|
-
};
|
|
1585
|
-
|
|
1586
|
-
const API$2 = LeadServiceAPI();
|
|
1587
|
-
const sendCode = (body, isRetail) => {
|
|
1588
|
-
return isRetail ? fetchRetail(body) : fetchMain$1(body);
|
|
1589
|
-
};
|
|
1590
|
-
const fetchRetail = (body) => doRequest('/sms/sendCode', 'POST', body)
|
|
1591
|
-
.then((res) => res.text())
|
|
1592
|
-
.then((text) => text === 'OK');
|
|
1593
|
-
const fetchMain$1 = (body) => API$2.sendCode({ phone: body.phoneNumber });
|
|
1594
|
-
|
|
1595
|
-
const SubmitButton$1 = JSX(({ isLoading, disabled, children, className, ...rest }) => (jsxs(Button, { type: "submit", className: style('relative', className), disabled: isLoading || disabled, ...rest, children: [isLoading ? jsx(Loader, { blur: true, size: "small" }) : null, children] })));
|
|
1596
|
-
|
|
1597
|
-
const inputValidStyle = 'border border-solid outline-none border-gray hover:border-primary-hover active:border-primary-text focus:border-primary-text rounded';
|
|
1598
|
-
|
|
1599
|
-
const getValidStyle = (valid) => (valid ? inputValidStyle : 'border-error');
|
|
1600
|
-
|
|
1601
|
-
const renderLabel$1 = (label) => label ? (jsx(Text, { size: "text-m", color: "text-primary-text", font: "font-light", children: label })) : null;
|
|
1602
|
-
|
|
1603
|
-
const Input = JSX(
|
|
1604
|
-
// eslint-disable-next-line max-lines-per-function
|
|
1605
|
-
({ key, className, id, name, type = 'text', label, placeholder, value = '', valid = true, pattern, autoFocus = false, isTextarea = false, disabled = false, children, onChange, onFocus, onBlur, }) => {
|
|
1606
|
-
const inputRef = useRef(null);
|
|
1607
|
-
const handleChange = useCallback((e) => {
|
|
1608
|
-
const valueWithoutSpace = (e.target?.value ?? '').trimStart();
|
|
1609
|
-
onChange && onChange(valueWithoutSpace);
|
|
1610
|
-
}, [onChange]);
|
|
1611
|
-
useEffect(() => {
|
|
1612
|
-
if (autoFocus) {
|
|
1613
|
-
inputRef.current?.focus();
|
|
1614
|
-
}
|
|
1615
|
-
}, [autoFocus, inputRef]);
|
|
1616
|
-
const paddingStyle = children ? 'pr-3xl' : '';
|
|
1617
|
-
const validStyle = getValidStyle(valid);
|
|
1618
|
-
const ariaLabel = label ?? name ?? id;
|
|
1619
|
-
return (jsxs("div", { className: style('relative', className), children: [jsxs("label", { className: "space-y-xs", children: [renderLabel$1(label), isTextarea ? (jsx("textarea", { className: style('block resize-y min-h-24', defaultStyle$1, validStyle), id: style('textarea', id), value: value, name: name || id, placeholder: placeholder, disabled: disabled, "aria-label": ariaLabel, onChange: handleChange, onFocus: onFocus, onBlur: onBlur }, key)) : (jsx("input", { ref: inputRef, className: style('h-14', defaultStyle$1, paddingStyle, validStyle), id: id, type: type, value: value, name: name || id, placeholder: placeholder, pattern: pattern, disabled: disabled, "aria-label": ariaLabel, onChange: handleChange, onFocus: onFocus, onBlur: onBlur }, key))] }), children] }));
|
|
1620
|
-
});
|
|
1621
|
-
const defaultStyle$1 = 'w-full border rounded-md text-primary-text outline-none p-m';
|
|
1622
|
-
|
|
1623
|
-
const ICON_SIZE = { width: '118', height: '24' };
|
|
1624
|
-
|
|
1625
|
-
const logoTitleSizeStyle = '';
|
|
1626
|
-
|
|
1627
|
-
const ICON_VERSION_MAP = {
|
|
1628
|
-
'bg-white': 'color',
|
|
1629
|
-
transparent: 'white',
|
|
1630
|
-
};
|
|
1631
|
-
const SVG_COLOR = {
|
|
1632
|
-
'bg-white': 'text-primary-main',
|
|
1633
|
-
transparent: 'text-white',
|
|
1634
|
-
};
|
|
1635
|
-
const renderImage = (bgColor, image, size) => {
|
|
1636
|
-
const img = image?.src
|
|
1637
|
-
? image
|
|
1638
|
-
: {
|
|
1639
|
-
icon: image?.icon || 'LogoIcon',
|
|
1640
|
-
iconVersion: ICON_VERSION_MAP[bgColor],
|
|
1641
|
-
};
|
|
1642
|
-
return (jsx(Img, { image: img, className: SVG_COLOR[bgColor], width: size?.width, height: size?.height }));
|
|
1643
|
-
};
|
|
1644
|
-
|
|
1645
|
-
const TEXT_COLOR = {
|
|
1646
|
-
'bg-white': 'text-primary-text',
|
|
1647
|
-
transparent: 'text-white',
|
|
1648
|
-
};
|
|
1649
|
-
const Logo = JSX(({ className, href = '/', logo, children, targetBlank, bgColor = 'bg-white', showTitle = true, data, }) => (jsxs("a", { className: style('inline-flex items-center font-sans no-underline', className), href: logo?.href ?? href, target: targetBlank ? '_blank' : '_self', "aria-label": logo?.title ?? 'Россельхозбанк', ...getAspectsAttributes(data), children: [renderImage(bgColor, logo?.image, ICON_SIZE), showTitle
|
|
1650
|
-
? children ?? (jsx("div", { className: "ml-s", children: jsx(Text, { font: "font-medium", color: TEXT_COLOR[bgColor], size: logoTitleSizeStyle, children: logo?.title ?? 'Россельхозбанк' }) }))
|
|
1651
|
-
: null] })));
|
|
1652
|
-
|
|
1653
|
-
const checkCaptcha = (body) => doRequest('/sms/checkCaptcha', 'POST', body)
|
|
1654
|
-
.then((res) => res.text())
|
|
1655
|
-
.then((text) => text !== 'ERROR');
|
|
1656
|
-
|
|
1657
|
-
const createCaptcha = (phoneNumber) => doRequest(`/sms/createCaptcha?phoneNumber=${encodeURIComponent(phoneNumber)}`, 'GET').then(async (res) => (res ? res.blob() : new Blob()));
|
|
1658
|
-
|
|
1659
|
-
const CaptchaDialog = JSX(({ phoneNumber, sendCode, onClose }) => {
|
|
1660
|
-
const [captcha, setCaptcha] = useState('');
|
|
1661
|
-
const [code, setCode] = useState('');
|
|
1662
|
-
const [hasError, setHasError] = useState(false);
|
|
1663
|
-
const [isLoading, { setTrue: startLoading, setFalse: endLoading }] = useBool(false);
|
|
1664
|
-
const { closeAll } = useDialogManager();
|
|
1665
|
-
const handleCheckCaptcha = useCallback(async () => {
|
|
1666
|
-
startLoading();
|
|
1667
|
-
const isValidCode = await checkCaptcha({ captchaText: code });
|
|
1668
|
-
if (isValidCode) {
|
|
1669
|
-
onClose?.();
|
|
1670
|
-
sendCode?.();
|
|
1671
|
-
}
|
|
1672
|
-
else {
|
|
1673
|
-
setHasError(true);
|
|
1674
|
-
}
|
|
1675
|
-
endLoading();
|
|
1676
|
-
}, [code, sendCode]);
|
|
1677
|
-
const handleCreateCaptcha = useCallback(() => {
|
|
1678
|
-
(async () => setCaptcha(URL.createObjectURL(await createCaptcha(phoneNumber))))();
|
|
1679
|
-
}, []);
|
|
1680
|
-
useEffect(handleCreateCaptcha, []);
|
|
1681
|
-
return (jsx(Dialog, { head: jsx(Logo, {}), onClose: onClose, children: jsxs("div", { className: "flex flex-col gap-lg items-center", children: [jsxs("div", { className: "flex", children: [jsx("img", { className: "grow", src: captcha }), jsx(Button, { className: "w-8", embedded: true, onClick: handleCreateCaptcha, children: jsx(Icon, { iconVersion: "normal", name: "RefreshIcon" }) })] }), jsx(Input, { className: "w-80", onChange: setCode, value: code, placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043A\u043E\u0434 \u0441 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438" }), hasError ? jsx("div", { className: "text-error", children: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u043A\u043E\u0434" }) : null, jsxs("div", { className: "flex w-80 justify-between", children: [jsx(Button, { version: "secondary", onClick: closeAll, children: "\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F" }), jsx(SubmitButton$1, { version: "secondary", disabled: !code, onClick: handleCheckCaptcha, children: "\u041E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C" })] }), isLoading ? jsx(Loader, { blur: false }) : null] }) }));
|
|
1682
|
-
});
|
|
1683
|
-
|
|
1684
|
-
const InputCode = JSX(({ values, setValues, hasError, errorText }) => {
|
|
1685
|
-
const [activeIndex, setActiveIndex] = useState(0);
|
|
1686
|
-
const inputRefs = useRef([]);
|
|
1687
|
-
useEffect(() => {
|
|
1688
|
-
inputRefs.current?.[activeIndex]?.focus();
|
|
1689
|
-
}, [activeIndex]);
|
|
1690
|
-
const handleChange = useCallback((index) => (event) => {
|
|
1691
|
-
const { value } = event.currentTarget;
|
|
1692
|
-
const oneValue = value.slice(0, 1);
|
|
1693
|
-
setValues(values.map((_, i) => (i === index ? oneValue : _)));
|
|
1694
|
-
setActiveIndex(index + 1);
|
|
1695
|
-
}, [values]);
|
|
1696
|
-
const handleKeyDown = useCallback((currentIndex) => (event) => {
|
|
1697
|
-
const { key } = event;
|
|
1698
|
-
if (key === 'Backspace' && !values[currentIndex]) {
|
|
1699
|
-
const previousIndex = currentIndex > 0 ? currentIndex - 1 : values.length - 1;
|
|
1700
|
-
const updatedValues = values.map((value, index) => (index === previousIndex ? '' : value));
|
|
1701
|
-
setValues(updatedValues);
|
|
1702
|
-
setActiveIndex(previousIndex);
|
|
1703
|
-
}
|
|
1704
|
-
}, [values]);
|
|
1705
|
-
const handlePaste = useCallback((event) => {
|
|
1706
|
-
event.preventDefault();
|
|
1707
|
-
const pastedData = event.clipboardData.getData('text');
|
|
1708
|
-
const updatedValues = values.map((_, idx) => (idx < pastedData.length ? pastedData[idx] : _));
|
|
1709
|
-
setValues(updatedValues);
|
|
1710
|
-
setActiveIndex(updatedValues.length - 1);
|
|
1711
|
-
}, [values]);
|
|
1712
|
-
return (jsxs("div", { className: "flex flex-col gap-2 text-center", children: [jsx("div", { children: values.map((value, index) => (jsx("input", { type: "number", maxLength: 1, value: value, onChange: handleChange(index), onPaste: handlePaste, ref: (ref) => {
|
|
1713
|
-
if (!inputRefs.current) {
|
|
1714
|
-
inputRefs.current = [];
|
|
1715
|
-
}
|
|
1716
|
-
inputRefs.current[index] = ref;
|
|
1717
|
-
}, onFocus: (event) => event.target.select(), onKeyDown: handleKeyDown(index), className: getInputStyle(index, values, hasError) }, index))) }), hasError ? jsx("div", { className: "text-error", children: errorText }) : null] }));
|
|
1718
|
-
});
|
|
1719
|
-
const getInputStyle = (index, values, hasError = false) => {
|
|
1720
|
-
const isInputEmpty = !values[index];
|
|
1721
|
-
return `w-16 sm:w-20 h-24 text-5xl text-center p-md m-2 border ${getValidStyle(!hasError || !isInputEmpty)} rounded-md caret-transparent outline-none`;
|
|
1722
|
-
};
|
|
1723
|
-
|
|
1724
|
-
const SubmitButton = JSX(({ disabled = false, onClick, text }) => (jsx(Button, { type: "button", onClick: onClick, disabled: disabled, children: jsx(Text, { font: "font-normal", children: text }) })));
|
|
1725
|
-
|
|
1726
|
-
const API$1 = LeadServiceAPI();
|
|
1727
|
-
const checkCode = async (body, isRetail) => {
|
|
1728
|
-
const transformedBody = transformBody(body, isRetail);
|
|
1729
|
-
return isRetail
|
|
1730
|
-
? fetchRetailJSON('/sms/checkCode', 'POST', transformedBody).then(saveToken)
|
|
1731
|
-
: fetchMain(transformedBody).then((res) => {
|
|
1732
|
-
if (res === null) {
|
|
1733
|
-
throw new Error('Неверный код');
|
|
1734
|
-
}
|
|
1735
|
-
});
|
|
1736
|
-
};
|
|
1737
|
-
const saveToken = (data) => {
|
|
1738
|
-
if (data?.access_token && data?.refresh_token) {
|
|
1739
|
-
globalThis.sessionStorage.setItem('accessToken', data.access_token);
|
|
1740
|
-
globalThis.sessionStorage.setItem('refreshToken', data.refresh_token);
|
|
1741
|
-
}
|
|
1742
|
-
};
|
|
1743
|
-
const fetchMain = (body) => API$1.checkCode(body);
|
|
1744
|
-
const transformBody = ({ smsText, smsCodesSetName, body, reqId }, isRetail) => {
|
|
1745
|
-
if (isRetail) {
|
|
1746
|
-
return { smsText, smsCodesSetName };
|
|
1747
|
-
}
|
|
1748
|
-
if (!reqId || !body) {
|
|
1749
|
-
throw new Error('Произошла ошибка, попробуйте позднее');
|
|
1750
|
-
}
|
|
1751
|
-
return { code: smsText, reqId, body };
|
|
1752
|
-
};
|
|
1753
|
-
|
|
1754
|
-
const TIME_TO_RESEND = 180;
|
|
1755
|
-
const useVerifyPhoneDialogSubmit = ({ values, onSuccess, formatData, reqId, isRetail = true, }) => {
|
|
1756
|
-
const sessionStore = useSessionStore();
|
|
1757
|
-
const attempts = sessionStore.smsCode?.attempts || 0;
|
|
1758
|
-
const timer = Math.max(getTimer(sessionStore.smsCode?.sendTime || Date.now()), 0);
|
|
1759
|
-
const [errorText, setErrorText] = useState('');
|
|
1760
|
-
const [isLoading, { setTrue: startLoading, setFalse: endLoading }] = useBool(false);
|
|
1761
|
-
const [timeNextReq, setTimeNextReq] = useState(timer);
|
|
1762
|
-
const resetError = useCallback(() => setErrorText(''), []);
|
|
1763
|
-
const isTimeExpired = Boolean(timeNextReq === 0 && sessionStore.smsCode?.sendTime);
|
|
1764
|
-
const isSubmitButtonDisabled = attempts > 2 || isTimeExpired || !values.every(Boolean);
|
|
1765
|
-
const handleSubmit = useCallback(async () => {
|
|
1766
|
-
try {
|
|
1767
|
-
sessionStore.smsCode = {
|
|
1768
|
-
...sessionStore.smsCode,
|
|
1769
|
-
attempts: attempts + 1,
|
|
1770
|
-
};
|
|
1771
|
-
startLoading();
|
|
1772
|
-
await checkCode({
|
|
1773
|
-
smsText: values.join(''),
|
|
1774
|
-
smsCodesSetName: { key: 'AUTHENTICATION' },
|
|
1775
|
-
body: isRetail ? undefined : formatData,
|
|
1776
|
-
reqId: isRetail ? undefined : reqId,
|
|
1777
|
-
}, isRetail);
|
|
1778
|
-
setTimeNextReq(0);
|
|
1779
|
-
resetError();
|
|
1780
|
-
sessionStore.smsCode = null;
|
|
1781
|
-
await onSuccess?.(values.join(''));
|
|
1782
|
-
}
|
|
1783
|
-
catch {
|
|
1784
|
-
setErrorText(attempts > 1 ? 'Исчерпан лимит ввода смс-кода' : 'Неверный код');
|
|
1785
|
-
}
|
|
1786
|
-
finally {
|
|
1787
|
-
endLoading();
|
|
1788
|
-
}
|
|
1789
|
-
}, [values, attempts]);
|
|
1790
|
-
useEffect(() => {
|
|
1791
|
-
if (isTimeExpired && isRetail) {
|
|
1792
|
-
setErrorText('Код просрочен');
|
|
1793
|
-
}
|
|
1794
|
-
else if (attempts > 2) {
|
|
1795
|
-
setErrorText('Исчерпан лимит ввода смс-кода');
|
|
1796
|
-
}
|
|
1797
|
-
}, [isTimeExpired]);
|
|
1798
|
-
return {
|
|
1799
|
-
handleSubmit,
|
|
1800
|
-
hasError: Boolean(errorText),
|
|
1801
|
-
errorText,
|
|
1802
|
-
isLoading,
|
|
1803
|
-
timeNextReq,
|
|
1804
|
-
isSubmitButtonDisabled,
|
|
1805
|
-
setTimeNextReq,
|
|
1806
|
-
setErrorText,
|
|
1807
|
-
};
|
|
1808
|
-
};
|
|
1809
|
-
const getTimer = (sendTime) => TIME_TO_RESEND - Math.floor((Date.now() - sendTime) / 1000);
|
|
1239
|
+
return [formState, setFormState];
|
|
1240
|
+
}
|
|
1810
1241
|
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
const
|
|
1816
|
-
const
|
|
1817
|
-
const
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1242
|
+
function useForm(initialState, { resetOnSubmit, formValidator, normalizer, onChange, onSubmit } = {}) {
|
|
1243
|
+
const [formState, setFormState] = useNormalizedFormState(initialState, normalizer, onChange);
|
|
1244
|
+
const fieldRefs = useRef(getRefsObject(initialState));
|
|
1245
|
+
const [isDirtyForm, { setTrue: markAsDirty, setFalse: markAsClean }] = useBool(false);
|
|
1246
|
+
const dirtyFieldsMap = useRef({});
|
|
1247
|
+
const [fieldValidatorsMap, { isValid, errors }] = useFormValidator(formState, formValidator);
|
|
1248
|
+
const field = useCallback((fieldName, options = {}) => {
|
|
1249
|
+
const { parse, format, onChange: onFieldChange } = options;
|
|
1250
|
+
const value = formState[fieldName];
|
|
1251
|
+
const isDirty = isDirtyForm || dirtyFieldsMap.current?.[String(fieldName)];
|
|
1252
|
+
const fieldValidator = options?.validator ?? fieldValidatorsMap[fieldName];
|
|
1253
|
+
const fieldErrors = isDirty && fieldValidator ? fieldValidator(value) : [];
|
|
1254
|
+
return {
|
|
1255
|
+
setFieldRef: (_) => {
|
|
1256
|
+
if (fieldRefs.current) {
|
|
1257
|
+
fieldRefs.current[fieldName] = _;
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1260
|
+
fieldRef: fieldRefs.current?.[fieldName],
|
|
1261
|
+
value: format ? format(value) : value,
|
|
1262
|
+
isDirty,
|
|
1263
|
+
errors: fieldValidator && fieldErrors,
|
|
1264
|
+
error: fieldErrors[0],
|
|
1265
|
+
onChange: (_) => {
|
|
1266
|
+
dirtyFieldsMap.current ||= {};
|
|
1267
|
+
dirtyFieldsMap.current[String(fieldName)] = true;
|
|
1268
|
+
const fieldVal = parse ? parse(_) : _;
|
|
1269
|
+
onFieldChange?.(fieldVal);
|
|
1270
|
+
setFormState((prev) => ({ ...prev, [fieldName]: fieldVal }));
|
|
1271
|
+
},
|
|
1272
|
+
};
|
|
1273
|
+
}, [formState, isDirtyForm, fieldValidatorsMap, setFormState]);
|
|
1274
|
+
const update = useCallback((_) => {
|
|
1275
|
+
dirtyFieldsMap.current = _;
|
|
1276
|
+
setFormState(_);
|
|
1277
|
+
}, [setFormState]);
|
|
1278
|
+
const reset = useCallback(() => {
|
|
1279
|
+
dirtyFieldsMap.current = {};
|
|
1280
|
+
markAsClean();
|
|
1281
|
+
setFormState(initialState);
|
|
1282
|
+
}, [initialState, setFormState]);
|
|
1283
|
+
const handleSubmit = useCallback((ev) => {
|
|
1284
|
+
ev.preventDefault();
|
|
1285
|
+
if (isValid) {
|
|
1286
|
+
resetOnSubmit && reset();
|
|
1287
|
+
onSubmit?.(formState, ev);
|
|
1844
1288
|
}
|
|
1845
1289
|
else {
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
useEffect(() => {
|
|
1850
|
-
if (!sessionStore.smsCode?.sendTime && isRetail) {
|
|
1851
|
-
handleSendCode();
|
|
1290
|
+
const errorFieldName = getErrorFieldName(formState, fieldValidatorsMap);
|
|
1291
|
+
markAsDirty();
|
|
1292
|
+
field(errorFieldName).fieldRef?.scrollIntoView({ behavior: 'smooth' });
|
|
1852
1293
|
}
|
|
1853
|
-
}, []);
|
|
1854
|
-
return
|
|
1855
|
-
}
|
|
1856
|
-
const
|
|
1857
|
-
const
|
|
1858
|
-
|
|
1859
|
-
|
|
1294
|
+
}, [resetOnSubmit, formState, isValid, reset, onSubmit]);
|
|
1295
|
+
return [formState, { errors, field, update, reset, onSubmit: handleSubmit }];
|
|
1296
|
+
}
|
|
1297
|
+
const getRefsObject = (initialState) => Object.keys(initialState).reduce((acc, key) => ({ ...acc, [key]: null }), {});
|
|
1298
|
+
const getErrorFieldName = (formState, fieldValidatorsMap = {}) => {
|
|
1299
|
+
const [errorFieldName = ''] = Object.entries(formState).find(([fieldName, value]) => {
|
|
1300
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
1301
|
+
return fieldValidatorsMap[fieldName]?.(value)?.length;
|
|
1302
|
+
}) ?? [];
|
|
1303
|
+
return errorFieldName;
|
|
1304
|
+
};
|
|
1860
1305
|
|
|
1861
1306
|
const ApplicationFormLayout = JSX((props) => {
|
|
1862
1307
|
const { className, title, children, ...rest } = props;
|
|
1863
1308
|
return (jsx(BlockWrapper, { className: className, defaultPadding: "p-6xl", ...rest, children: jsxs("div", { className: "container space-y-lg", children: [title ? jsx(Heading, { headingType: "h3", title: title, className: "@xl:text-center" }) : null, children] }) }));
|
|
1864
1309
|
});
|
|
1865
1310
|
|
|
1311
|
+
function useDialog(Dialog, initialProps = {}) {
|
|
1312
|
+
const { open, close, ...rest } = useDialogManager();
|
|
1313
|
+
const openDialog = useCallback((props, options = {}) => open({
|
|
1314
|
+
dialog: (jsx(Dialog, { ...initialProps, ...props, onClose: () => {
|
|
1315
|
+
close();
|
|
1316
|
+
props.onClose?.();
|
|
1317
|
+
} })),
|
|
1318
|
+
...options,
|
|
1319
|
+
}), [Dialog, open, close]);
|
|
1320
|
+
return { open: openDialog, close, ...rest };
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1866
1323
|
const getConsentDataProcessing = (inputs) => inputs?.find((_) => _?.name === 'consentDataProcessing');
|
|
1867
1324
|
|
|
1868
1325
|
// TODO Базовая функицональность всех Control - надо вынести и привязать к required флагу
|
|
@@ -1886,6 +1343,12 @@
|
|
|
1886
1343
|
return debouncedCallback;
|
|
1887
1344
|
};
|
|
1888
1345
|
|
|
1346
|
+
const noop = () => {
|
|
1347
|
+
// Do nothing
|
|
1348
|
+
};
|
|
1349
|
+
|
|
1350
|
+
const renderLabel$1 = (label) => label ? (jsx(Text, { size: "text-m", color: "text-primary-text", font: "font-light", children: label })) : null;
|
|
1351
|
+
|
|
1889
1352
|
function useEventListener(target, type, listener, options) {
|
|
1890
1353
|
useEffect(() => {
|
|
1891
1354
|
if (!target || !listener) {
|
|
@@ -1909,6 +1372,30 @@
|
|
|
1909
1372
|
return targetRef;
|
|
1910
1373
|
}
|
|
1911
1374
|
|
|
1375
|
+
const inputValidStyle = 'border border-solid outline-none border-gray hover:border-primary-hover active:border-primary-text focus:border-primary-text rounded';
|
|
1376
|
+
|
|
1377
|
+
const getValidStyle = (valid) => (valid ? inputValidStyle : 'border-error');
|
|
1378
|
+
|
|
1379
|
+
const Input = JSX(
|
|
1380
|
+
// eslint-disable-next-line max-lines-per-function
|
|
1381
|
+
({ key, className, id, name, type = 'text', label, placeholder, value = '', valid = true, pattern, autoFocus = false, isTextarea = false, disabled = false, children, onChange, onFocus, onBlur, }) => {
|
|
1382
|
+
const inputRef = useRef(null);
|
|
1383
|
+
const handleChange = useCallback((e) => {
|
|
1384
|
+
const valueWithoutSpace = (e.target?.value ?? '').trimStart();
|
|
1385
|
+
onChange && onChange(valueWithoutSpace);
|
|
1386
|
+
}, [onChange]);
|
|
1387
|
+
useEffect(() => {
|
|
1388
|
+
if (autoFocus) {
|
|
1389
|
+
inputRef.current?.focus();
|
|
1390
|
+
}
|
|
1391
|
+
}, [autoFocus, inputRef]);
|
|
1392
|
+
const paddingStyle = children ? 'pr-3xl' : '';
|
|
1393
|
+
const validStyle = getValidStyle(valid);
|
|
1394
|
+
const ariaLabel = label ?? name ?? id;
|
|
1395
|
+
return (jsxs("div", { className: style('relative', className), children: [jsxs("label", { className: "space-y-xs", children: [renderLabel$1(label), isTextarea ? (jsx("textarea", { className: style('block resize-y min-h-24', defaultStyle$1, validStyle), id: style('textarea', id), value: value, name: name || id, placeholder: placeholder, disabled: disabled, "aria-label": ariaLabel, onChange: handleChange, onFocus: onFocus, onBlur: onBlur }, key)) : (jsx("input", { ref: inputRef, className: style('h-14', defaultStyle$1, paddingStyle, validStyle), id: id, type: type, value: value, name: name || id, placeholder: placeholder, pattern: pattern, disabled: disabled, "aria-label": ariaLabel, onChange: handleChange, onFocus: onFocus, onBlur: onBlur }, key))] }), children] }));
|
|
1396
|
+
});
|
|
1397
|
+
const defaultStyle$1 = 'w-full border rounded-md text-primary-text outline-none p-m';
|
|
1398
|
+
|
|
1912
1399
|
const InputWrapper = JSX(({ className, label, value = '', error, errors, type, isInteger, placeholder, maxLength, inputRef, isOpen, onOpen, onClose, onChange = noop, ...rest }) => {
|
|
1913
1400
|
const popupRef = useOutsideClick(onClose);
|
|
1914
1401
|
const handleChange = useCallback((v) => {
|
|
@@ -2703,9 +2190,9 @@
|
|
|
2703
2190
|
onChange && onChange(!value);
|
|
2704
2191
|
}, [onChange, disabled, value]);
|
|
2705
2192
|
const icon = isRadio ? (jsx("div", { className: "absolute left-1 w-3 h-3 rounded-full bg-primary-main" })) : (jsx(SVG, { paths: CHECK_PATHS, className: "absolute left-1 ml-px block", width: "11", height: "9", fill: "white", viewBox: "0 0 11 9" }));
|
|
2706
|
-
return (jsx("div", { className: className, children: jsxs("label", { className: style('flex items-center relative group/box', getCursorStyle(disabled)), onClick: handleChange, children: [jsx("div", { className: style(defaultCheckStyle, 'm-0', isRadio ? 'rounded-full border-2' : checkboxStyle(value), !disabled && value ? 'border-primary-main' : 'border-gray', disabled ? 'bg-main-disabled' : 'group-hover/box:border-primary-hover'), role: role(isRadio), "aria-checked": Boolean(value), "aria-disabled": Boolean(disabled), "aria-label": text }), value ? icon : null, renderText$
|
|
2193
|
+
return (jsx("div", { className: className, children: jsxs("label", { className: style('flex items-center relative group/box', getCursorStyle(disabled)), onClick: handleChange, children: [jsx("div", { className: style(defaultCheckStyle, 'm-0', isRadio ? 'rounded-full border-2' : checkboxStyle(value), !disabled && value ? 'border-primary-main' : 'border-gray', disabled ? 'bg-main-disabled' : 'group-hover/box:border-primary-hover'), role: role(isRadio), "aria-checked": Boolean(value), "aria-disabled": Boolean(disabled), "aria-label": text }), value ? icon : null, renderText$3(text)] }) }));
|
|
2707
2194
|
});
|
|
2708
|
-
const renderText$
|
|
2195
|
+
const renderText$3 = (text) => text ? (jsx("div", { className: "ml-s", children: jsx(Text, { size: "text-l", font: "font-light", children: text }) })) : null;
|
|
2709
2196
|
const getCursorStyle = (disabled = false) => (disabled ? 'cursor-not-allowed' : 'cursor-pointer');
|
|
2710
2197
|
const role = (isRadio = false) => (isRadio ? 'radio' : 'checkbox');
|
|
2711
2198
|
const checkboxStyle = (value = false) => style('rounded border', { 'bg-primary-main': value });
|
|
@@ -3054,6 +2541,39 @@
|
|
|
3054
2541
|
|
|
3055
2542
|
const renderTitle = (title) => title ? (jsx("div", { className: "@xl:text-center @xl:col-span-2 mb-m", children: jsx(Text, { size: "text-h6", children: title }) })) : null;
|
|
3056
2543
|
|
|
2544
|
+
const themeStyle$1 = {
|
|
2545
|
+
primary: style('text-white bg-primary-main hover:bg-primary-hover active:bg-primary-active', 'group-data-secondary:text-primary-main group-data-secondary:bg-white', 'group-data-secondary:hover:text-white group-data-secondary:hover:bg-primary-hover', 'group-data-secondary:active:bg-primary-active'),
|
|
2546
|
+
secondary: style('text-primary-main bg-main-divider hover:text-white hover:bg-primary-hover active:bg-primary-active', 'group-data-secondary:text-white group-data-secondary:bg-white/20', 'group-data-secondary:hover:bg-primary-hover', 'group-data-secondary:active:bg-primary-active'),
|
|
2547
|
+
};
|
|
2548
|
+
const embeddedStyle = style('group/btn-embedded', 'bg-transparent border border-transparent outline-none');
|
|
2549
|
+
const disabledStyle = style('bg-main-gray text-main-disabled cursor-not-allowed');
|
|
2550
|
+
const Button = JSX(({ className, type = 'button', version = 'primary', shape = 'default', embedded, disabled, role, ariaLabel, data, dataTheme, children, wcmsIgnore, onClick = noop, }) => {
|
|
2551
|
+
const handleClick = useCallback(role !== 'tab' ? handlerDecorator(onClick) : onClick, [
|
|
2552
|
+
role,
|
|
2553
|
+
onClick,
|
|
2554
|
+
]);
|
|
2555
|
+
const aspectsAttrs = useMemo(() => getAspectsAttributes(data), [data]);
|
|
2556
|
+
const isRound = shape === 'round';
|
|
2557
|
+
return (jsx("button", { className: style('font-sans flex items-center gap-xs', {
|
|
2558
|
+
[themeStyle$1[version]]: !disabled && !embedded,
|
|
2559
|
+
[embeddedStyle]: embedded,
|
|
2560
|
+
[disabledStyle]: disabled,
|
|
2561
|
+
}, embedded ? 'justify-between' : 'justify-center', embedded || isRound ? 'p-0' : 'px-9 py-4', {
|
|
2562
|
+
'rounded-md': shape === 'default',
|
|
2563
|
+
'rounded-full': isRound,
|
|
2564
|
+
}, className), type: type, role: role, "aria-label": ariaLabel, disabled: disabled, "aria-disabled": disabled ? 'true' : undefined, "data-theme": dataTheme, "data-wcms-ignore": wcmsIgnore, ...aspectsAttrs, onClick: handleClick, children: children }));
|
|
2565
|
+
});
|
|
2566
|
+
|
|
2567
|
+
const CloseButton = JSX(({ className, onClose }) => (jsx("button", { className: style('flex justify-center items-center w-12 h-12 p-2xs bg-transparent border-none', className), onClick: onClose, title: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C", type: "button", children: jsx(Icon, { name: "CloseIcon", width: "20", height: "20", iconVersion: "gray" }) })));
|
|
2568
|
+
|
|
2569
|
+
const DIALOG_STYLE = {
|
|
2570
|
+
sm: 'max-w-sm top-1/3',
|
|
2571
|
+
lg: 'max-w-lg',
|
|
2572
|
+
'4xl': 'max-w-4xl',
|
|
2573
|
+
none: 'mt-0',
|
|
2574
|
+
};
|
|
2575
|
+
const Dialog = JSX(({ head, maxWidth = '4xl', children, onClose, onClick }) => (jsxs("div", { className: style('relative bg-white p-lg pb-6xl my-6xl mx-auto rounded-lg w-full', DIALOG_STYLE[maxWidth]), role: "dialog", title: "\u0414\u0438\u0430\u043B\u043E\u0433", onClick: onClick, children: [jsxs("div", { className: "sticky py-xl top-0 bg-white z-10", children: [jsx(CloseButton, { className: "absolute top-0 right-0 z-10", onClose: onClose }), jsx("div", { className: "container", children: head })] }), jsx("div", { className: "container", children: children })] })));
|
|
2576
|
+
|
|
3057
2577
|
const ResponseTypeDialog = JSX(({ ok, typeForm, onClose }) => {
|
|
3058
2578
|
const statusIcon = ok ? 'ResponseOKIcon' : 'ResponseFailIcon';
|
|
3059
2579
|
const responseOKDescription = typeForm === 'ANTIFRAUD'
|
|
@@ -3138,34 +2658,203 @@
|
|
|
3138
2658
|
return { ...formState, typeForm: { key: typeForm, text: '' } };
|
|
3139
2659
|
};
|
|
3140
2660
|
|
|
3141
|
-
const
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
2661
|
+
const Loader = JSX(({ color = 'text-primary-main', position = 'absolute', blur = true, size = 'big' }) => (jsx("div", { className: style('flex justify-center items-center h-full w-full z-50', position, {
|
|
2662
|
+
'backdrop-blur': blur,
|
|
2663
|
+
}), children: jsx("div", { className: style('inline-block', 'animate-spin rounded-full', 'border-solid border-current', 'border-r-transparent', size === 'extraSmall' && 'border-2 h-4 w-4', size === 'small' && 'border-4 h-8 w-8', size === 'big' && 'border-8 h-28 w-28', color), role: "status" }) })));
|
|
2664
|
+
|
|
2665
|
+
const SubmitButton$1 = JSX(({ isLoading, disabled, children, className, ...rest }) => (jsxs(Button, { type: "submit", className: style('relative', className), disabled: isLoading || disabled, ...rest, children: [isLoading ? jsx(Loader, { blur: true, size: "small" }) : null, children] })));
|
|
2666
|
+
|
|
2667
|
+
const themeStyle = {
|
|
2668
|
+
primary: themeStyle$1.primary,
|
|
2669
|
+
secondary: themeStyle$1.secondary,
|
|
2670
|
+
white: 'text-primary-main bg-white hover:text-white hover:bg-primary-hover active:bg-white active:text-primary-main',
|
|
2671
|
+
link: 'text-primary-main',
|
|
2672
|
+
gray: themeStyle$1.secondary,
|
|
2673
|
+
transparent: '',
|
|
2674
|
+
'': '',
|
|
2675
|
+
};
|
|
2676
|
+
const Link = JSX((props) => {
|
|
2677
|
+
const link = useLink();
|
|
2678
|
+
const { className, href, target, text, aboveText, version = 'link', rel, ariaLabel, data, children, onClick, } = link(props);
|
|
2679
|
+
const buttonLike = version !== 'link';
|
|
2680
|
+
return (jsx("a", { className: style('group/btn inline-flex items-center h-fit', 'font-sans no-underline select-none', 'border border-transparent focus:border-primary-text focus:border', 'cursor-pointer', {
|
|
2681
|
+
[themeStyle[version]]: Boolean(version),
|
|
2682
|
+
[aboveText ? 'px-9 py-2.5' : 'px-9 py-4']: buttonLike,
|
|
2683
|
+
'rounded-md': buttonLike,
|
|
2684
|
+
}, className), href: href, target: target, rel: rel, "aria-label": ariaLabel ?? `Ссылка на ${text}`, role: href ? 'link' : 'button', onClick: onClick, ...getAspectsAttributes(data), children: children ?? renderText$2(text, aboveText) }));
|
|
2685
|
+
});
|
|
2686
|
+
const renderText$2 = (text, aboveText) => text || aboveText ? (jsxs("div", { className: "whitespace-pre", children: [aboveText ? jsx("div", { className: "font-light text-left text-xs", children: aboveText }) : null, jsx("div", { className: style('text-left', { 'text-s -mt-3xs': Boolean(aboveText) }), children: text })] })) : null;
|
|
2687
|
+
|
|
2688
|
+
const Footnote = JSX(({ text, link }) => (jsxs(Paragraph, { size: "text-l", font: "font-light", color: "text-secondary-text", children: [text ? jsx(Text, { children: text }) : null, link ? (jsx(Link, { ...link, ariaLabel: "\u0443\u0441\u043B\u043E\u0432\u0438\u044F \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043D\u043D\u044B\u0445", children: link.text })) : null] })));
|
|
2689
|
+
|
|
2690
|
+
const agreementText = 'Нажимая кнопку, вы подтверждаете согласие с ';
|
|
2691
|
+
const agreementTextPF = 'Нажимая на кнопку, вы подтверждаете, что клиент дал согласие на ';
|
|
2692
|
+
const renderAgreementSubmit = ({ consentDataProcessing, link, button, typeForm, }) => (jsxs("div", { className: "flex col-span-2 gap-xs flex-col w-full items-baseline", children: [consentDataProcessing ? (jsxs("div", { children: [jsxs("div", { className: "flex gap-3 items-center", children: [jsx(Checkbox, { ...consentDataProcessing }), jsx(Footnote, { link: link })] }), renderErrorText(withValidator(consentDataProcessing, agreementValidator).error)] })) : (jsx(Footnote, { text: typeForm === 'PF' ? agreementTextPF : agreementText, link: link })), jsx(SubmitButton$1, { className: "w-full @xl:w-auto", children: button?.text ? button.text : 'Отправить заявку' })] }));
|
|
2693
|
+
|
|
2694
|
+
const renderContacts = () => (jsxs("div", { className: "space-y-m", children: [jsx(Heading, { headingType: "h6", title: "\u0418\u043B\u0438 \u0441\u0432\u044F\u0436\u0438\u0442\u0435\u0441\u044C \u0441 \u043D\u0430\u043C\u0438 \u0443\u0434\u043E\u0431\u043D\u044B\u043C \u0441\u043F\u043E\u0441\u043E\u0431\u043E\u043C", className: "@xl:text-center" }), jsxs("div", { className: "flex sm:justify-center gap-xl", children: [jsxs("a", { className: "flex gap-s items-center text-primary-text no-underline", href: `tel:8 (800) 200-78-70`, "aria-label": "\u0442\u0435\u043B\u0435\u0444\u043E\u043D 8 (800) 200-78-70", children: [jsx(Img, { image: { icon: 'PhoneIcon' }, width: "24", height: "24" }), jsx("span", { children: "8 (800) 200-78-70" })] }), jsxs("a", { className: "flex gap-s items-center text-primary-text no-underline", "aria-label": "\u043F\u043E\u0447\u0442\u0430 ved@rshb.ru", href: `mailto:ved@rshb.ru`, children: [jsx(Img, { image: { icon: 'MailIcon' }, width: "24", height: "24" }), jsx("span", { children: "ved@rshb.ru" })] })] })] }));
|
|
2695
|
+
|
|
2696
|
+
const useInterval = (handler, period) => {
|
|
2697
|
+
const timer = useRef(null);
|
|
2698
|
+
const stop = useCallback(() => clearInterval(timer.current), []);
|
|
2699
|
+
const start = useCallback(() => {
|
|
2700
|
+
stop();
|
|
2701
|
+
timer.current = setInterval(() => handler(stop), period);
|
|
2702
|
+
}, [handler, period, stop]);
|
|
2703
|
+
useEffect(() => {
|
|
2704
|
+
start();
|
|
2705
|
+
return stop;
|
|
2706
|
+
}, [start, stop]);
|
|
2707
|
+
return { start, stop };
|
|
2708
|
+
};
|
|
2709
|
+
|
|
2710
|
+
function useCountDownTimer({ seconds, period = 1000, onTick, onEnd }) {
|
|
2711
|
+
const counter = useRef(seconds);
|
|
2712
|
+
const handleTick = useCallback((stop) => {
|
|
2713
|
+
counter.current ||= 0;
|
|
2714
|
+
counter.current = Math.max(0, counter.current - 1);
|
|
2715
|
+
try {
|
|
2716
|
+
onTick?.(counter.current);
|
|
2717
|
+
}
|
|
2718
|
+
finally {
|
|
2719
|
+
if (counter.current <= 0) {
|
|
2720
|
+
stop();
|
|
2721
|
+
onEnd?.();
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}, [onTick, onEnd]);
|
|
2725
|
+
const { start } = useInterval(handleTick, period);
|
|
2726
|
+
return useCallback((_) => {
|
|
2727
|
+
counter.current = _;
|
|
2728
|
+
start();
|
|
2729
|
+
}, []);
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
const InputCode = JSX(({ values, setValues, hasError, errorText }) => {
|
|
2733
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
2734
|
+
const inputRefs = useRef([]);
|
|
2735
|
+
useEffect(() => {
|
|
2736
|
+
inputRefs.current?.[activeIndex]?.focus();
|
|
2737
|
+
}, [activeIndex]);
|
|
2738
|
+
const handleChange = useCallback((index) => (event) => {
|
|
2739
|
+
const { value } = event.currentTarget;
|
|
2740
|
+
const oneValue = value.slice(0, 1);
|
|
2741
|
+
setValues(values.map((_, i) => (i === index ? oneValue : _)));
|
|
2742
|
+
setActiveIndex(index + 1);
|
|
2743
|
+
}, [values]);
|
|
2744
|
+
const handleKeyDown = useCallback((currentIndex) => (event) => {
|
|
2745
|
+
const { key } = event;
|
|
2746
|
+
if (key === 'Backspace' && !values[currentIndex]) {
|
|
2747
|
+
const previousIndex = currentIndex > 0 ? currentIndex - 1 : values.length - 1;
|
|
2748
|
+
const updatedValues = values.map((value, index) => (index === previousIndex ? '' : value));
|
|
2749
|
+
setValues(updatedValues);
|
|
2750
|
+
setActiveIndex(previousIndex);
|
|
2751
|
+
}
|
|
2752
|
+
}, [values]);
|
|
2753
|
+
const handlePaste = useCallback((event) => {
|
|
2754
|
+
event.preventDefault();
|
|
2755
|
+
const pastedData = event.clipboardData.getData('text');
|
|
2756
|
+
const updatedValues = values.map((_, idx) => (idx < pastedData.length ? pastedData[idx] : _));
|
|
2757
|
+
setValues(updatedValues);
|
|
2758
|
+
setActiveIndex(updatedValues.length - 1);
|
|
2759
|
+
}, [values]);
|
|
2760
|
+
return (jsxs("div", { className: "flex flex-col gap-2 text-center", children: [jsx("div", { children: values.map((value, index) => (jsx("input", { type: "number", maxLength: 1, value: value, onChange: handleChange(index), onPaste: handlePaste, ref: (ref) => {
|
|
2761
|
+
if (!inputRefs.current) {
|
|
2762
|
+
inputRefs.current = [];
|
|
2763
|
+
}
|
|
2764
|
+
inputRefs.current[index] = ref;
|
|
2765
|
+
}, onFocus: (event) => event.target.select(), onKeyDown: handleKeyDown(index), className: getInputStyle(index, values, hasError) }, index))) }), hasError ? jsx("div", { className: "text-error", children: errorText }) : null] }));
|
|
2766
|
+
});
|
|
2767
|
+
const getInputStyle = (index, values, hasError = false) => {
|
|
2768
|
+
const isInputEmpty = !values[index];
|
|
2769
|
+
return `w-16 sm:w-20 h-24 text-5xl text-center p-md m-2 border ${getValidStyle(!hasError || !isInputEmpty)} rounded-md caret-transparent outline-none`;
|
|
2770
|
+
};
|
|
2771
|
+
|
|
2772
|
+
const SubmitButton = JSX(({ disabled = false, onClick, text }) => (jsx(Button, { type: "button", onClick: onClick, disabled: disabled, children: jsx(Text, { font: "font-normal", children: text }) })));
|
|
2773
|
+
|
|
2774
|
+
const ButtonTitle = JSX(({ className, children }) => (jsx("span", { className: style('inline-flex items-center text-start gap-s group-[]/btn-embedded:text-primary-main', className), children: children })));
|
|
2775
|
+
|
|
2776
|
+
const Timer = JSX(({ className, seconds }) => (jsx("span", { className: className, children: formatTimer(seconds) })));
|
|
2777
|
+
const formatTimer = (seconds) => {
|
|
2778
|
+
const minutes = Math.floor(seconds / 60);
|
|
2779
|
+
return [minutes, seconds % 60].map((_) => String(_).padStart(2, '0')).join(':');
|
|
3149
2780
|
};
|
|
3150
|
-
const Link = JSX((props) => {
|
|
3151
|
-
const link = useLink();
|
|
3152
|
-
const { className, href, target, text, aboveText, version = 'link', rel, ariaLabel, data, children, onClick, } = link(props);
|
|
3153
|
-
const buttonLike = version !== 'link';
|
|
3154
|
-
return (jsx("a", { className: style('group/btn inline-flex items-center h-fit', 'font-sans no-underline select-none', 'border border-transparent focus:border-primary-text focus:border', 'cursor-pointer', {
|
|
3155
|
-
[themeStyle[version]]: Boolean(version),
|
|
3156
|
-
[aboveText ? 'px-9 py-2.5' : 'px-9 py-4']: buttonLike,
|
|
3157
|
-
'rounded-md': buttonLike,
|
|
3158
|
-
}, className), href: href, target: target, rel: rel, "aria-label": ariaLabel ?? `Ссылка на ${text}`, role: href ? 'link' : 'button', onClick: onClick, ...getAspectsAttributes(data), children: children ?? renderText$1(text, aboveText) }));
|
|
3159
|
-
});
|
|
3160
|
-
const renderText$1 = (text, aboveText) => text || aboveText ? (jsxs("div", { className: "whitespace-pre", children: [aboveText ? jsx("div", { className: "font-light text-left text-xs", children: aboveText }) : null, jsx("div", { className: style('text-left', { 'text-s -mt-3xs': Boolean(aboveText) }), children: text })] })) : null;
|
|
3161
2781
|
|
|
3162
|
-
const
|
|
2782
|
+
const VerifyPhoneDialogLayout = JSX(({ children, isLoading, isSubmitButtonDisabled, timeNextReq, onSubmit, onSendCode, values, onChange, errorText, hasError, phone, onClose, }) => (jsx(Dialog, { maxWidth: "lg", onClose: onClose, children: jsxs("div", { className: "flex flex-col gap-xl items-center rounded-md", children: [renderHeadline(phone), jsx(InputCode, { values: values, setValues: onChange, errorText: errorText, hasError: hasError }), renderText$1(timeNextReq, onSendCode), children, renderNextButton(isSubmitButtonDisabled, onSubmit), isLoading ? jsx(Loader, { blur: false }) : null] }) })));
|
|
2783
|
+
const renderHeadline = (phone) => (jsx(Headline, { className: "w-full", title: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430", description: `Мы отправили код на ${phone}`, headlineVersion: "XS", isEmbedded: true, as: "h6" }));
|
|
2784
|
+
const renderNextButton = (disabled, onClick) => (jsx(SubmitButton, { text: "\u0414\u0430\u043B\u0435\u0435", disabled: disabled, onClick: onClick }));
|
|
2785
|
+
const renderText$1 = (timeNextReq, handleSendCode) => timeNextReq ? (jsxs("div", { className: "flex flex-row text-l font-light text-base gap-2xs", children: [jsx("span", { children: " \u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043D\u043E\u0432\u044B\u0439 \u043A\u043E\u0434 \u043C\u043E\u0436\u043D\u043E \u0447\u0435\u0440\u0435\u0437" }), jsx(Timer, { seconds: timeNextReq })] })) : (jsx(Button, { embedded: true, onClick: handleSendCode, children: jsx(ButtonTitle, { children: "\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043D\u043E\u0432\u044B\u0439 \u043A\u043E\u0434" }) }));
|
|
3163
2786
|
|
|
3164
|
-
const
|
|
3165
|
-
const
|
|
3166
|
-
const renderAgreementSubmit = ({ consentDataProcessing, link, button, typeForm, }) => (jsxs("div", { className: "flex col-span-2 gap-xs flex-col w-full items-baseline", children: [consentDataProcessing ? (jsxs("div", { children: [jsxs("div", { className: "flex gap-3 items-center", children: [jsx(Checkbox, { ...consentDataProcessing }), jsx(Footnote, { link: link })] }), renderErrorText(withValidator(consentDataProcessing, agreementValidator).error)] })) : (jsx(Footnote, { text: typeForm === 'PF' ? agreementTextPF : agreementText, link: link })), jsx(SubmitButton$1, { className: "w-full @xl:w-auto", children: button?.text ? button.text : 'Отправить заявку' })] }));
|
|
2787
|
+
const TIME_TO_RESEND$2 = 180;
|
|
2788
|
+
const getTimer = (sendTime) => TIME_TO_RESEND$2 - Math.floor((Date.now() - sendTime) / 1000);
|
|
3167
2789
|
|
|
3168
|
-
const
|
|
2790
|
+
const API$2 = LeadServiceAPI();
|
|
2791
|
+
const useVerifyPhoneDialogSubmit$1 = ({ values, onSuccess, formatData, reqId, }) => {
|
|
2792
|
+
const timer = Math.max(getTimer(Date.now()), 0);
|
|
2793
|
+
const [errorText, setErrorText] = useState('');
|
|
2794
|
+
const [isLoading, { setTrue: startLoading, setFalse: endLoading }] = useBool(false);
|
|
2795
|
+
const [timeNextReq, setTimeNextReq] = useState(timer);
|
|
2796
|
+
const resetError = useCallback(() => setErrorText(''), []);
|
|
2797
|
+
const isSubmitButtonDisabled = !values.every(Boolean);
|
|
2798
|
+
const handleSubmit = useCallback(async () => {
|
|
2799
|
+
try {
|
|
2800
|
+
startLoading();
|
|
2801
|
+
const response = await API$2.checkCode({
|
|
2802
|
+
code: values.join(''),
|
|
2803
|
+
body: formatData,
|
|
2804
|
+
reqId,
|
|
2805
|
+
});
|
|
2806
|
+
if (response?.errorDesc) {
|
|
2807
|
+
setErrorText(response?.errorDesc);
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2810
|
+
setTimeNextReq(0);
|
|
2811
|
+
resetError();
|
|
2812
|
+
onSuccess?.(values.join(''));
|
|
2813
|
+
}
|
|
2814
|
+
catch {
|
|
2815
|
+
setErrorText('Неверный код');
|
|
2816
|
+
}
|
|
2817
|
+
finally {
|
|
2818
|
+
endLoading();
|
|
2819
|
+
}
|
|
2820
|
+
}, [values]);
|
|
2821
|
+
return {
|
|
2822
|
+
handleSubmit,
|
|
2823
|
+
hasError: Boolean(errorText),
|
|
2824
|
+
errorText,
|
|
2825
|
+
isLoading,
|
|
2826
|
+
timeNextReq,
|
|
2827
|
+
isSubmitButtonDisabled,
|
|
2828
|
+
setTimeNextReq,
|
|
2829
|
+
setErrorText,
|
|
2830
|
+
};
|
|
2831
|
+
};
|
|
2832
|
+
|
|
2833
|
+
const API$1 = LeadServiceAPI();
|
|
2834
|
+
const CODE_LENGTH$1 = 4;
|
|
2835
|
+
const TIME_TO_RESEND$1 = 180;
|
|
2836
|
+
const VerifyPhoneDialog$1 = JSX(({ phone, onSuccess = noop, onClose = noop, formatData = {}, reqId }) => {
|
|
2837
|
+
const [values, setValues] = useState(Array(CODE_LENGTH$1).fill(''));
|
|
2838
|
+
const [requestId, setRequestId] = useState(reqId);
|
|
2839
|
+
const { handleSubmit, hasError, errorText, isLoading, timeNextReq, isSubmitButtonDisabled, setTimeNextReq, setErrorText, } = useVerifyPhoneDialogSubmit$1({
|
|
2840
|
+
values,
|
|
2841
|
+
onSuccess,
|
|
2842
|
+
formatData,
|
|
2843
|
+
reqId: requestId ?? '',
|
|
2844
|
+
});
|
|
2845
|
+
const phoneNumber = formatPhone(phone);
|
|
2846
|
+
const restartTimer = useCountDownTimer({ seconds: timeNextReq, onTick: setTimeNextReq });
|
|
2847
|
+
const handleSendCode = useCallback(async () => {
|
|
2848
|
+
const response = await API$1.sendCode({ phone: phoneNumber });
|
|
2849
|
+
if (response) {
|
|
2850
|
+
setTimeNextReq(TIME_TO_RESEND$1);
|
|
2851
|
+
restartTimer(TIME_TO_RESEND$1);
|
|
2852
|
+
setErrorText('');
|
|
2853
|
+
setRequestId(String(response));
|
|
2854
|
+
}
|
|
2855
|
+
}, [phoneNumber, restartTimer, onClose]);
|
|
2856
|
+
return (jsx(VerifyPhoneDialogLayout, { isSubmitButtonDisabled: isSubmitButtonDisabled, onSubmit: handleSubmit, onSendCode: handleSendCode, timeNextReq: timeNextReq, values: values, onChange: setValues, phone: phone, isLoading: isLoading, errorText: errorText, hasError: hasError, onClose: onClose }));
|
|
2857
|
+
});
|
|
3169
2858
|
|
|
3170
2859
|
const API = LeadServiceAPI();
|
|
3171
2860
|
const ApplicationForm = UniBlock(
|
|
@@ -3177,7 +2866,7 @@
|
|
|
3177
2866
|
const aspects = useAspects();
|
|
3178
2867
|
const formValidator = useMemo(() => getFormValidator(inputs), [inputs]);
|
|
3179
2868
|
const responseTypeDialog = useDialog(ResponseTypeDialog);
|
|
3180
|
-
const verifyPhoneDialog = useDialog(VerifyPhoneDialog);
|
|
2869
|
+
const verifyPhoneDialog = useDialog(VerifyPhoneDialog$1);
|
|
3181
2870
|
const handleSubmit = useCallback(async (formData, ev) => {
|
|
3182
2871
|
const formatData = getFormatData({ ...formData, ...additionalParams });
|
|
3183
2872
|
if (endpoint === 'initcorporatelead') {
|
|
@@ -3189,10 +2878,8 @@
|
|
|
3189
2878
|
}
|
|
3190
2879
|
verifyPhoneDialog.open({
|
|
3191
2880
|
phone,
|
|
3192
|
-
withDescription: false,
|
|
3193
2881
|
formatData,
|
|
3194
2882
|
reqId: String(response),
|
|
3195
|
-
isRetail: false,
|
|
3196
2883
|
onSuccess: () => {
|
|
3197
2884
|
verifyPhoneDialog.close();
|
|
3198
2885
|
responseTypeDialog.open({ ok: true, typeForm });
|
|
@@ -3497,6 +3184,42 @@
|
|
|
3497
3184
|
EsiaStatuses["Pending"] = "PENDING";
|
|
3498
3185
|
})(EsiaStatuses || (EsiaStatuses = {}));
|
|
3499
3186
|
|
|
3187
|
+
const getTraceId = () => {
|
|
3188
|
+
const result = new Uint8Array(8);
|
|
3189
|
+
globalThis.crypto.getRandomValues(result);
|
|
3190
|
+
return result.reduce((acc, _) => `${acc}${_.toString(16).padStart(2, '0')}`, '');
|
|
3191
|
+
};
|
|
3192
|
+
|
|
3193
|
+
const fetchRetailJSON = async (url, method, body) => {
|
|
3194
|
+
try {
|
|
3195
|
+
const response = await doRequest(url, method, body);
|
|
3196
|
+
return response.json();
|
|
3197
|
+
}
|
|
3198
|
+
catch (err) {
|
|
3199
|
+
console.error(err);
|
|
3200
|
+
return null;
|
|
3201
|
+
}
|
|
3202
|
+
};
|
|
3203
|
+
async function doRequest(url, method, body) {
|
|
3204
|
+
const traceId = getTraceId();
|
|
3205
|
+
return globalThis?.fetch?.(`${RETAIL_API_BASE_URI}${url}`, {
|
|
3206
|
+
method,
|
|
3207
|
+
headers: {
|
|
3208
|
+
'Content-Type': 'application/json',
|
|
3209
|
+
'X-B3-Sampled': '1',
|
|
3210
|
+
'X-B3-Spanid': traceId,
|
|
3211
|
+
'X-B3-Traceid': traceId,
|
|
3212
|
+
...getAuthorizationHeaders(),
|
|
3213
|
+
},
|
|
3214
|
+
credentials: 'include',
|
|
3215
|
+
body: body ? JSON.stringify(body) : null,
|
|
3216
|
+
});
|
|
3217
|
+
}
|
|
3218
|
+
const getAuthorizationHeaders = () => {
|
|
3219
|
+
const token = sessionStorage.getItem('accessToken');
|
|
3220
|
+
return token ? { Authorization: `Bearer ${token}` } : null;
|
|
3221
|
+
};
|
|
3222
|
+
|
|
3500
3223
|
const getLink = (body) => fetchRetailJSON('/esia/getLink', 'POST', body);
|
|
3501
3224
|
|
|
3502
3225
|
const EsiaLoginBanner = JSX(({ onChangeEsiaStatus, productType }) => {
|
|
@@ -4435,42 +4158,180 @@
|
|
|
4435
4158
|
|
|
4436
4159
|
const API_BASE_URI = '/light-api-cash/v1';
|
|
4437
4160
|
|
|
4438
|
-
const useLeadFormData = (typeField) => {
|
|
4439
|
-
const { data, error } = useAsyncData(`${API_BASE_URI}/dictionary?dictionaryType=${encodeURIComponent(typeField)}`, fetchData);
|
|
4440
|
-
if (data && 'errorMessage' in data) {
|
|
4441
|
-
return { error };
|
|
4442
|
-
}
|
|
4443
|
-
return { data: data, error };
|
|
4444
|
-
};
|
|
4445
|
-
const fetchData = async (url) => {
|
|
4446
|
-
const result = await fetchJSON(url, { method: 'POST' });
|
|
4447
|
-
return result || [];
|
|
4448
|
-
};
|
|
4161
|
+
const useLeadFormData = (typeField) => {
|
|
4162
|
+
const { data, error } = useAsyncData(`${API_BASE_URI}/dictionary?dictionaryType=${encodeURIComponent(typeField)}`, fetchData);
|
|
4163
|
+
if (data && 'errorMessage' in data) {
|
|
4164
|
+
return { error };
|
|
4165
|
+
}
|
|
4166
|
+
return { data: data, error };
|
|
4167
|
+
};
|
|
4168
|
+
const fetchData = async (url) => {
|
|
4169
|
+
const result = await fetchJSON(url, { method: 'POST' });
|
|
4170
|
+
return result || [];
|
|
4171
|
+
};
|
|
4172
|
+
|
|
4173
|
+
const AddressRetailField = JSX(({ field, input }) => {
|
|
4174
|
+
const [offices, setOffices] = useState([]);
|
|
4175
|
+
const { data } = useLeadFormData('REGION_RF');
|
|
4176
|
+
const regionValue = field('regionRetail')?.value || {};
|
|
4177
|
+
const addressField = field(input?.name ?? '');
|
|
4178
|
+
useEffect(() => {
|
|
4179
|
+
(async () => {
|
|
4180
|
+
const officesList = await fetchRegionOffices(regionValue?.key ?? '');
|
|
4181
|
+
setOffices(officesList);
|
|
4182
|
+
})();
|
|
4183
|
+
if (regionValue?.key) {
|
|
4184
|
+
addressField.onChange?.('');
|
|
4185
|
+
}
|
|
4186
|
+
}, [regionValue.key]);
|
|
4187
|
+
const { points } = useOfficesAtmsMapData({
|
|
4188
|
+
data: offices,
|
|
4189
|
+
filtrationState: {},
|
|
4190
|
+
getBalloon: getOfficePoint,
|
|
4191
|
+
});
|
|
4192
|
+
return (jsxs("div", { children: [jsx(SelectControl, { label: "\u0410\u0434\u0440\u0435\u0441 \u043E\u0442\u0434\u0435\u043B\u0435\u043D\u0438\u044F", placeholder: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043E\u0442\u0434\u0435\u043B\u0435\u043D\u0438\u0435", options: offices.map(({ id, address = '' }) => ({
|
|
4193
|
+
key: id?.toString() || '',
|
|
4194
|
+
text: address,
|
|
4195
|
+
})), ...addressField, isSearch: true }), jsx("div", { className: "h-[600px]", children: jsx(ClientOnly, { children: jsx(YandexMap, { points: points, isLoad: !data, className: "h-full", selectedAddress: addressField?.value?.text }) }) })] }));
|
|
4196
|
+
});
|
|
4197
|
+
|
|
4198
|
+
function copy(source, target) {
|
|
4199
|
+
for (const [k, v] of source.entries()) {
|
|
4200
|
+
if (v !== null && v !== undefined) {
|
|
4201
|
+
target.setItem(k, v);
|
|
4202
|
+
}
|
|
4203
|
+
else {
|
|
4204
|
+
target.removeItem(k);
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
|
|
4209
|
+
function replicate(primary, secondary) {
|
|
4210
|
+
copy(primary, secondary);
|
|
4211
|
+
copy(secondary, primary);
|
|
4212
|
+
return primary.bus.watch(({ type, event }) => {
|
|
4213
|
+
if (event !== null && event !== undefined) {
|
|
4214
|
+
secondary.setItem(type, event);
|
|
4215
|
+
}
|
|
4216
|
+
else {
|
|
4217
|
+
secondary.removeItem(type);
|
|
4218
|
+
}
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
4221
|
+
|
|
4222
|
+
class StorageAdapter {
|
|
4223
|
+
storage;
|
|
4224
|
+
bus;
|
|
4225
|
+
get size() {
|
|
4226
|
+
return this.storage?.length ?? 0;
|
|
4227
|
+
}
|
|
4228
|
+
constructor(storage, bus = new EventBus()) {
|
|
4229
|
+
this.storage = storage;
|
|
4230
|
+
this.bus = bus;
|
|
4231
|
+
}
|
|
4232
|
+
hasItem(key) {
|
|
4233
|
+
return Boolean(this.storage?.getItem(String(key)));
|
|
4234
|
+
}
|
|
4235
|
+
getItem(key) {
|
|
4236
|
+
const _ = this.storage?.getItem(String(key)) ?? null;
|
|
4237
|
+
try {
|
|
4238
|
+
return JSON.parse(String(_));
|
|
4239
|
+
}
|
|
4240
|
+
catch (ex) {
|
|
4241
|
+
return null;
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
4244
|
+
entries() {
|
|
4245
|
+
return Array.from({ length: this.size }, (_, i) => {
|
|
4246
|
+
const k = String(this.storage?.key(i));
|
|
4247
|
+
return [k, this.getItem(k)];
|
|
4248
|
+
});
|
|
4249
|
+
}
|
|
4250
|
+
setItem(key, value) {
|
|
4251
|
+
if (value !== null) {
|
|
4252
|
+
this.storage?.setItem(String(key), JSON.stringify(value));
|
|
4253
|
+
}
|
|
4254
|
+
else {
|
|
4255
|
+
this.storage?.removeItem(String(key));
|
|
4256
|
+
}
|
|
4257
|
+
this.bus?.subject(key, value);
|
|
4258
|
+
}
|
|
4259
|
+
removeItem(key) {
|
|
4260
|
+
this.storage?.removeItem(String(key));
|
|
4261
|
+
this.bus?.subject(key, null);
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4265
|
+
class Store {
|
|
4266
|
+
bus;
|
|
4267
|
+
store = new Map();
|
|
4268
|
+
get size() {
|
|
4269
|
+
return this.store.size;
|
|
4270
|
+
}
|
|
4271
|
+
constructor(bus = new EventBus()) {
|
|
4272
|
+
this.bus = bus;
|
|
4273
|
+
}
|
|
4274
|
+
hasItem(key) {
|
|
4275
|
+
return this.store.has(key);
|
|
4276
|
+
}
|
|
4277
|
+
getItem(key) {
|
|
4278
|
+
return this.store.get(key);
|
|
4279
|
+
}
|
|
4280
|
+
entries() {
|
|
4281
|
+
return this.store.entries();
|
|
4282
|
+
}
|
|
4283
|
+
setItem(key, value) {
|
|
4284
|
+
this.store.set(key, value);
|
|
4285
|
+
this.bus.subject(key, value);
|
|
4286
|
+
}
|
|
4287
|
+
removeItem(key) {
|
|
4288
|
+
this.store.delete(key);
|
|
4289
|
+
this.bus.subject(key, null);
|
|
4290
|
+
}
|
|
4291
|
+
}
|
|
4292
|
+
|
|
4293
|
+
function useRerender() {
|
|
4294
|
+
const [, setCount] = useState(0);
|
|
4295
|
+
return useCallback(() => setCount(_ => (_ + 1) % (1 << 16)), []);
|
|
4296
|
+
}
|
|
4449
4297
|
|
|
4450
|
-
const
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4298
|
+
const DEFAULT_METHODS = {};
|
|
4299
|
+
/**
|
|
4300
|
+
* MobX like reactivity (simplified).
|
|
4301
|
+
* Can be used to migrate from Redux/MobX or something else
|
|
4302
|
+
*
|
|
4303
|
+
* @param store
|
|
4304
|
+
* @returns reactive proxy backed by store
|
|
4305
|
+
*/
|
|
4306
|
+
function useStore(store, methods = DEFAULT_METHODS) {
|
|
4307
|
+
const deps = useRef(null);
|
|
4308
|
+
const render = useRerender();
|
|
4309
|
+
useEffect(() => store.bus.watch(ev => {
|
|
4310
|
+
if (deps.current?.has(String(ev.type))) {
|
|
4311
|
+
render();
|
|
4312
|
+
}
|
|
4313
|
+
}), [store, render]);
|
|
4314
|
+
return useMemo(() => new Proxy(methods, {
|
|
4315
|
+
get(_, key) {
|
|
4316
|
+
deps.current ||= new Set();
|
|
4317
|
+
deps.current.add(key);
|
|
4318
|
+
return store.getItem(key);
|
|
4319
|
+
},
|
|
4320
|
+
has(_, key) {
|
|
4321
|
+
deps.current ||= new Set();
|
|
4322
|
+
deps.current.add(key);
|
|
4323
|
+
return store.hasItem(key);
|
|
4324
|
+
},
|
|
4325
|
+
set(_, key, value) {
|
|
4326
|
+
store.setItem(key, value);
|
|
4327
|
+
return true;
|
|
4328
|
+
},
|
|
4329
|
+
deleteProperty(_, key) {
|
|
4330
|
+
store.removeItem(key);
|
|
4331
|
+
return true;
|
|
4332
|
+
}
|
|
4333
|
+
}), [store]);
|
|
4334
|
+
}
|
|
4474
4335
|
|
|
4475
4336
|
const localStore = new Store(); // localStorage cache
|
|
4476
4337
|
replicate(localStore, new StorageAdapter(globalThis?.localStorage));
|
|
@@ -5699,6 +5560,12 @@
|
|
|
5699
5560
|
|
|
5700
5561
|
const renderSubmitButton = (button, isSending = false) => (jsx(SubmitButton$1, { className: "w-full @xl:w-auto", isLoading: isSending, children: button?.text ? button.text : 'Отправить заявку' }));
|
|
5701
5562
|
|
|
5563
|
+
const sessionStore = new Store(); // sessionStorage cache
|
|
5564
|
+
replicate(sessionStore, new StorageAdapter(globalThis?.sessionStorage));
|
|
5565
|
+
function useSessionStore() {
|
|
5566
|
+
return useStore(sessionStore);
|
|
5567
|
+
}
|
|
5568
|
+
|
|
5702
5569
|
const createDraftTask = async (body) => {
|
|
5703
5570
|
const res = await fetchRetailJSON('/user-data/createDraftTask', 'POST', body);
|
|
5704
5571
|
return res || {};
|
|
@@ -5727,6 +5594,171 @@
|
|
|
5727
5594
|
|
|
5728
5595
|
const updateUserTask = (body) => doRequest('/user-data/updateUserTask', 'PUT', body);
|
|
5729
5596
|
|
|
5597
|
+
const sendCode = (body) => doRequest('/sms/sendCode', 'POST', body)
|
|
5598
|
+
.then((res) => res.text())
|
|
5599
|
+
.then((text) => text === 'OK');
|
|
5600
|
+
|
|
5601
|
+
const ICON_SIZE = { width: '118', height: '24' };
|
|
5602
|
+
|
|
5603
|
+
const logoTitleSizeStyle = '';
|
|
5604
|
+
|
|
5605
|
+
const ICON_VERSION_MAP = {
|
|
5606
|
+
'bg-white': 'color',
|
|
5607
|
+
transparent: 'white',
|
|
5608
|
+
};
|
|
5609
|
+
const SVG_COLOR = {
|
|
5610
|
+
'bg-white': 'text-primary-main',
|
|
5611
|
+
transparent: 'text-white',
|
|
5612
|
+
};
|
|
5613
|
+
const renderImage = (bgColor, image, size) => {
|
|
5614
|
+
const img = image?.src
|
|
5615
|
+
? image
|
|
5616
|
+
: {
|
|
5617
|
+
icon: image?.icon || 'LogoIcon',
|
|
5618
|
+
iconVersion: ICON_VERSION_MAP[bgColor],
|
|
5619
|
+
};
|
|
5620
|
+
return (jsx(Img, { image: img, className: SVG_COLOR[bgColor], width: size?.width, height: size?.height }));
|
|
5621
|
+
};
|
|
5622
|
+
|
|
5623
|
+
const TEXT_COLOR = {
|
|
5624
|
+
'bg-white': 'text-primary-text',
|
|
5625
|
+
transparent: 'text-white',
|
|
5626
|
+
};
|
|
5627
|
+
const Logo = JSX(({ className, href = '/', logo, children, targetBlank, bgColor = 'bg-white', showTitle = true, data, }) => (jsxs("a", { className: style('inline-flex items-center font-sans no-underline', className), href: logo?.href ?? href, target: targetBlank ? '_blank' : '_self', "aria-label": logo?.title ?? 'Россельхозбанк', ...getAspectsAttributes(data), children: [renderImage(bgColor, logo?.image, ICON_SIZE), showTitle
|
|
5628
|
+
? children ?? (jsx("div", { className: "ml-s", children: jsx(Text, { font: "font-medium", color: TEXT_COLOR[bgColor], size: logoTitleSizeStyle, children: logo?.title ?? 'Россельхозбанк' }) }))
|
|
5629
|
+
: null] })));
|
|
5630
|
+
|
|
5631
|
+
const checkCaptcha = (body) => doRequest('/sms/checkCaptcha', 'POST', body)
|
|
5632
|
+
.then((res) => res.text())
|
|
5633
|
+
.then((text) => text !== 'ERROR');
|
|
5634
|
+
|
|
5635
|
+
const createCaptcha = (phoneNumber) => doRequest(`/sms/createCaptcha?phoneNumber=${encodeURIComponent(phoneNumber)}`, 'GET').then(async (res) => (res ? res.blob() : new Blob()));
|
|
5636
|
+
|
|
5637
|
+
const CaptchaDialog = JSX(({ phoneNumber, sendCode, onClose }) => {
|
|
5638
|
+
const [captcha, setCaptcha] = useState('');
|
|
5639
|
+
const [code, setCode] = useState('');
|
|
5640
|
+
const [hasError, setHasError] = useState(false);
|
|
5641
|
+
const [isLoading, { setTrue: startLoading, setFalse: endLoading }] = useBool(false);
|
|
5642
|
+
const { closeAll } = useDialogManager();
|
|
5643
|
+
const handleCheckCaptcha = useCallback(async () => {
|
|
5644
|
+
startLoading();
|
|
5645
|
+
const isValidCode = await checkCaptcha({ captchaText: code });
|
|
5646
|
+
if (isValidCode) {
|
|
5647
|
+
onClose?.();
|
|
5648
|
+
sendCode?.();
|
|
5649
|
+
}
|
|
5650
|
+
else {
|
|
5651
|
+
setHasError(true);
|
|
5652
|
+
}
|
|
5653
|
+
endLoading();
|
|
5654
|
+
}, [code, sendCode]);
|
|
5655
|
+
const handleCreateCaptcha = useCallback(() => {
|
|
5656
|
+
(async () => setCaptcha(URL.createObjectURL(await createCaptcha(phoneNumber))))();
|
|
5657
|
+
}, []);
|
|
5658
|
+
useEffect(handleCreateCaptcha, []);
|
|
5659
|
+
return (jsx(Dialog, { head: jsx(Logo, {}), onClose: onClose, children: jsxs("div", { className: "flex flex-col gap-lg items-center", children: [jsxs("div", { className: "flex", children: [jsx("img", { className: "grow", src: captcha }), jsx(Button, { className: "w-8", embedded: true, onClick: handleCreateCaptcha, children: jsx(Icon, { iconVersion: "normal", name: "RefreshIcon" }) })] }), jsx(Input, { className: "w-80", onChange: setCode, value: code, placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043A\u043E\u0434 \u0441 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438" }), hasError ? jsx("div", { className: "text-error", children: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u043A\u043E\u0434" }) : null, jsxs("div", { className: "flex w-80 justify-between", children: [jsx(Button, { version: "secondary", onClick: closeAll, children: "\u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F" }), jsx(SubmitButton$1, { version: "secondary", disabled: !code, onClick: handleCheckCaptcha, children: "\u041E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C" })] }), isLoading ? jsx(Loader, { blur: false }) : null] }) }));
|
|
5660
|
+
});
|
|
5661
|
+
|
|
5662
|
+
const checkCode = async (body) => fetchRetailJSON('/sms/checkCode', 'POST', body).then(saveToken);
|
|
5663
|
+
const saveToken = (data) => {
|
|
5664
|
+
if (data?.access_token && data?.refresh_token) {
|
|
5665
|
+
globalThis.sessionStorage.setItem('accessToken', data.access_token);
|
|
5666
|
+
globalThis.sessionStorage.setItem('refreshToken', data.refresh_token);
|
|
5667
|
+
}
|
|
5668
|
+
};
|
|
5669
|
+
|
|
5670
|
+
const TIME_TO_RESEND = 180;
|
|
5671
|
+
const useVerifyPhoneDialogSubmit = ({ values, onSuccess, }) => {
|
|
5672
|
+
const sessionStore = useSessionStore();
|
|
5673
|
+
const attempts = sessionStore.smsCode?.attempts || 0;
|
|
5674
|
+
const timer = Math.max(getTimer(sessionStore.smsCode?.sendTime || Date.now()), 0);
|
|
5675
|
+
const [errorText, setErrorText] = useState('');
|
|
5676
|
+
const [isLoading, { setTrue: startLoading, setFalse: endLoading }] = useBool(false);
|
|
5677
|
+
const [timeNextReq, setTimeNextReq] = useState(timer);
|
|
5678
|
+
const resetError = useCallback(() => setErrorText(''), []);
|
|
5679
|
+
const isTimeExpired = Boolean(timeNextReq === 0 && sessionStore.smsCode?.sendTime);
|
|
5680
|
+
const isSubmitButtonDisabled = attempts > 2 || isTimeExpired || !values.every(Boolean);
|
|
5681
|
+
const handleSubmit = useCallback(async () => {
|
|
5682
|
+
try {
|
|
5683
|
+
sessionStore.smsCode = {
|
|
5684
|
+
...sessionStore.smsCode,
|
|
5685
|
+
attempts: attempts + 1,
|
|
5686
|
+
};
|
|
5687
|
+
startLoading();
|
|
5688
|
+
await checkCode({
|
|
5689
|
+
smsText: values.join(''),
|
|
5690
|
+
smsCodesSetName: { key: 'AUTHENTICATION' },
|
|
5691
|
+
});
|
|
5692
|
+
setTimeNextReq(0);
|
|
5693
|
+
resetError();
|
|
5694
|
+
sessionStore.smsCode = null;
|
|
5695
|
+
onSuccess?.(values.join(''));
|
|
5696
|
+
}
|
|
5697
|
+
catch {
|
|
5698
|
+
setErrorText(attempts > 1 ? 'Исчерпан лимит ввода смс-кода' : 'Неверный код');
|
|
5699
|
+
}
|
|
5700
|
+
finally {
|
|
5701
|
+
endLoading();
|
|
5702
|
+
}
|
|
5703
|
+
}, [values, attempts]);
|
|
5704
|
+
useEffect(() => {
|
|
5705
|
+
if (isTimeExpired) {
|
|
5706
|
+
setErrorText('Код просрочен');
|
|
5707
|
+
}
|
|
5708
|
+
else if (attempts > 2) {
|
|
5709
|
+
setErrorText('Исчерпан лимит ввода смс-кода');
|
|
5710
|
+
}
|
|
5711
|
+
}, [isTimeExpired]);
|
|
5712
|
+
return {
|
|
5713
|
+
handleSubmit,
|
|
5714
|
+
hasError: Boolean(errorText),
|
|
5715
|
+
errorText,
|
|
5716
|
+
isLoading,
|
|
5717
|
+
timeNextReq,
|
|
5718
|
+
isSubmitButtonDisabled,
|
|
5719
|
+
setTimeNextReq,
|
|
5720
|
+
setErrorText,
|
|
5721
|
+
};
|
|
5722
|
+
};
|
|
5723
|
+
|
|
5724
|
+
const CODE_LENGTH = 4;
|
|
5725
|
+
const VerifyPhoneDialog = JSX(({ phone, withDescription = true, consents, onSuccess = noop, onClose = noop }) => {
|
|
5726
|
+
const [values, setValues] = useState(Array(CODE_LENGTH).fill(''));
|
|
5727
|
+
const sessionStore = useSessionStore();
|
|
5728
|
+
const { handleSubmit, hasError, errorText, isLoading, timeNextReq, isSubmitButtonDisabled, setTimeNextReq, setErrorText, } = useVerifyPhoneDialogSubmit({
|
|
5729
|
+
values,
|
|
5730
|
+
onSuccess,
|
|
5731
|
+
});
|
|
5732
|
+
const captchaDialog = useDialog(CaptchaDialog);
|
|
5733
|
+
const phoneNumber = formatPhone(phone);
|
|
5734
|
+
const restartTimer = useCountDownTimer({ seconds: timeNextReq, onTick: setTimeNextReq });
|
|
5735
|
+
const handleSendCode = useCallback(async () => {
|
|
5736
|
+
const response = await sendCode({
|
|
5737
|
+
phoneNumber,
|
|
5738
|
+
smsCodesSetName: { key: 'AUTHENTICATION' },
|
|
5739
|
+
});
|
|
5740
|
+
if (response) {
|
|
5741
|
+
setTimeNextReq(TIME_TO_RESEND);
|
|
5742
|
+
restartTimer(TIME_TO_RESEND);
|
|
5743
|
+
setErrorText('');
|
|
5744
|
+
sessionStore.smsCode = {
|
|
5745
|
+
sendTime: Date.now(),
|
|
5746
|
+
attempts: 0,
|
|
5747
|
+
};
|
|
5748
|
+
}
|
|
5749
|
+
else {
|
|
5750
|
+
captchaDialog.open({ phoneNumber, sendCode: handleSendCode });
|
|
5751
|
+
}
|
|
5752
|
+
}, [phoneNumber, restartTimer, onClose]);
|
|
5753
|
+
useEffect(() => {
|
|
5754
|
+
if (!sessionStore.smsCode?.sendTime) {
|
|
5755
|
+
handleSendCode();
|
|
5756
|
+
}
|
|
5757
|
+
}, []);
|
|
5758
|
+
return (jsx(VerifyPhoneDialogLayout, { isSubmitButtonDisabled: isSubmitButtonDisabled, onSubmit: handleSubmit, onSendCode: handleSendCode, timeNextReq: timeNextReq, values: values, onChange: setValues, phone: phone, isLoading: isLoading, errorText: errorText, hasError: hasError, onClose: onClose, children: renderDescription$2(consents, withDescription) }));
|
|
5759
|
+
});
|
|
5760
|
+
const renderDescription$2 = (consents, isRender = false) => isRender ? (jsxs(RichText, { itemSize: "list-s", children: [jsx("span", { children: "\u0412\u0432\u043E\u0434\u044F \u043A\u043E\u0434, \u044F \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E, \u0447\u0442\u043E \u043E\u0437\u043D\u0430\u043A\u043E\u043C\u043B\u0435\u043D \u0438 \u043F\u043E\u0434\u043F\u0438\u0441\u044B\u0432\u0430\u044E: " }), jsx("ul", { children: consents?.map((_, i) => (jsx("li", { children: _ }, `${_}-${i}`))) })] })) : null;
|
|
5761
|
+
|
|
5730
5762
|
const defaultConsentText = {
|
|
5731
5763
|
title: 'Подпишите согласие на запрос в БКИ',
|
|
5732
5764
|
description: 'Согласие на запрос в Бюро кредитных историй (БКИ) ускорит решение по кредиту',
|
|
@@ -10381,7 +10413,7 @@
|
|
|
10381
10413
|
};
|
|
10382
10414
|
const handleInputSell = (setCalcState, currencyRatesSell) => (value, currencyFrom, currencyTo) => {
|
|
10383
10415
|
setCalcState({ inputSell: formatValue(value), selectBuy: currencyTo });
|
|
10384
|
-
const rate = currencyRatesSell.find((_) => _.currency?.currency === currencyTo)?.
|
|
10416
|
+
const rate = currencyRatesSell.find((_) => _.currency?.currency === currencyTo)?.saleExchangeRate ||
|
|
10385
10417
|
currencyRatesSell.find((_) => _.currency?.currency === currencyFrom)?.buyExchangeRate;
|
|
10386
10418
|
if (rate) {
|
|
10387
10419
|
setCalcState({
|
|
@@ -10391,7 +10423,7 @@
|
|
|
10391
10423
|
};
|
|
10392
10424
|
const handleInputBuy = (setCalcState, currencyRatesBuy) => (value, currencyTo, currencyFrom) => {
|
|
10393
10425
|
setCalcState({ inputBuy: formatValue(value), selectSell: currencyFrom });
|
|
10394
|
-
const rate = currencyRatesBuy.find((_) => _.currency?.currency === currencyFrom)?.
|
|
10426
|
+
const rate = currencyRatesBuy.find((_) => _.currency?.currency === currencyFrom)?.buyExchangeRate ||
|
|
10395
10427
|
currencyRatesBuy.find((_) => _.currency?.currency === currencyTo)?.saleExchangeRate;
|
|
10396
10428
|
if (rate) {
|
|
10397
10429
|
setCalcState({
|
|
@@ -12021,7 +12053,7 @@
|
|
|
12021
12053
|
slots: () => [HEADER_SLOT, FOOTER_SLOT, STICKY_FOOTER_SLOT],
|
|
12022
12054
|
});
|
|
12023
12055
|
|
|
12024
|
-
const packageVersion = "0.14.
|
|
12056
|
+
const packageVersion = "0.14.912";
|
|
12025
12057
|
|
|
12026
12058
|
exports.Blocks = Blocks;
|
|
12027
12059
|
exports.ContentPage = ContentPage;
|