@redneckz/wildless-cms-uni-blocks 0.14.623 → 0.14.625

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/bundle/blocks.schema.json +1 -1
  2. package/bundle/bundle.umd.js +1040 -981
  3. package/bundle/bundle.umd.min.js +1 -1
  4. package/bundle/components/CreditForm/getInitialFormState.d.ts +2 -2
  5. package/bundle/components/OfficesAtmsMap/useOfficesAtmsMapData.d.ts +20 -0
  6. package/bundle/hooks/useRegions.d.ts +2 -0
  7. package/bundle/ui-kit/FormField/Fields/RetailAddressField.d.ts +2 -0
  8. package/bundle/ui-kit/FormField/Fields/RetailRegionField.d.ts +2 -0
  9. package/bundle/ui-kit/FormField/NameFieldDef.d.ts +1 -1
  10. package/bundle/ui-kit/FormField/validators.d.ts +1 -1
  11. package/bundle/ui-kit/YandexMap/YandexMap.d.ts +1 -0
  12. package/dist/components/CreditForm/creditFormStepsData.js +2 -2
  13. package/dist/components/CreditForm/creditFormStepsData.js.map +1 -1
  14. package/dist/components/CreditForm/getInitialFormState.d.ts +2 -2
  15. package/dist/components/CreditForm/getInitialFormState.js +2 -2
  16. package/dist/components/CreditForm/getInitialFormState.js.map +1 -1
  17. package/dist/components/OfficesAtmsMap/OfficesAtmsMapLayout.js +8 -21
  18. package/dist/components/OfficesAtmsMap/OfficesAtmsMapLayout.js.map +1 -1
  19. package/dist/components/OfficesAtmsMap/useOfficesAtmsMapData.d.ts +20 -0
  20. package/dist/components/OfficesAtmsMap/useOfficesAtmsMapData.js +31 -0
  21. package/dist/components/OfficesAtmsMap/useOfficesAtmsMapData.js.map +1 -0
  22. package/dist/hooks/useRegions.d.ts +2 -0
  23. package/dist/hooks/useRegions.js.map +1 -1
  24. package/dist/ui-kit/FormField/Fields/RetailAddressField.d.ts +2 -0
  25. package/dist/ui-kit/FormField/Fields/RetailAddressField.js +38 -0
  26. package/dist/ui-kit/FormField/Fields/RetailAddressField.js.map +1 -0
  27. package/dist/ui-kit/FormField/Fields/RetailRegionField.d.ts +2 -0
  28. package/dist/ui-kit/FormField/Fields/RetailRegionField.js +14 -0
  29. package/dist/ui-kit/FormField/Fields/RetailRegionField.js.map +1 -0
  30. package/dist/ui-kit/FormField/NameFieldDef.d.ts +1 -1
  31. package/dist/ui-kit/FormField/getField.js +4 -1
  32. package/dist/ui-kit/FormField/getField.js.map +1 -1
  33. package/dist/ui-kit/FormField/getObjectValidator.js +8 -6
  34. package/dist/ui-kit/FormField/getObjectValidator.js.map +1 -1
  35. package/dist/ui-kit/FormField/validators.d.ts +1 -1
  36. package/dist/ui-kit/FormField/validators.js +6 -5
  37. package/dist/ui-kit/FormField/validators.js.map +1 -1
  38. package/dist/ui-kit/VerifyPhoneDialog/handleSendCode.js +7 -3
  39. package/dist/ui-kit/VerifyPhoneDialog/handleSendCode.js.map +1 -1
  40. package/dist/ui-kit/YandexMap/YandexMap.d.ts +1 -0
  41. package/dist/ui-kit/YandexMap/YandexMap.js +12 -2
  42. package/dist/ui-kit/YandexMap/YandexMap.js.map +1 -1
  43. package/lib/components/CreditForm/creditFormStepsData.js +2 -2
  44. package/lib/components/CreditForm/creditFormStepsData.js.map +1 -1
  45. package/lib/components/CreditForm/getInitialFormState.d.ts +2 -2
  46. package/lib/components/CreditForm/getInitialFormState.js +2 -2
  47. package/lib/components/CreditForm/getInitialFormState.js.map +1 -1
  48. package/lib/components/OfficesAtmsMap/OfficesAtmsMapLayout.js +9 -22
  49. package/lib/components/OfficesAtmsMap/OfficesAtmsMapLayout.js.map +1 -1
  50. package/lib/components/OfficesAtmsMap/useOfficesAtmsMapData.d.ts +20 -0
  51. package/lib/components/OfficesAtmsMap/useOfficesAtmsMapData.js +28 -0
  52. package/lib/components/OfficesAtmsMap/useOfficesAtmsMapData.js.map +1 -0
  53. package/lib/hooks/useRegions.d.ts +2 -0
  54. package/lib/hooks/useRegions.js.map +1 -1
  55. package/lib/ui-kit/FormField/Fields/RetailAddressField.d.ts +2 -0
  56. package/lib/ui-kit/FormField/Fields/RetailAddressField.js +36 -0
  57. package/lib/ui-kit/FormField/Fields/RetailAddressField.js.map +1 -0
  58. package/lib/ui-kit/FormField/Fields/RetailRegionField.d.ts +2 -0
  59. package/lib/ui-kit/FormField/Fields/RetailRegionField.js +12 -0
  60. package/lib/ui-kit/FormField/Fields/RetailRegionField.js.map +1 -0
  61. package/lib/ui-kit/FormField/NameFieldDef.d.ts +1 -1
  62. package/lib/ui-kit/FormField/getField.js +4 -1
  63. package/lib/ui-kit/FormField/getField.js.map +1 -1
  64. package/lib/ui-kit/FormField/getObjectValidator.js +8 -6
  65. package/lib/ui-kit/FormField/getObjectValidator.js.map +1 -1
  66. package/lib/ui-kit/FormField/validators.d.ts +1 -1
  67. package/lib/ui-kit/FormField/validators.js +5 -5
  68. package/lib/ui-kit/FormField/validators.js.map +1 -1
  69. package/lib/ui-kit/VerifyPhoneDialog/handleSendCode.js +7 -3
  70. package/lib/ui-kit/VerifyPhoneDialog/handleSendCode.js.map +1 -1
  71. package/lib/ui-kit/YandexMap/YandexMap.d.ts +1 -0
  72. package/lib/ui-kit/YandexMap/YandexMap.js +12 -2
  73. package/lib/ui-kit/YandexMap/YandexMap.js.map +1 -1
  74. package/mobile/bundle/bundle.umd.js +1079 -1020
  75. package/mobile/bundle/bundle.umd.min.js +1 -1
  76. package/mobile/bundle/components/CreditForm/getInitialFormState.d.ts +2 -2
  77. package/mobile/bundle/components/OfficesAtmsMap/useOfficesAtmsMapData.d.ts +20 -0
  78. package/mobile/bundle/hooks/useRegions.d.ts +2 -0
  79. package/mobile/bundle/ui-kit/FormField/Fields/RetailAddressField.d.ts +2 -0
  80. package/mobile/bundle/ui-kit/FormField/Fields/RetailRegionField.d.ts +2 -0
  81. package/mobile/bundle/ui-kit/FormField/NameFieldDef.d.ts +1 -1
  82. package/mobile/bundle/ui-kit/FormField/validators.d.ts +1 -1
  83. package/mobile/bundle/ui-kit/YandexMap/YandexMap.d.ts +1 -0
  84. package/mobile/dist/components/CreditForm/creditFormStepsData.js +2 -2
  85. package/mobile/dist/components/CreditForm/creditFormStepsData.js.map +1 -1
  86. package/mobile/dist/components/CreditForm/getInitialFormState.d.ts +2 -2
  87. package/mobile/dist/components/CreditForm/getInitialFormState.js +2 -2
  88. package/mobile/dist/components/CreditForm/getInitialFormState.js.map +1 -1
  89. package/mobile/dist/components/OfficesAtmsMap/OfficesAtmsMapLayout.js +8 -21
  90. package/mobile/dist/components/OfficesAtmsMap/OfficesAtmsMapLayout.js.map +1 -1
  91. package/mobile/dist/components/OfficesAtmsMap/useOfficesAtmsMapData.d.ts +20 -0
  92. package/mobile/dist/components/OfficesAtmsMap/useOfficesAtmsMapData.js +31 -0
  93. package/mobile/dist/components/OfficesAtmsMap/useOfficesAtmsMapData.js.map +1 -0
  94. package/mobile/dist/hooks/useRegions.d.ts +2 -0
  95. package/mobile/dist/hooks/useRegions.js.map +1 -1
  96. package/mobile/dist/ui-kit/FormField/Fields/RetailAddressField.d.ts +2 -0
  97. package/mobile/dist/ui-kit/FormField/Fields/RetailAddressField.js +38 -0
  98. package/mobile/dist/ui-kit/FormField/Fields/RetailAddressField.js.map +1 -0
  99. package/mobile/dist/ui-kit/FormField/Fields/RetailRegionField.d.ts +2 -0
  100. package/mobile/dist/ui-kit/FormField/Fields/RetailRegionField.js +14 -0
  101. package/mobile/dist/ui-kit/FormField/Fields/RetailRegionField.js.map +1 -0
  102. package/mobile/dist/ui-kit/FormField/NameFieldDef.d.ts +1 -1
  103. package/mobile/dist/ui-kit/FormField/getField.js +4 -1
  104. package/mobile/dist/ui-kit/FormField/getField.js.map +1 -1
  105. package/mobile/dist/ui-kit/FormField/getObjectValidator.js +8 -6
  106. package/mobile/dist/ui-kit/FormField/getObjectValidator.js.map +1 -1
  107. package/mobile/dist/ui-kit/FormField/validators.d.ts +1 -1
  108. package/mobile/dist/ui-kit/FormField/validators.js +6 -5
  109. package/mobile/dist/ui-kit/FormField/validators.js.map +1 -1
  110. package/mobile/dist/ui-kit/VerifyPhoneDialog/handleSendCode.js +7 -3
  111. package/mobile/dist/ui-kit/VerifyPhoneDialog/handleSendCode.js.map +1 -1
  112. package/mobile/dist/ui-kit/YandexMap/YandexMap.d.ts +1 -0
  113. package/mobile/dist/ui-kit/YandexMap/YandexMap.js +12 -2
  114. package/mobile/dist/ui-kit/YandexMap/YandexMap.js.map +1 -1
  115. package/mobile/lib/components/CreditForm/creditFormStepsData.js +2 -2
  116. package/mobile/lib/components/CreditForm/creditFormStepsData.js.map +1 -1
  117. package/mobile/lib/components/CreditForm/getInitialFormState.d.ts +2 -2
  118. package/mobile/lib/components/CreditForm/getInitialFormState.js +2 -2
  119. package/mobile/lib/components/CreditForm/getInitialFormState.js.map +1 -1
  120. package/mobile/lib/components/OfficesAtmsMap/OfficesAtmsMapLayout.js +9 -22
  121. package/mobile/lib/components/OfficesAtmsMap/OfficesAtmsMapLayout.js.map +1 -1
  122. package/mobile/lib/components/OfficesAtmsMap/useOfficesAtmsMapData.d.ts +20 -0
  123. package/mobile/lib/components/OfficesAtmsMap/useOfficesAtmsMapData.js +28 -0
  124. package/mobile/lib/components/OfficesAtmsMap/useOfficesAtmsMapData.js.map +1 -0
  125. package/mobile/lib/hooks/useRegions.d.ts +2 -0
  126. package/mobile/lib/hooks/useRegions.js.map +1 -1
  127. package/mobile/lib/ui-kit/FormField/Fields/RetailAddressField.d.ts +2 -0
  128. package/mobile/lib/ui-kit/FormField/Fields/RetailAddressField.js +36 -0
  129. package/mobile/lib/ui-kit/FormField/Fields/RetailAddressField.js.map +1 -0
  130. package/mobile/lib/ui-kit/FormField/Fields/RetailRegionField.d.ts +2 -0
  131. package/mobile/lib/ui-kit/FormField/Fields/RetailRegionField.js +12 -0
  132. package/mobile/lib/ui-kit/FormField/Fields/RetailRegionField.js.map +1 -0
  133. package/mobile/lib/ui-kit/FormField/NameFieldDef.d.ts +1 -1
  134. package/mobile/lib/ui-kit/FormField/getField.js +4 -1
  135. package/mobile/lib/ui-kit/FormField/getField.js.map +1 -1
  136. package/mobile/lib/ui-kit/FormField/getObjectValidator.js +8 -6
  137. package/mobile/lib/ui-kit/FormField/getObjectValidator.js.map +1 -1
  138. package/mobile/lib/ui-kit/FormField/validators.d.ts +1 -1
  139. package/mobile/lib/ui-kit/FormField/validators.js +5 -5
  140. package/mobile/lib/ui-kit/FormField/validators.js.map +1 -1
  141. package/mobile/lib/ui-kit/VerifyPhoneDialog/handleSendCode.js +7 -3
  142. package/mobile/lib/ui-kit/VerifyPhoneDialog/handleSendCode.js.map +1 -1
  143. package/mobile/lib/ui-kit/YandexMap/YandexMap.d.ts +1 -0
  144. package/mobile/lib/ui-kit/YandexMap/YandexMap.js +12 -2
  145. package/mobile/lib/ui-kit/YandexMap/YandexMap.js.map +1 -1
  146. package/mobile/src/components/CreditForm/creditFormStepsData.tsx +2 -2
  147. package/mobile/src/components/CreditForm/getInitialFormState.tsx +4 -4
  148. package/mobile/src/components/OfficesAtmsMap/OfficesAtmsMapLayout.tsx +9 -25
  149. package/mobile/src/components/OfficesAtmsMap/useOfficesAtmsMapData.tsx +49 -0
  150. package/mobile/src/hooks/useRegions.ts +2 -0
  151. package/mobile/src/ui-kit/FormField/Fields/RetailAddressField.tsx +66 -0
  152. package/mobile/src/ui-kit/FormField/Fields/RetailRegionField.tsx +24 -0
  153. package/mobile/src/ui-kit/FormField/NameFieldDef.ts +3 -1
  154. package/mobile/src/ui-kit/FormField/getField.tsx +4 -1
  155. package/mobile/src/ui-kit/FormField/getObjectValidator.tsx +8 -6
  156. package/mobile/src/ui-kit/FormField/validators.ts +6 -6
  157. package/mobile/src/ui-kit/VerifyPhoneDialog/handleSendCode.ts +9 -3
  158. package/mobile/src/ui-kit/YandexMap/YandexMap.tsx +59 -45
  159. package/package.json +1 -1
  160. package/src/components/CreditForm/creditFormStepsData.tsx +2 -2
  161. package/src/components/CreditForm/getInitialFormState.tsx +4 -4
  162. package/src/components/OfficesAtmsMap/OfficesAtmsMapLayout.tsx +9 -25
  163. package/src/components/OfficesAtmsMap/useOfficesAtmsMapData.tsx +49 -0
  164. package/src/hooks/useRegions.ts +2 -0
  165. package/src/ui-kit/FormField/Fields/RetailAddressField.tsx +66 -0
  166. package/src/ui-kit/FormField/Fields/RetailRegionField.tsx +24 -0
  167. package/src/ui-kit/FormField/NameFieldDef.ts +3 -1
  168. package/src/ui-kit/FormField/getField.tsx +4 -1
  169. package/src/ui-kit/FormField/getObjectValidator.tsx +8 -6
  170. package/src/ui-kit/FormField/validators.ts +6 -6
  171. package/src/ui-kit/VerifyPhoneDialog/handleSendCode.ts +9 -3
  172. package/src/ui-kit/YandexMap/YandexMap.tsx +59 -45
@@ -1418,11 +1418,11 @@
1418
1418
  const required = validator((_) => _ !== null && _ !== undefined && _ !== '');
1419
1419
 
1420
1420
  const ERROR_MESSAGE = 'Некорректно заполненное поле';
1421
- const defaultValidator = (errorMsg) => required(errorMsg ? errorMsg : ERROR_MESSAGE);
1422
- const defaultSelectValidator = validator((_) => _?.key && _?.key !== '')(ERROR_MESSAGE);
1423
- const jobNumberValidator = (errorMsg) => validator((_) => typeof _ === 'string' && _.length > 0 && _.length <= 2)(errorMsg ? errorMsg : ERROR_MESSAGE);
1424
- const nameValidator = (errorMsg) => validator((_) => typeof _ === 'string' && _.length > 1)(errorMsg ? errorMsg : ERROR_MESSAGE);
1425
- const lengthStringValidator = (maxLength, errorMsg) => validator((_) => typeof _ === 'string' && _.length >= 1 && _.length <= maxLength)(errorMsg ? errorMsg : ERROR_MESSAGE);
1421
+ const defaultValidator = (errorMsg) => required(errorMsg ?? ERROR_MESSAGE);
1422
+ const defaultSelectValidator = (errorMsg) => validator((_) => _?.key && _?.key !== '')(errorMsg ?? ERROR_MESSAGE);
1423
+ const jobNumberValidator = (errorMsg) => validator((_) => typeof _ === 'string' && _.length > 0 && _.length <= 2)(errorMsg ?? ERROR_MESSAGE);
1424
+ const nameValidator = (errorMsg) => validator((_) => typeof _ === 'string' && _.length > 1)(errorMsg ?? ERROR_MESSAGE);
1425
+ const lengthStringValidator = (maxLength, errorMsg) => validator((_) => typeof _ === 'string' && _.length >= 1 && _.length <= maxLength)(errorMsg ?? ERROR_MESSAGE);
1426
1426
  const serieValidator = (errorMsg) => validator((_) => typeof _ === 'string' && _.length === 4)(errorMsg);
1427
1427
  const numberValidator = (errorMsg) => validator((_) => typeof _ === 'string' && _.length === 6)(errorMsg);
1428
1428
  const innValidator = (errorMsg) => validator((_) => typeof _ === 'string' && (_.length === 10 || _.length === 12))(errorMsg);
@@ -1454,8 +1454,8 @@
1454
1454
  surname: nameValidator('Укажите свою фамилию'),
1455
1455
  name: nameValidator('Укажите своё имя'),
1456
1456
  middleName: nameValidator('Укажите своё отчество'),
1457
- region: defaultSelectValidator,
1458
- addressBranch: defaultSelectValidator,
1457
+ region: defaultSelectValidator(),
1458
+ addressBranch: defaultSelectValidator(),
1459
1459
  phone: phoneValidator('Укажите номер телефона'),
1460
1460
  secondaryPhone: phoneValidator('Укажите номер телефона'),
1461
1461
  birthday: defaultValidator('Укажите дату рождения'),
@@ -1487,10 +1487,10 @@
1487
1487
  partnerComments: defaultValidator(),
1488
1488
  collectionCount: defaultValidator(),
1489
1489
  comment: defaultValidator(),
1490
- acquiringType: defaultSelectValidator,
1491
- feedbackMethod: defaultSelectValidator,
1492
- serviceType: defaultSelectValidator,
1493
- serviceDirection: defaultSelectValidator,
1490
+ acquiringType: defaultSelectValidator(),
1491
+ feedbackMethod: defaultSelectValidator(),
1492
+ serviceType: defaultSelectValidator(),
1493
+ serviceDirection: defaultSelectValidator(),
1494
1494
  meetingDay: defaultValidator(),
1495
1495
  product: defaultValidator(),
1496
1496
  localities: defaultValidator(),
@@ -1524,6 +1524,8 @@
1524
1524
  legalEntityName: defaultValidator(),
1525
1525
  bankEmployeeCode: defaultValidator(),
1526
1526
  partInBusiness: defaultValidator(),
1527
+ regionRetail: defaultSelectValidator('Выберите филиал банка'),
1528
+ addressRetail: defaultSelectValidator('Выберите адрес банка'),
1527
1529
  };
1528
1530
  const getObjectValidator = (inputs) => {
1529
1531
  const requiredInputs = getNamesFromInput(inputs.filter((_) => Boolean(_?.required)));
@@ -2411,6 +2413,666 @@
2411
2413
  return (jsx(SelectControl, { label: "\u0420\u0435\u0433\u0438\u043E\u043D", placeholder: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0440\u0435\u0433\u0438\u043E\u043D", options: regions, ...getValidation(field('region'), validatorObj.region, input?.required) }));
2412
2414
  });
2413
2415
 
2416
+ const Foldable = JSX(({ className = '', isFoldButtonOnTop = false, unfoldedByDefault = false, renderFoldableSection, renderFoldButton, }) => {
2417
+ const [isUnfolded, setIsUnfolded] = useState(unfoldedByDefault);
2418
+ const onToggle = useCallback(() => {
2419
+ setIsUnfolded((_) => !_);
2420
+ }, []);
2421
+ const sectionNode = renderFoldableSection({ isUnfolded, onToggle });
2422
+ const buttonNode = renderFoldButton ? renderFoldButton({ isUnfolded, onToggle }) : null;
2423
+ return isFoldButtonOnTop ? (jsxs("div", { className: className, role: "group", children: [buttonNode, sectionNode] })) : (jsxs("div", { className: className, role: "group", children: [sectionNode, buttonNode] }));
2424
+ });
2425
+
2426
+ function useResizeObserver(callback, deps) {
2427
+ const ref = useRef(null);
2428
+ useEffect(() => {
2429
+ const element = ref?.current;
2430
+ if (!element) {
2431
+ return undefined;
2432
+ }
2433
+ const observer = new ResizeObserver((entries) => {
2434
+ callback(element, entries[0]);
2435
+ });
2436
+ observer.observe(element);
2437
+ return () => {
2438
+ observer.disconnect();
2439
+ };
2440
+ }, [callback, ...deps]);
2441
+ return ref;
2442
+ }
2443
+
2444
+ const FoldableSection = JSX(({ className = '', isUnfolded, children }) => {
2445
+ const containerRef = useRef(null);
2446
+ const childrenWrapperRef = useResizeObserver((childrenWrapperEl) => {
2447
+ if (containerRef.current) {
2448
+ containerRef.current.style.maxHeight = isUnfolded
2449
+ ? `${childrenWrapperEl.scrollHeight}px`
2450
+ : '';
2451
+ }
2452
+ }, [isUnfolded]);
2453
+ return (jsx("div", { ref: containerRef, className: `transition-max-h duration-300 overflow-hidden ${containerRef.current || !isUnfolded ? 'max-h-0' : ''} `, children: jsx("div", { className: className, ref: childrenWrapperRef, children: children }) }));
2454
+ });
2455
+
2456
+ const CardCell = JSX(({ value, subText, children, isPhone, ...props }) => {
2457
+ const textItems = (Array.isArray(value) ? value : value?.split(',') ?? []).filter(Boolean);
2458
+ if ([textItems.length, children, subText].every((_) => !_)) {
2459
+ return null;
2460
+ }
2461
+ return renderCardCell({ textItems, subText, children, isPhone, ...props });
2462
+ });
2463
+ const renderCardCell = ({ label, labelSize = 'text-m', textItems, subColor, subText, className, children, isPhone = false, }) => (jsxs("div", { className: style('flex gap-2xs flex-col h-full max-w-[300px]', className), children: [label ? (jsx(Text, { color: "text-secondary-text", font: "font-light", size: labelSize, children: label })) : null, children || renderTextItems(textItems, isPhone), subText ? (jsx(Text, { color: subColor, size: "text-m", children: subText })) : null] }));
2464
+ const renderTextItems = (textItems, isPhone) => textItems.filter(Boolean).map((text, i) => (jsx(Text, { size: "text-l", children: isPhone ? jsx("a", { href: `tel:${cleanPhoneNumber(text)}`, children: text.trim() }) : text.trim() }, String(i))));
2465
+ const cleanPhoneNumber = (phone) => phone.replace(/\D/g, '');
2466
+
2467
+ const CardRow = JSX(({ className, children }) => (jsx("div", { className: style('flex flex-col sm:flex-row sm:border-t sm:border-solid sm:border-main-divider py-xl gap-x-6xl gap-y-xl', className), children: children })));
2468
+
2469
+ const getScheduleDescription = (workScheduleWeek) => {
2470
+ const rows = getDateDescription(workScheduleWeek);
2471
+ return jsx(CardCell, { label: "\u0420\u0435\u0436\u0438\u043C \u0440\u0430\u0431\u043E\u0442\u044B", value: rows, className: "max-w-none" });
2472
+ };
2473
+ const buildScheduleText = ({ workTime = '', lunchHour = '', daysOff = '' }, isSaturday = false) => {
2474
+ if (!workTime) {
2475
+ return '';
2476
+ }
2477
+ return [
2478
+ `${isSaturday ? 'Суббота' : 'Будние дни'}: ${workTime}`,
2479
+ lunchHour ? `перерыв: ${lunchHour}` : '',
2480
+ daysOff ? `не работает: ${daysOff}` : '',
2481
+ ]
2482
+ .filter(Boolean)
2483
+ .join('; ');
2484
+ };
2485
+ const getDateDescription = (workScheduleWeek) => {
2486
+ const workingWeekday = workScheduleWeek.find((_) => _.key !== 'workingSaturday' && Boolean(_.status) && Boolean(_.workTime));
2487
+ const workingSaturday = workScheduleWeek.find((_) => _.key === 'workingSaturday' && Boolean(_.status) && Boolean(_.workTime));
2488
+ const daysOff = workScheduleWeek
2489
+ .filter((_) => !_.status)
2490
+ .map((_) => _.short?.toLowerCase())
2491
+ .join(', ');
2492
+ const rows = [
2493
+ buildScheduleText({
2494
+ workTime: workingWeekday?.workTime,
2495
+ lunchHour: workingWeekday?.lunchHour,
2496
+ daysOff: workingSaturday ? '' : daysOff,
2497
+ }),
2498
+ buildScheduleText({ workTime: workingSaturday?.workTime, lunchHour: workingSaturday?.lunchHour, daysOff }, true),
2499
+ ].filter(Boolean);
2500
+ return rows;
2501
+ };
2502
+
2503
+ const WEEKDAY_MAP = [
2504
+ ['workingMonday', 'Пн', 'Понедельник'],
2505
+ ['workingTuesday', 'Вт', 'Вторник'],
2506
+ ['workingWednesday', 'Ср', 'Среда'],
2507
+ ['workingThursday', 'Чт', 'Четверг'],
2508
+ ['workingFriday', 'Пт', 'Пятница'],
2509
+ ['workingSaturday', 'Сб', 'Суббота'],
2510
+ ['workingSunday', 'Вс', 'Воскресенье'],
2511
+ ];
2512
+ const getWorkScheduleWeek = (workSchedule) => WEEKDAY_MAP.map(([key, short, title]) => ({
2513
+ key,
2514
+ title,
2515
+ short,
2516
+ status: Boolean(workSchedule?.[key]),
2517
+ get workTime() {
2518
+ return key === 'workingSaturday' ? workSchedule?.workTimeSaturday : workSchedule?.workTime;
2519
+ },
2520
+ get lunchHour() {
2521
+ return key === 'workingSaturday' ? workSchedule?.lunchHourSaturday : workSchedule?.lunchHour;
2522
+ },
2523
+ get hasLunch() {
2524
+ return /\d+/.test(this.lunchHour ?? '');
2525
+ },
2526
+ }));
2527
+
2528
+ const renderBusinessSchedule = (scheduleDescription) => {
2529
+ if (!scheduleDescription) {
2530
+ return null;
2531
+ }
2532
+ const businessSchedule = getBusinessSchedule(scheduleDescription);
2533
+ return (jsxs(CardRow, { className: "border-none", children: [jsx(CardCell, { label: "\u0414\u043B\u044F \u044E\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", labelSize: "text-l", children: jsx("div", { className: "flex gap-1", children: businessSchedule.map(renderAlternativeDay) }) }), jsx(CardCell, { label: "\u0420\u0435\u0436\u0438\u043C \u0440\u0430\u0431\u043E\u0442\u044B", className: "max-w-none", children: jsx(Text, { children: scheduleDescription }) })] }));
2534
+ };
2535
+ const getBusinessSchedule = (scheduleDescription) => {
2536
+ const weekDayMap = WEEKDAY_MAP.map(([, short]) => ({ short, status: true }));
2537
+ const splittedScheduleDescription = scheduleDescription.split('/') ?? [];
2538
+ const lastPartScheduleDescription = splittedScheduleDescription[splittedScheduleDescription.length - 1]?.toLowerCase();
2539
+ if (!lastPartScheduleDescription?.includes('выходной')) {
2540
+ return weekDayMap;
2541
+ }
2542
+ return weekDayMap.map((_) => ({
2543
+ ..._,
2544
+ status: !lastPartScheduleDescription?.includes(_.short.toLowerCase()),
2545
+ }));
2546
+ };
2547
+ const renderAlternativeDay = ({ short, status }, i) => (jsx("div", { className: style('w-9 h-9 rounded-md flex items-center justify-center', status ? 'bg-green-more-light text-green-dark' : 'bg-error/30 text-error'), children: jsx(Text, { size: "text-xs", children: short }) }, String(i)));
2548
+
2549
+ const renderCurrency = ({ currency, buyExchangeRate, saleExchangeRate }, i) => (jsxs("div", { className: "flex gap-lg h-full", children: [currency?.currency ? jsx(CardCell, { label: "\u0412\u0430\u043B\u044E\u0442\u0430", value: currency.currency }) : null, buyExchangeRate ? jsx(CardCell, { label: "\u041A\u0443\u043F\u0438\u0442\u044C", value: String(buyExchangeRate) }) : null, saleExchangeRate ? jsx(CardCell, { label: "\u041F\u0440\u043E\u0434\u0430\u0442\u044C", value: String(saleExchangeRate) }) : null] }, String(i)));
2550
+
2551
+ const colorStyle = {
2552
+ yellow: { border: 'border-yellow-light', text: 'text-yellow' },
2553
+ green: { border: 'border-green-more-light', text: 'text-green-dark' },
2554
+ gray: { border: 'border-gray', text: 'text-secondary-text' },
2555
+ red: { border: 'border-error/30', text: 'text-error' },
2556
+ };
2557
+ const Badge$1 = JSX(({ className, children, color = 'gray' }) => (jsxs("div", { className: style('sm:p-s sm:border sm:border-green rounded-md flex items-center h-fit', colorStyle[color].border, className), children: [jsx("div", { className: "block pr-m sm:pr-0 sm:hidden", children: jsx(Img, { image: { icon: 'SmallClockIcon' }, width: "24", height: "24" }) }), jsx(Text, { size: "text-m", color: colorStyle[color].text, children: children })] })));
2558
+
2559
+ const currentWeekDayIdx = new Date().getDay();
2560
+ //TODO: Add logic time https://github.com/redneckz/wildless-cms-uni-blocks/pull/1549
2561
+ const renderCurrentDaySchedule = (workScheduleWeek) => {
2562
+ const [currentWeekDay] = workScheduleWeek?.slice(currentWeekDayIdx - 1) ?? [];
2563
+ if (!currentWeekDay) {
2564
+ return null;
2565
+ }
2566
+ const { lunchHour, status, workTime, hasLunch } = currentWeekDay;
2567
+ return status ? (jsxs("div", { className: "flex gap-s items-start whitespace-nowrap", children: [workTime ? jsx(Badge$1, { color: "green", children: workTime }) : null, lunchHour && hasLunch ? jsx(Badge$1, { color: "yellow", children: `перерыв: ${lunchHour}` }) : null] })) : (jsx(Badge$1, { color: "red", children: "\u0412\u044B\u0445\u043E\u0434\u043D\u043E\u0439" }));
2568
+ };
2569
+
2570
+ const getSubTextLunch = ({ lunchHour, hasLunch = false, status = false }) => {
2571
+ if (!status) {
2572
+ return 'Не работает';
2573
+ }
2574
+ return lunchHour && hasLunch ? `Перерыв ${lunchHour}` : lunchHour;
2575
+ };
2576
+ const renderDay = ({ title, status, workTime, lunchHour, hasLunch }, i) => (jsx(CardCell, { label: title, value: status && workTime ? workTime : '', subText: getSubTextLunch({ lunchHour, hasLunch, status }), subColor: !status || hasLunch ? 'text-error' : 'text-green-dark' }, String(i)));
2577
+
2578
+ const ICONS$1 = ['ArrowDownIcon', 'ArrowUpIcon'];
2579
+ const labels = ['Подробнее', 'Скрыть'];
2580
+ const renderFoldButton$3 = ({ isUnfolded, onToggle }) => (jsxs("button", { className: "w-full py-2xl cursor-pointer text-primary-main flex items-center border-b border-solid border-main-divider", onClick: onToggle, type: "button", children: [jsx("div", { className: "pr-m", children: labels[Number(isUnfolded)] }), jsx(Icon, { className: "text-primary-text", name: ICONS$1[Number(isUnfolded)], width: "16", height: "16" })] }));
2581
+
2582
+ const renderWorkSchedule = (workSchedule) => {
2583
+ const workScheduleWeek = getWorkScheduleWeek(workSchedule);
2584
+ const timeOfWork = workSchedule ? getDateDescription(workScheduleWeek) : '';
2585
+ const businessTimeOfWork = workSchedule ? workSchedule.businessScheduleDescription : '';
2586
+ if (!workSchedule) {
2587
+ return null;
2588
+ }
2589
+ if (!workSchedule.businessScheduleVisibleTag) {
2590
+ return renderMatchingTimeOfWork(timeOfWork);
2591
+ }
2592
+ if (workSchedule.businessScheduleVisibleTag &&
2593
+ workSchedule.businessScheduleDescription === null) {
2594
+ return renderIndividualTimeOfWork(timeOfWork);
2595
+ }
2596
+ return renderDefaultTimeOfWork(timeOfWork, businessTimeOfWork);
2597
+ };
2598
+ const renderIndividualTimeOfWork = (timeOfWork) => `<p><b>Режим обслуживания физ.лиц:<br/></b>${timeOfWork}</p>`;
2599
+ const renderMatchingTimeOfWork = (timeOfWork) => `<p><b>Режим обслуживания физ. и юр. лиц:<br/></b> ${timeOfWork}</p>`;
2600
+ const renderDefaultTimeOfWork = (timeOfWork, businessTimeOfWork) => `<p><b>Режим обслуживания физ.лиц:<br/></b>${timeOfWork}</p> <p><b>Режим обслуживания юр.лиц:<br/></b>${businessTimeOfWork}</p>`;
2601
+
2602
+ const renderOfficeCard = ({ name, address, phone, fax, phoneBusiness, phoneNatural, phoneCallCentre, phoneCurrencyControl, workSchedule, exchangeRate, }, i) => {
2603
+ if (!workSchedule) {
2604
+ return null;
2605
+ }
2606
+ const workScheduleWeek = getWorkScheduleWeek(workSchedule);
2607
+ return (jsxs("div", { className: "bg-white col-span-12 p-3xl sm:border-green sm:border", children: [jsxs("div", { className: "sm:flex sm:justify-between", children: [jsxs("div", { children: [jsx(Text, { size: "text-h4", children: name }), address ? (jsxs("div", { className: "flex pb-xl pt-xs gap-2xs", children: [jsx(Icon, { name: "GeolocationIcon", width: "24", height: "24" }), jsx(Text, { size: "text-l", children: address })] })) : null] }), renderCurrentDaySchedule(workScheduleWeek)] }), jsx("div", { className: "hidden sm:block", children: renderCardContent$1({
2608
+ phone,
2609
+ fax,
2610
+ phoneBusiness,
2611
+ phoneNatural,
2612
+ phoneCallCentre,
2613
+ phoneCurrencyControl,
2614
+ workSchedule,
2615
+ exchangeRate,
2616
+ }) }), jsx(Foldable, { className: "block sm:hidden", renderFoldableSection: ({ isUnfolded }) => {
2617
+ return (jsx(FoldableSection, { isUnfolded: isUnfolded, children: renderCardContent$1({
2618
+ phone,
2619
+ fax,
2620
+ phoneBusiness,
2621
+ phoneNatural,
2622
+ phoneCallCentre,
2623
+ phoneCurrencyControl,
2624
+ workSchedule,
2625
+ exchangeRate,
2626
+ }) }));
2627
+ },
2628
+ //** TODO: remove styles with refactoring DefaultFoldButton*/
2629
+ renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton$3({ isUnfolded, onToggle }) })] }, String(i)));
2630
+ };
2631
+ const renderCardContent$1 = ({ phone, fax, phoneBusiness, phoneNatural, phoneCallCentre, phoneCurrencyControl, workSchedule, exchangeRate, }) => {
2632
+ const workScheduleWeek = getWorkScheduleWeek(workSchedule);
2633
+ const labelSchedule = workSchedule?.businessScheduleVisibleTag
2634
+ ? 'Для физических лиц'
2635
+ : 'Для физических и юридических лиц';
2636
+ return (jsxs("div", { children: [jsxs(CardRow, { className: "flex-wrap border-b border-solid border-main-divider", children: [jsx(CardCell, { label: "\u0424\u0430\u043A\u0441", value: fax, isPhone: true }), jsx(CardCell, { label: "\u0422\u0435\u043B\u0435\u0444\u043E\u043D \u0444\u0438\u043B\u0438\u0430\u043B\u0430", value: phone, isPhone: true }), jsx(CardCell, { label: "\u0414\u043B\u044F \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u044E\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", value: phoneBusiness, isPhone: true }), jsx(CardCell, { label: "\u041E\u0431\u0441\u043B\u0443\u0436\u0438\u0432\u0430\u043D\u0438\u0435 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", value: phoneNatural, isPhone: true }), jsx(CardCell, { label: "\u0414\u043B\u044F \u043A\u043E\u043D\u0441\u0443\u043B\u044C\u0442\u0430\u0446\u0438\u0439 \u043F\u043E \u0432\u0430\u043B\u044E\u0442\u043D\u043E\u043C\u0443 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044E", value: phoneCurrencyControl, isPhone: true }), jsx(CardCell, { label: "\u041A\u043E\u043D\u0442\u0430\u043A\u0442-\u0446\u0435\u043D\u0442\u0440", value: phoneCallCentre, isPhone: true })] }), workSchedule?.isMatchesPattern ? (jsx(CardRow, { children: jsx(CardCell, { label: labelSchedule, labelSize: "text-l", className: "w-full max-w-none", children: jsx("div", { className: "flex flex-wrap gap-xs sm:justify-between pt-xs", children: workScheduleWeek?.map(renderDay) }) }) })) : (jsxs(CardRow, { children: [jsx(CardCell, { label: labelSchedule, labelSize: "text-l", children: jsx("div", { className: "flex gap-1", children: workScheduleWeek?.map(renderAlternativeDay) }) }), getScheduleDescription(workScheduleWeek)] })), workSchedule?.businessScheduleVisibleTag
2637
+ ? renderBusinessSchedule(workSchedule?.businessScheduleDescription)
2638
+ : null, exchangeRate?.currencies?.length ? (jsx(CardRow, { className: "flex-wrap", children: exchangeRate?.currencies?.map(renderCurrency) })) : null] }));
2639
+ };
2640
+ const capitalizedFirstLetter$1 = (text) => text ? `${text?.charAt(0)?.toUpperCase()}${text?.slice(1)}` : '';
2641
+ const getOfficePoint = ({ name = '', address = '', workSchedule }) => {
2642
+ const header = capitalizedFirstLetter$1(name);
2643
+ const body = `${address} ${renderWorkSchedule(workSchedule)}`;
2644
+ return { header, body };
2645
+ };
2646
+
2647
+ const isSSR = () => Boolean(typeof globalThis.process === 'object' && globalThis.process && globalThis.process.version);
2648
+
2649
+ const isClient = !isSSR();
2650
+ const ClientOnly = JSX(({ children }) => (isClient ? children : null));
2651
+
2652
+ const Loader = JSX(({ color = 'text-primary-main', position = 'absolute', blur = true }) => (jsx("div", { className: style('flex justify-center items-center h-full w-full z-50', position, {
2653
+ 'backdrop-blur': blur,
2654
+ }), children: jsx("div", { className: style('inline-block h-28 w-28', 'animate-spin rounded-full', 'border-8 border-solid border-current', 'border-r-transparent', color), role: "status" }) })));
2655
+
2656
+ const MapMarkerClusterIcon = '/icons/MapMarkerClusterIcon.svg';
2657
+ const MapMarkerClusterYellowIcon = '/icons/MapMarkerClusterYellowIcon.svg';
2658
+ function renderClusterer({ yandexMaps, map, points, isLoad, }) {
2659
+ if (isLoad || !points) {
2660
+ return;
2661
+ }
2662
+ map.geoObjects.removeAll();
2663
+ if (!points.length) {
2664
+ return;
2665
+ }
2666
+ const clusterIconContentLayout = yandexMaps.templateLayoutFactory.createClass('<div style="margin-top: -3px;">{{properties.geoObjects.length}}</div>');
2667
+ const officeClusterer = defineClusterer('offices', yandexMaps, clusterIconContentLayout);
2668
+ if (points.length && points.every((_) => 'type' in _)) {
2669
+ const remoteWorkplaceClusterer = defineClusterer('workplaces', yandexMaps, clusterIconContentLayout);
2670
+ const remoteWorkplaceGeoObjects = defineGeoObjects(points.filter((_) => _.type === 'workplaces'), 'workplaces', yandexMaps);
2671
+ const officesGeoObjects = defineGeoObjects(points.filter((_) => _.type === 'offices'), 'offices', yandexMaps);
2672
+ officeClusterer.add(officesGeoObjects);
2673
+ remoteWorkplaceClusterer.add(remoteWorkplaceGeoObjects);
2674
+ map.geoObjects.add(remoteWorkplaceClusterer);
2675
+ map.geoObjects.add(officeClusterer);
2676
+ }
2677
+ else {
2678
+ const geoObjects = defineGeoObjects(points, 'offices', yandexMaps);
2679
+ officeClusterer.add(geoObjects);
2680
+ map.geoObjects.add(officeClusterer);
2681
+ }
2682
+ map.setBounds(yandexMaps.util.bounds.fromPoints(points.map((_) => _.coords))).then(() => {
2683
+ if (map.getZoom() > 10) {
2684
+ map.setZoom(10);
2685
+ }
2686
+ });
2687
+ }
2688
+ const defineClusterer = (type, yandexMaps, clusterIconContentLayout) => {
2689
+ return new yandexMaps.Clusterer({
2690
+ clusterIcons: [
2691
+ {
2692
+ href: type === 'offices' ? MapMarkerClusterIcon : MapMarkerClusterYellowIcon,
2693
+ size: [78, 84],
2694
+ offset: [-35, -50],
2695
+ },
2696
+ ],
2697
+ clusterIconContentLayout,
2698
+ clusterHideIconOnBalloonOpen: false,
2699
+ geoObjectHideIconOnBalloonOpen: false,
2700
+ });
2701
+ };
2702
+ const defineGeoObjects = (pointArr, type, yandexMaps) => {
2703
+ return pointArr.map(({ coords, content }) => new yandexMaps.Placemark(coords, {
2704
+ balloonContentHeader: content?.header,
2705
+ balloonContentBody: content?.body,
2706
+ balloonContentFooter: content?.footer,
2707
+ hintContent: content?.hint,
2708
+ }, {
2709
+ iconLayout: 'default#image',
2710
+ iconImageHref: type === 'offices' ? MapMarkerClusterIcon : MapMarkerClusterYellowIcon,
2711
+ iconImageSize: [78, 84],
2712
+ iconImageOffset: [-35, -50],
2713
+ }));
2714
+ };
2715
+
2716
+ const defaultStyle = {
2717
+ focus: 'focus:border-primary-text focus:border',
2718
+ hover: 'hover:bg-primary-hover',
2719
+ active: 'active:bg-primary-active',
2720
+ font: 'text-center font-sans',
2721
+ };
2722
+
2723
+ const styles$1 = {
2724
+ ...defaultStyle,
2725
+ border: 'border border-transparent rounded-md',
2726
+ position: 'absolute flex items-center justify-center',
2727
+ };
2728
+ const renderUserGeolocation = (map, yandexMaps, className) => {
2729
+ const setUserGeoLocation = () => {
2730
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2731
+ // @ts-ignore
2732
+ yandexMaps.geolocation
2733
+ .get({
2734
+ provider: 'yandex',
2735
+ autoReverseGeocode: true,
2736
+ mapStateAutoApply: true,
2737
+ })
2738
+ .then(function (result) {
2739
+ map.current.geoObjects.add(result.geoObjects);
2740
+ });
2741
+ };
2742
+ return (jsx("div", { className: `select-none cursor-pointer py-m w-12 bg-white ${Object.values(styles$1).join(' ')} ${className}`, onClick: setUserGeoLocation, children: jsx(Icon, { name: "UserGeoLocationIcon", width: "20", height: "16" }) }));
2743
+ };
2744
+
2745
+ const getNS = (_) => globalThis[_];
2746
+ const initializeExternalNS = (namespaceName, url) => {
2747
+ const script = document.getElementById(url);
2748
+ if (script) {
2749
+ const ns = getNS(namespaceName);
2750
+ if (ns) {
2751
+ return Promise.resolve(ns);
2752
+ }
2753
+ else {
2754
+ return new Promise((resolve) => {
2755
+ script.addEventListener('load', () => {
2756
+ resolve(getNS(namespaceName));
2757
+ });
2758
+ });
2759
+ }
2760
+ }
2761
+ else {
2762
+ return new Promise((resolve, reject) => {
2763
+ const newScript = document.createElement('script');
2764
+ newScript.src = url;
2765
+ newScript.async = true;
2766
+ newScript.id = url;
2767
+ newScript.addEventListener('load', () => {
2768
+ resolve(getNS(namespaceName));
2769
+ });
2770
+ newScript.addEventListener('error', (error) => {
2771
+ reject(error);
2772
+ });
2773
+ document.head.appendChild(newScript);
2774
+ });
2775
+ }
2776
+ };
2777
+ function useExternalNS(namespaceName, url, unmountNS = true) {
2778
+ const [externalNS, setExternalNS] = useState(undefined);
2779
+ useEffect(() => {
2780
+ let isMounted = true;
2781
+ initializeExternalNS(namespaceName, url)
2782
+ .then((ns) => {
2783
+ if (isMounted) {
2784
+ setExternalNS(ns);
2785
+ }
2786
+ })
2787
+ .catch((error) => {
2788
+ console.error(`Failed to initialize external namespace: ${error}`);
2789
+ });
2790
+ return () => {
2791
+ isMounted = false;
2792
+ if (unmountNS) {
2793
+ const script = document.getElementById(url);
2794
+ if (script) {
2795
+ document.head.removeChild(script);
2796
+ }
2797
+ setExternalNS(undefined);
2798
+ }
2799
+ };
2800
+ }, [namespaceName, url, unmountNS]);
2801
+ return externalNS;
2802
+ }
2803
+
2804
+ const YMAPS_NAMESPACE = 'ymaps';
2805
+ const useYandexMaps = () => {
2806
+ const url = `https://api-maps.yandex.ru/2.1/?apikey=${projectSettings.YANDEX_MAP_API_KEY || ''}&lang=ru_RU`;
2807
+ return useExternalNS(YMAPS_NAMESPACE, url, false);
2808
+ };
2809
+
2810
+ const styles = {
2811
+ ...defaultStyle,
2812
+ border: 'border-b border-b-2 border-gray last:border-0',
2813
+ position: 'relative flex items-center justify-center',
2814
+ };
2815
+ // TODO: Добавить метод определения центральной точки
2816
+ const ZoomButton = JSX(({ yandexMaps, direction = 'in' }) => {
2817
+ const iconName = direction === 'in' ? 'PlusIcon' : 'MinusIcon';
2818
+ const changeZoom = () => {
2819
+ const currentZoom = yandexMaps.current.getZoom();
2820
+ const newZoom = direction === 'in' ? currentZoom + 1 : currentZoom - 1;
2821
+ yandexMaps.current.setZoom(newZoom, { checkZoomRange: true });
2822
+ };
2823
+ return (jsx("div", { onClick: changeZoom, className: `${Object.values(styles).join(' ')} bg-white select-none cursor-pointer w-12 h-12`, children: jsx(Icon, { name: iconName, width: "20", height: "16" }) }));
2824
+ });
2825
+
2826
+ const DEFAULT_CENTER_COORDS = [55.753995, 37.614069];
2827
+ // TODO: Поле для поиска: невыяснено среди каких данных делать поиск (искать в имени офиса, в адресе, метро и т.д.).
2828
+ // Сейчас реализован поиск среди тестовых данных
2829
+ // TODO: Также выяснить что делать когда ничего не найдено
2830
+ // TODO: На макетах также когда есть поле поиска нет кнопки открыть на карте.
2831
+ const YandexMap = JSX(({ points, className = '', zoom = 5, isLoad, selectedAddress }) => {
2832
+ const map = useRef(null);
2833
+ const yandexMaps = useYandexMaps();
2834
+ useEffect(() => {
2835
+ if (map.current) {
2836
+ renderClusterer({ yandexMaps, map: map.current, points, isLoad });
2837
+ }
2838
+ else {
2839
+ yandexMaps?.ready(() => {
2840
+ // Ready function may be called few times, but must be called once
2841
+ if (map.current) {
2842
+ renderClusterer({ yandexMaps, map: map.current, points, isLoad });
2843
+ return;
2844
+ }
2845
+ map.current = new yandexMaps.Map('map', {
2846
+ center: getCenterPoint(points),
2847
+ zoom,
2848
+ controls: [],
2849
+ suppressMapOpenBlock: true,
2850
+ });
2851
+ renderClusterer({ yandexMaps, map: map.current, points, isLoad });
2852
+ });
2853
+ }
2854
+ }, [yandexMaps, points, zoom, isLoad, selectedAddress]);
2855
+ useEffect(() => {
2856
+ if (map.current && selectedAddress) {
2857
+ yandexMaps?.geocode(selectedAddress).then((res) => {
2858
+ const firstGeoObject = res.geoObjects.get(0);
2859
+ const coords = firstGeoObject.geometry.getCoordinates();
2860
+ map.current.setCenter(coords);
2861
+ map.current.setZoom(18);
2862
+ });
2863
+ }
2864
+ }, [selectedAddress]);
2865
+ if (!yandexMaps) {
2866
+ return null;
2867
+ }
2868
+ const zIndex = 'z-10';
2869
+ return (jsxs("div", { id: "map", className: style('relative', 'w-full', className), children: [isLoad ? jsx(Loader, {}) : null, jsxs("div", { className: style('absolute right-2 top-52 z-10 w-12 overflow-hidden border border-transparent rounded-md', zIndex), children: [jsx(ZoomButton, { yandexMaps: map }), jsx(ZoomButton, { yandexMaps: map, direction: "out" })] }), renderUserGeolocation(map, yandexMaps, style('right-2 top-80', zIndex))] }));
2870
+ });
2871
+ const getCenterPoint = (points) => {
2872
+ const centerCoords = [
2873
+ getArraySumAndAverage(mapByIndex(points, 0)),
2874
+ getArraySumAndAverage(mapByIndex(points, 1)),
2875
+ ];
2876
+ return centerCoords.every((_) => _) ? centerCoords : DEFAULT_CENTER_COORDS;
2877
+ };
2878
+ const mapByIndex = (points, index) => points.map((_) => _.coords?.[index]);
2879
+ const getArraySumAndAverage = (arr) => arr.length && arr.reduce((a, b) => a + b) / arr.length;
2880
+
2881
+ const INITIAL_FILTRATION_STATE$1 = {
2882
+ workingSaturday: false,
2883
+ premiumService: false,
2884
+ privateBanking: false,
2885
+ remoteWorkplace: false,
2886
+ serviceDisabledPeople: false,
2887
+ sellingCoins: false,
2888
+ buyingCoins: false,
2889
+ bullionOperations: false,
2890
+ preciousMetalsOperations: false,
2891
+ transferringDataToBiometricSystem: false,
2892
+ };
2893
+ const FILTRATION_LABELS = {
2894
+ safeBoxCaseVolumes: 'Аренда индивидуальных сейфовых ячеек',
2895
+ workingSaturday: 'Открыты по субботам',
2896
+ terminalTypeAtms: 'Банкоматы',
2897
+ terminalTypeTerm: 'Терминалы',
2898
+ workAllTime: 'Круглосуточно',
2899
+ billAcceptorEnable: 'Прием наличных',
2900
+ premiumService: 'Премиальное обслуживание',
2901
+ privateBanking: 'Услуга Private banking',
2902
+ sellingCoins: 'Продажа монет из драгоценных металлов',
2903
+ buyingCoins: 'Покупка монет из драгоценных металлов',
2904
+ bullionOperations: 'Операции со слитками',
2905
+ preciousMetalsOperations: 'Операции с драгоценными металлами',
2906
+ transferringDataToBiometricSystem: 'Передача фото и голоса в Единую биометрическую систему',
2907
+ locationDisabledPeople: 'Для маломобильных',
2908
+ designDisabledPeople: 'Для слабовидящих',
2909
+ remoteWorkplace: 'Удаленное рабочее место',
2910
+ serviceDisabledPeople: 'Для маломобильных граждан',
2911
+ };
2912
+ const FILTRATION_PREDICATES$1 = {
2913
+ workingSaturday: (item) => Boolean('workSchedule' in item && item.workSchedule?.workingSaturday),
2914
+ premiumService: (item) => Boolean('premiumService' in item && item.premiumService),
2915
+ privateBanking: (item) => Boolean('privateBanking' in item && item.privateBanking),
2916
+ remoteWorkplace: (item) => Boolean('workScheduleDescription' in item),
2917
+ serviceDisabledPeople: (item) => Boolean('serviceDisabledPeople' in item && item.serviceDisabledPeople),
2918
+ sellingCoins: (item) => Boolean('sellingCoins' in item && item.sellingCoins),
2919
+ buyingCoins: (item) => Boolean('buyingCoins' in item && item.buyingCoins),
2920
+ bullionOperations: (item) => Boolean('bullionOperations' in item && item.bullionOperations),
2921
+ preciousMetalsOperations: (item) => Boolean('preciousMetalsOperations' in item && item.preciousMetalsOperations),
2922
+ transferringDataToBiometricSystem: (item) => Boolean('transferringDataToBiometricSystem' in item && item.transferringDataToBiometricSystem),
2923
+ };
2924
+
2925
+ function useButton() {
2926
+ return (props) => ({
2927
+ ...props,
2928
+ onClick: handlerDecorator(handleClick(props)),
2929
+ });
2930
+ }
2931
+ function handleClick({ disabled, onClick }) {
2932
+ return (ev) => {
2933
+ !disabled && onClick && onClick(ev);
2934
+ };
2935
+ }
2936
+
2937
+ const buttonStyleMap = {
2938
+ primary: 'text-white bg-primary-main hover:bg-primary-hover active:bg-primary-active',
2939
+ secondary: 'text-primary-main bg-main-divider hover:text-white hover:bg-primary-hover active:bg-primary-active',
2940
+ };
2941
+ const secondaryButtonStyleMap = {
2942
+ primary: style('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'),
2943
+ secondary: style('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'),
2944
+ };
2945
+ const Button = JSX(({ children, ...props }) => {
2946
+ const button = useButton();
2947
+ const { className, version = 'primary', active, disabled, type = 'button', rounded = true, role, onClick, } = button(props);
2948
+ return (jsx("button", { className: style('font-sans px-9 py-4', 'flex justify-center items-center gap-xs', {
2949
+ 'text-white bg-primary-active': active,
2950
+ 'bg-main-gray text-main-disabled cursor-not-allowed': disabled,
2951
+ 'rounded-md': rounded,
2952
+ }, !active && !disabled
2953
+ ? style(buttonStyleMap[version], secondaryButtonStyleMap[version])
2954
+ : '', className), type: type, role: role, onClick: onClick, children: children }));
2955
+ });
2956
+
2957
+ const getVersion = (isPrimary, type) => isPrimary && type !== 'underlined' ? 'primary' : 'secondary';
2958
+
2959
+ const renderButtonsGroup = (data, activeButton, onButtonClick) => {
2960
+ const allButtonVersion = getVersion(activeButton === 'all');
2961
+ const businessButtonVersion = getVersion(activeButton === 'business');
2962
+ const handleClick = (e, key, branches) => {
2963
+ const filteredBranches = e.currentTarget === e.target && key === 'business' ? filterBranches(branches) : branches;
2964
+ onButtonClick(key);
2965
+ return filteredBranches;
2966
+ };
2967
+ const filterBranches = (branches) => branches.filter((branch) => branch.workSchedule &&
2968
+ branch.workSchedule.businessScheduleVisibleTag &&
2969
+ !branch.workSchedule.businessScheduleDescription);
2970
+ return (jsxs("div", { className: "flex gap-lg flex-col sm:flex-row pb-lg", children: [jsx(Button, { "data-id": "all", onClick: (e) => handleClick(e, 'all', data), version: allButtonVersion, children: "\u0414\u043B\u044F \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446" }), jsx(Button, { "data-id": "business", onClick: (e) => handleClick(e, 'business', data), version: businessButtonVersion, children: "\u0414\u043B\u044F \u044E\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446" })] }));
2971
+ };
2972
+
2973
+ const renderDescriptionBlock$1 = ({ __html, list, richVersion }) => __html || list?.length ? (jsxs("div", { className: "mb-2xl border-b sm:border border-main-divider sm:rounded-md", children: [__html ? (jsx("div", { className: "mb-2xl", children: jsx(RichText, { __html: __html, richVersion: richVersion }) })) : null, list?.length ? (jsx("div", { className: "flex flex-col sm:flex-row gap-2xl sm:flex-wrap pb-2xl sm:pb-xl", children: list.map((item, i) => (jsxs("div", { className: "flex gap-xs items-center", children: [item?.image ? jsx(Img, { image: item.image }) : null, item?.text ? (jsx(Text, { size: "text-m", font: "font-light", children: item.text })) : null] }, String(i)))) })) : null] })) : null;
2974
+
2975
+ const COMMON_FILTERS_STYLES = 'flex flex-col sm:flex-row sm:flex-wrap gap-3xl pb-2xl';
2976
+ const renderFiltrationForm = ({ filters, field: { field, reset }, onlyOffice, labels, }) => {
2977
+ const visibleFiltersNum = onlyOffice ? 5 : 6;
2978
+ const filtersCheckbox = (filters || []).map((key) => (jsx(Checkbox, { text: labels[key], ...field(key) }, key)));
2979
+ const [visibleFilters, hiddenFilters] = visibleFiltersNum > 0
2980
+ ? [filtersCheckbox.slice(0, visibleFiltersNum), filtersCheckbox.slice(visibleFiltersNum)]
2981
+ : [filtersCheckbox, []];
2982
+ return (jsx("div", { children: filters?.length ? (jsx("div", { children: jsx(Foldable, { renderFoldableSection: ({ isUnfolded }) => (jsxs("div", { children: [jsx("div", { className: COMMON_FILTERS_STYLES, children: visibleFilters }), jsx(FoldableSection, { className: COMMON_FILTERS_STYLES, isUnfolded: isUnfolded, children: hiddenFilters })] })), renderFoldButton: renderFoldButton$2(reset, onlyOffice) }) })) : null }));
2983
+ };
2984
+ const renderFoldButton$2 = (reset, onlyOffice = false) => ({ isUnfolded, onToggle }) => {
2985
+ const labels = ['Больше фильтров', 'Меньше фильтров'];
2986
+ const icons = ['ArrowDownIcon', 'ArrowUpIcon'];
2987
+ return (jsxs("div", { className: "flex space-x-lg", children: [onlyOffice ? (jsx(LinkButton, { version: "transparent", className: "text-secondary-text [&>*]:p-0", appendRight: jsx(Icon, { name: icons[Number(isUnfolded)], width: "16", height: "16" }), text: labels[Number(isUnfolded)], onClick: onToggle })) : null, jsx(LinkButton, { version: "transparent", className: "text-secondary-text [&>*]:p-0", onClick: reset, children: renderBtnInner() })] }));
2988
+ };
2989
+ const renderBtnInner = () => (jsxs("div", { className: "flex items-center", children: ["\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u0444\u0438\u043B\u044C\u0442\u0440", jsx(Icon, { name: "CloseIcon", width: "16", height: "16", className: "ml-2xs" })] }));
2990
+
2991
+ const renderHeading = (title, lengthItems) => (jsx("div", { className: "flex flex-col sm:flex-row gap-xs mb-2xl", children: jsxs(Heading, { headingType: "h3", children: [jsx("span", { suppressHydrationWarning: true, children: title }), lengthItems ? (jsx(Text, { size: "text-h2", color: "text-secondary-text", children: jsx("span", { suppressHydrationWarning: true, children: ` (${lengthItems})` }) })) : null] }) }));
2992
+
2993
+ const defaultEmptyFunction$1 = () => void 0;
2994
+ const filtersVisibleStyles = (activeButton) => activeButton === 'all' ? 'block' : 'hidden';
2995
+ const OfficesAtmsMapLayout = JSX(({ className, data = [], isLoad, remoteWorkplaces = [], renderCard = defaultEmptyFunction$1, renderRemoteWorkplaceCard = defaultEmptyFunction$1, getBalloon = defaultEmptyFunction$1, getBalloonRemoteWorkplaces = defaultEmptyFunction$1, descriptionData, title, }) => {
2996
+ const onlyOffice = title?.includes('Офис');
2997
+ const [filtrationState, { field, reset }] = useForm(INITIAL_FILTRATION_STATE$1);
2998
+ const { filteredItems, points, filteredRemoteWorkplaces, lengthItems } = useOfficesAtmsMapData({
2999
+ data,
3000
+ remoteWorkplaces,
3001
+ filtrationState,
3002
+ getBalloon,
3003
+ getBalloonRemoteWorkplaces,
3004
+ });
3005
+ const [activeButton, setActiveButton] = useState('all');
3006
+ const filterOptions = {
3007
+ filters: getFiltersWithNonEmptyData([...data, ...remoteWorkplaces]),
3008
+ field: { field, reset },
3009
+ onlyOffice,
3010
+ labels: FILTRATION_LABELS,
3011
+ };
3012
+ return (jsxs("div", { className: style('space-y-1', className), children: [jsxs("div", { className: "bg-white", children: [jsxs("div", { className: "p-3xl pb-0", children: [renderHeading(title, lengthItems), descriptionData ? renderDescriptionBlock$1(descriptionData) : null, onlyOffice && renderButtonsGroup(data, activeButton, setActiveButton), jsx("div", { className: style('pb-3xl', filtersVisibleStyles(activeButton)), children: renderFiltrationForm(filterOptions) })] }), jsx("div", { className: "h-[600px]", children: jsx(ClientOnly, { children: jsx(YandexMap, { points: points, isLoad: isLoad, className: "h-full" }) }) })] }), jsxs(ClientOnly, { children: [filteredItems.map(renderCard), filteredRemoteWorkplaces.map(renderRemoteWorkplaceCard)] })] }));
3013
+ });
3014
+ const filterItems$1 = (data, filtrationState) => {
3015
+ const truthyFilters = Object.keys(filtrationState).filter((key) => filtrationState[key]);
3016
+ return data.filter((item) => truthyFilters.every((_) => FILTRATION_PREDICATES$1[_](item)));
3017
+ };
3018
+ const getFiltersWithNonEmptyData = (data) => Object.keys(INITIAL_FILTRATION_STATE$1).filter((_) => data.filter((item) => FILTRATION_PREDICATES$1[_](item)).length);
3019
+
3020
+ const defaultEmptyFunction = () => void 0;
3021
+ const useOfficesAtmsMapData = ({ data, remoteWorkplaces = [], filtrationState = {}, getBalloon = defaultEmptyFunction, getBalloonRemoteWorkplaces = defaultEmptyFunction, }) => {
3022
+ const [filteredItems, points, filteredRemoteWorkplaces, lengthItems] = useMemo(() => {
3023
+ const _filteredItems = filterItems$1(data, filtrationState);
3024
+ const _filteredRemoteWorkplaces = filterItems$1(remoteWorkplaces, filtrationState);
3025
+ const _points = [
3026
+ ..._filteredItems.map((_) => ({
3027
+ type: 'offices',
3028
+ coords: [Number(_.gpsLatitude), Number(_.gpsLongitude)]?.filter(Boolean),
3029
+ content: getBalloon(_),
3030
+ })),
3031
+ ..._filteredRemoteWorkplaces.map((_) => ({
3032
+ type: 'workplaces',
3033
+ coords: [Number(_.gpsLatitude), Number(_.gpsLongitude)]?.filter(Boolean),
3034
+ content: getBalloonRemoteWorkplaces({
3035
+ address: _.address,
3036
+ workScheduleDescription: _.workScheduleDescription,
3037
+ }),
3038
+ })),
3039
+ ].filter((_) => _.coords && _.coords.length === 2);
3040
+ const itemsLength = _filteredItems.length + _filteredRemoteWorkplaces?.length;
3041
+ return [_filteredItems, _points, _filteredRemoteWorkplaces, itemsLength];
3042
+ }, [data, remoteWorkplaces, filtrationState, getBalloon, getBalloonRemoteWorkplaces]);
3043
+ return { filteredItems, points, filteredRemoteWorkplaces, lengthItems };
3044
+ };
3045
+
3046
+ const RetailAddressField = JSX(({ field, input }) => {
3047
+ const fieldRegion = field('regionRetail');
3048
+ const fieldBranch = field('addressRetail');
3049
+ const regions = useBranchesByRegions();
3050
+ const regionKey = fieldRegion?.value?.key;
3051
+ const selectedRegion = regions.find(({ region }) => region === regionKey);
3052
+ const isLoad = !regions;
3053
+ const regionText = fieldRegion?.value?.text;
3054
+ const addressBranchRetail = useBranchesByRegions()?.find((_) => _?.region === regionText)?.branches;
3055
+ useEffect(() => {
3056
+ if (fieldRegion?.value?.key !== '') {
3057
+ field?.('addressRetail')?.onChange?.('');
3058
+ }
3059
+ }, [fieldRegion?.value]);
3060
+ const { points } = useOfficesAtmsMapData({
3061
+ data: selectedRegion?.branches || [],
3062
+ filtrationState: {},
3063
+ getBalloon: getOfficePoint,
3064
+ });
3065
+ 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: (addressBranchRetail || []).map(({ address = '' }) => ({
3066
+ key: address,
3067
+ text: address,
3068
+ })), ...getValidation(field('addressRetail'), validatorObj.addressRetail, input?.required), isSearch: true }), jsx("div", { className: "h-[600px]", children: jsx(ClientOnly, { children: jsx(YandexMap, { points: points, isLoad: isLoad, className: "h-full", selectedAddress: fieldBranch?.value?.text }) }) })] }));
3069
+ });
3070
+
3071
+ const RetailRegionField = JSX(({ field, input }) => {
3072
+ const regions = useBranchesByRegions();
3073
+ return (jsx(SelectControl, { label: "\u0424\u0438\u043B\u0438\u0430\u043B \u0431\u0430\u043D\u043A\u0430", placeholder: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0438\u043B\u0438\u0430\u043B \u0431\u0430\u043D\u043A\u0430", isSearch: true, options: useMemo(() => regions?.map(({ region = '' }) => ({ key: region, text: region })), [regions]), ...getValidation(field('regionRetail'), validatorObj.regionRetail, input?.required) }));
3074
+ });
3075
+
2414
3076
  const RetirementIncomeField = JSX(({ field, input }) => (jsx(InputControl, { label: "\u041F\u0435\u043D\u0441\u0438\u043E\u043D\u043D\u044B\u0435 \u0434\u043E\u0445\u043E\u0434\u044B", placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435", type: "number", ...getValidation(field('retirementIncome'), validatorObj.retirementIncome, input?.required), ...input })));
2415
3077
 
2416
3078
  const SecondaryPhoneField = JSX(({ field }) => {
@@ -2559,7 +3221,6 @@
2559
3221
  armyIdFlg: jsx(ArmyIdFlgField, { field: field, input: input }),
2560
3222
  dulSerie: jsx(DulSerieField, { field: field, input: input }),
2561
3223
  dulNumber: jsx(DulNumberField, { field: field, input: input }),
2562
- // eslint-disable-next-line max-lines
2563
3224
  dulIssueDateField: jsx(DulIssueDateField, { field: field, input: input }),
2564
3225
  dulSubdivisionCode: jsx(DulSubdivisionCodeField, { field: field, input: input }),
2565
3226
  dulIssuedBy: jsx(DulIssuedByField, { field: field, input: input }),
@@ -2576,6 +3237,8 @@
2576
3237
  creditInRshbCd: jsx(CreditInRshbCdField, { field: field, input: input }),
2577
3238
  bankEmployeeCode: jsx(BankEmpoleeCodeField, { field: field, input: input }),
2578
3239
  partInBusiness: jsx(PartInBusinessField, { field: field, input: input }),
3240
+ regionRetail: jsx(RetailRegionField, { field: field, input: input }),
3241
+ addressRetail: jsx(RetailAddressField, { field: field, input: input }),
2579
3242
  };
2580
3243
  return isRenderField({ input, field }) ? (jsx("div", { children: InputsMap[input?.name || ''] }, String(i))) : null;
2581
3244
  };
@@ -2584,38 +3247,6 @@
2584
3247
 
2585
3248
  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;
2586
3249
 
2587
- function useButton() {
2588
- return (props) => ({
2589
- ...props,
2590
- onClick: handlerDecorator(handleClick(props)),
2591
- });
2592
- }
2593
- function handleClick({ disabled, onClick }) {
2594
- return (ev) => {
2595
- !disabled && onClick && onClick(ev);
2596
- };
2597
- }
2598
-
2599
- const buttonStyleMap = {
2600
- primary: 'text-white bg-primary-main hover:bg-primary-hover active:bg-primary-active',
2601
- secondary: 'text-primary-main bg-main-divider hover:text-white hover:bg-primary-hover active:bg-primary-active',
2602
- };
2603
- const secondaryButtonStyleMap = {
2604
- primary: style('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'),
2605
- secondary: style('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'),
2606
- };
2607
- const Button = JSX(({ children, ...props }) => {
2608
- const button = useButton();
2609
- const { className, version = 'primary', active, disabled, type = 'button', rounded = true, role, onClick, } = button(props);
2610
- return (jsx("button", { className: style('font-sans px-9 py-4', 'flex justify-center items-center gap-xs', {
2611
- 'text-white bg-primary-active': active,
2612
- 'bg-main-gray text-main-disabled cursor-not-allowed': disabled,
2613
- 'rounded-md': rounded,
2614
- }, !active && !disabled
2615
- ? style(buttonStyleMap[version], secondaryButtonStyleMap[version])
2616
- : '', className), type: type, role: role, onClick: onClick, children: children }));
2617
- });
2618
-
2619
3250
  const ResponseTypeDialog = JSX(function ({ responseType, typeForm, }) {
2620
3251
  const responseOK = responseType === 'OK';
2621
3252
  const statusIcon = responseOK ? 'ResponseOKIcon' : 'ResponseFailIcon';
@@ -2774,50 +3405,6 @@
2774
3405
  return [storedValue, setValue];
2775
3406
  }
2776
3407
 
2777
- const Loader = JSX(({ color = 'text-primary-main', position = 'absolute', blur = true }) => (jsx("div", { className: style('flex justify-center items-center h-full w-full z-50', position, {
2778
- 'backdrop-blur': blur,
2779
- }), children: jsx("div", { className: style('inline-block h-28 w-28', 'animate-spin rounded-full', 'border-8 border-solid border-current', 'border-r-transparent', color), role: "status" }) })));
2780
-
2781
- const Foldable = JSX(({ className = '', isFoldButtonOnTop = false, unfoldedByDefault = false, renderFoldableSection, renderFoldButton, }) => {
2782
- const [isUnfolded, setIsUnfolded] = useState(unfoldedByDefault);
2783
- const onToggle = useCallback(() => {
2784
- setIsUnfolded((_) => !_);
2785
- }, []);
2786
- const sectionNode = renderFoldableSection({ isUnfolded, onToggle });
2787
- const buttonNode = renderFoldButton ? renderFoldButton({ isUnfolded, onToggle }) : null;
2788
- return isFoldButtonOnTop ? (jsxs("div", { className: className, role: "group", children: [buttonNode, sectionNode] })) : (jsxs("div", { className: className, role: "group", children: [sectionNode, buttonNode] }));
2789
- });
2790
-
2791
- function useResizeObserver(callback, deps) {
2792
- const ref = useRef(null);
2793
- useEffect(() => {
2794
- const element = ref?.current;
2795
- if (!element) {
2796
- return undefined;
2797
- }
2798
- const observer = new ResizeObserver((entries) => {
2799
- callback(element, entries[0]);
2800
- });
2801
- observer.observe(element);
2802
- return () => {
2803
- observer.disconnect();
2804
- };
2805
- }, [callback, ...deps]);
2806
- return ref;
2807
- }
2808
-
2809
- const FoldableSection = JSX(({ className = '', isUnfolded, children }) => {
2810
- const containerRef = useRef(null);
2811
- const childrenWrapperRef = useResizeObserver((childrenWrapperEl) => {
2812
- if (containerRef.current) {
2813
- containerRef.current.style.maxHeight = isUnfolded
2814
- ? `${childrenWrapperEl.scrollHeight}px`
2815
- : '';
2816
- }
2817
- }, [isUnfolded]);
2818
- return (jsx("div", { ref: containerRef, className: `transition-max-h duration-300 overflow-hidden ${containerRef.current || !isUnfolded ? 'max-h-0' : ''} `, children: jsx("div", { className: className, ref: childrenWrapperRef, children: children }) }));
2819
- });
2820
-
2821
3408
  const CONSENT_ALL_DOCS_TEXT = 'Согласие на все документы';
2822
3409
  const CONSENT_REQUIRED = 'Отметьте все обязательные соглашения';
2823
3410
  const GroupedConsents = JSX(({ inputs = [], typeForm = '', field, key }) => {
@@ -3060,15 +3647,19 @@
3060
3647
  await sendCode({
3061
3648
  phoneNumber: phoneNumber,
3062
3649
  smsCodesSetName: { key: 'AUTHENTICATION' },
3650
+ }).then((res) => {
3651
+ if (typeof res !== 'string' &&
3652
+ res.errorMessage &&
3653
+ res.errorMessage.startsWith(`Too many request for phoneNumber [${phoneNumber}]`)) {
3654
+ throw res;
3655
+ }
3063
3656
  });
3064
3657
  setAttemps(0);
3065
3658
  setTimeNextReq(180);
3066
3659
  setIsTimerStarted(true);
3067
3660
  }
3068
3661
  catch (e) {
3069
- if (e?.status === 429) {
3070
- captchaDialog.open();
3071
- }
3662
+ captchaDialog.open();
3072
3663
  }
3073
3664
  };
3074
3665
 
@@ -3743,13 +4334,13 @@
3743
4334
  return (jsx(DefaultFoldButton, { icon: icons[Number(isUnfolded)], label: labels[Number(isUnfolded)], onClick: onToggle }));
3744
4335
  };
3745
4336
 
3746
- const ICONS$1 = ['ArrowDownIcon', 'ArrowUpIcon'];
4337
+ const ICONS = ['ArrowDownIcon', 'ArrowUpIcon'];
3747
4338
  const resultsGridStyle = 'space-y-px lg:space-y-0 lg:grid lg:grid-cols-12 gap-2xs';
3748
4339
  const renderGridBlocks = ({ topItemsCount = 0, label = '', block, blocksToRender = [], ...rest }) => {
3749
4340
  const [visibleBlocks, hiddenBlocks] = topItemsCount > 0
3750
4341
  ? [blocksToRender.slice(0, topItemsCount), blocksToRender.slice(topItemsCount)]
3751
4342
  : [blocksToRender, []];
3752
- return (jsxs("div", { className: style('space-y-2xs', { hidden: !blocksToRender.length }), children: [jsxs("div", { className: style(resultsGridStyle), children: [renderBlocksList(visibleBlocks, { ...rest.options, parent: block }), isOdd(visibleBlocks.length) ? jsx(AdTile, { className: "col-span-6", ...rest }) : null] }), jsx(Foldable, { renderFoldableSection: ({ isUnfolded }) => (jsxs(FoldableSection, { className: style(resultsGridStyle), isUnfolded: isUnfolded, children: [renderBlocksList(hiddenBlocks, { ...rest.options, parent: block }), isOdd(hiddenBlocks.length) ? jsx(AdTile, { className: "col-span-6", ...rest }) : null] })), renderFoldButton: ({ isUnfolded, onToggle }) => (jsx(DefaultFoldButton, { className: style({ hidden: topItemsCount < 1 }), disabled: !hiddenBlocks?.length, label: label, icon: ICONS$1[Number(isUnfolded)], dataTheme: rest.options?.page?.colorPalette, onClick: onToggle })) })] }));
4343
+ return (jsxs("div", { className: style('space-y-2xs', { hidden: !blocksToRender.length }), children: [jsxs("div", { className: style(resultsGridStyle), children: [renderBlocksList(visibleBlocks, { ...rest.options, parent: block }), isOdd(visibleBlocks.length) ? jsx(AdTile, { className: "col-span-6", ...rest }) : null] }), jsx(Foldable, { renderFoldableSection: ({ isUnfolded }) => (jsxs(FoldableSection, { className: style(resultsGridStyle), isUnfolded: isUnfolded, children: [renderBlocksList(hiddenBlocks, { ...rest.options, parent: block }), isOdd(hiddenBlocks.length) ? jsx(AdTile, { className: "col-span-6", ...rest }) : null] })), renderFoldButton: ({ isUnfolded, onToggle }) => (jsx(DefaultFoldButton, { className: style({ hidden: topItemsCount < 1 }), disabled: !hiddenBlocks?.length, label: label, icon: ICONS[Number(isUnfolded)], dataTheme: rest.options?.page?.colorPalette, onClick: onToggle })) })] }));
3753
4344
  };
3754
4345
 
3755
4346
  const FilteredBlocks = JSX(({ blocksSection, blocksToRender = [], notFound, ...rest }) => {
@@ -5063,10 +5654,10 @@
5063
5654
  }
5064
5655
  }), [options?.parent]);
5065
5656
  return (jsxs(BlockWrapper, { className: style('flex flex-col', className), defaultPadding: "p-2xl", ...rest, children: [isIcon(icon) ? (jsx("div", { className: "self-center", children: jsx(Img, { image: icon }) })) : null, title ? (jsx(Heading, { className: style('pt-xs', align), headingType: "h5", title: title })) : null, button?.text ? jsx(LinkButton, { className: "w-full mt-m mb-lg", ...button }) : null, hiddenCells.length ? (jsx(Foldable, { renderFoldableSection: () => (jsxs("div", { children: [visibleCells, jsx(FoldableSection, { isUnfolded: isVisible, children: hiddenCells })] })), renderFoldButton: cardCells.length >= visibleCellsCount
5066
- ? renderFoldButton$3(options?.parent, data, isVisible)
5657
+ ? renderFoldButton$1(options?.parent, data, isVisible)
5067
5658
  : null })) : (jsx("div", { children: visibleCells }))] }));
5068
5659
  });
5069
- const renderFoldButton$3 = (parent, data, isUnfolded = false) => () => (jsxs("button", { className: "w-full cursor-pointer text-primary-main pt-lg flex justify-between items-center", onClick: () => {
5660
+ const renderFoldButton$1 = (parent, data, isUnfolded = false) => () => (jsxs("button", { className: "w-full cursor-pointer text-primary-main pt-lg flex justify-between items-center", onClick: () => {
5070
5661
  if (parent !== undefined) {
5071
5662
  defaultEventBus.fire('fold', { type: 'fold', isUnfolded: !isUnfolded, parent });
5072
5663
  }
@@ -5136,8 +5727,8 @@
5136
5727
  creditInRshbCd: '',
5137
5728
  },
5138
5729
  5: {
5139
- region: '',
5140
- addressBranch: '',
5730
+ regionRetail: '',
5731
+ addressRetail: '',
5141
5732
  bankEmployeeCode: '',
5142
5733
  },
5143
5734
  };
@@ -5393,10 +5984,10 @@
5393
5984
  inputs: [],
5394
5985
  },
5395
5986
  {
5396
- inputs: [{ fieldType: 'common', name: 'region', required: true }],
5987
+ inputs: [{ fieldType: 'common', name: 'regionRetail', required: true }],
5397
5988
  },
5398
5989
  {
5399
- inputs: [{ fieldType: 'common', name: 'addressBranch', required: true }],
5990
+ inputs: [{ fieldType: 'common', name: 'addressRetail', required: true }],
5400
5991
  },
5401
5992
  {
5402
5993
  title: 'Код представителя Банка',
@@ -5767,824 +6358,458 @@
5767
6358
  });
5768
6359
  }
5769
6360
  };
5770
- const handleInputBuy = (setCalcState, currencyRatesBuy) => (value, currencyTo, currencyFrom) => {
5771
- setCalcState({ inputBuy: formatValue(value), selectSell: currencyFrom });
5772
- const rate = currencyRatesBuy.find((_) => _.currency?.currency === currencyFrom)?.saleExchangeRate ||
5773
- currencyRatesBuy.find((_) => _.currency?.currency === currencyTo)?.saleExchangeRate;
5774
- if (rate) {
5775
- setCalcState({
5776
- inputSell: String(calculateResult(value, rate, currencyTo === Currency.RUB) || ''),
5777
- });
5778
- }
5779
- };
5780
-
5781
- const EXCHANGE_RATES_URL = `${API_BASE_URI}/exchangerates`;
5782
- function useFetchExchangeRateData(currentRegion) {
5783
- const regionCode = currentRegion?.code || '000';
5784
- const { data } = useAsyncData(EXCHANGE_RATES_URL + `?regionCode=${regionCode}`, fetchJSONUnsafe);
5785
- return data || {};
5786
- }
5787
-
5788
- const ExchangeRateTile = JSX(({ className = '', title = 'Курсы обмена валют', button, ...rest }) => {
5789
- const [currentLocation] = useLocation();
5790
- const exchangeRates = useFetchExchangeRateData(currentLocation);
5791
- const currencyRates = getCurrencyRates(exchangeRates?.exchangeRate?.currencies);
5792
- const currencyRatesBuy = currencyRates.filter((_) => _.buyExchangeRate);
5793
- currencyRatesBuy.unshift({ currency: { currency: Currency.RUB } });
5794
- const currencyRatesSell = currencyRates.filter((_) => _.saleExchangeRate);
5795
- currencyRatesSell.push({ currency: { currency: Currency.RUB } });
5796
- return (jsx(BlockWrapper, { className: style('box-border min-h-80', className), ...rest, children: jsx(BaseTile, { className: "h-full", title: jsx(Heading, { headingType: "h4", title: title, className: "whitespace-pre-wrap" }), children: jsxs("div", { className: "flex w-full gap-6xl flex-wrap @lg:flex-nowrap", children: [jsxs("div", { className: "w-full @2xl:w-auto @5xl:w-1/2", children: [currencyRates ? (jsx(CurrencyTable, { className: "mb-xl", exchangeCurrencyItems: currencyRates })) : null, jsx(CurrentLocation, { address: exchangeRates?.address })] }), jsx(ExchangeCurrencyCalculator, { className: "grow w-1/2", currencyRatesBuy: currencyRatesBuy, currencyRatesSell: currencyRatesSell, button: button })] }) }) }));
5797
- });
5798
- const getCurrencyRates = (currencies) => currencies?.filter((_) => [1, 2, 3].includes(_?.currency?.id)) || [];
5799
-
5800
- const LinkList = JSX(({ className = '', items }) => {
5801
- const link = useLink();
5802
- return (jsx("ul", { className: style('flex flex-col gap-s w-full', className), children: items?.map(renderLinkListItem(link)) }));
5803
- });
5804
- const renderLinkListItem = (link) => ({ dataFooter, ...linkProps }, i) => {
5805
- const { text, href, target, onClick } = link(linkProps);
5806
- if (!text) {
5807
- return null;
5808
- }
5809
- return (jsx("li", { className: "list-none", children: jsx("a", { className: "hover:text-primary-main font-light", role: "link", href: href, target: target || '_self', onClick: onClick, ...getAspectsAttributes(dataFooter), children: text ? text : null }) }, String(i)));
5810
- };
5811
-
5812
- const AccordionFoldButton = JSX(({ label, labelIconBgVersion, icon, onToggle, labelIcon }) => (jsx(TextWithIcon, { tag: "button", className: style('border-none bg-transparent items-center group/button', labelIcon?.icon ? 'py-xs' : 'py-lg'), onClick: onToggle, textNode: jsxs("div", { className: "flex items-center text-start group-hover/button:text-primary-main gap-s", children: [renderRoundedIcon(labelIcon, labelIconBgVersion), label ? (jsx(Text, { size: "text-h6", font: "font-normal", children: label })) : null] }), iconNode: icon ? jsx(Icon, { name: icon, iconVersion: "color", width: "24", height: "24" }) : null })));
5813
-
5814
- const getFoldableStyles = (isMobile = false) => isMobile ? 'flex flex-wrap group-last:last:pb-0' : 'grid grid-cols-12 [&>*]:pb-m';
5815
-
5816
- const getIconName = (isUnfolded = false, isMobile = false) => isMobile ? getMobileName(isUnfolded) : getDesktopName(isUnfolded);
5817
- const getDesktopName = (isUnfolded = false) => (isUnfolded ? 'MinusIcon' : 'PlusIcon');
5818
- const getMobileName = (isUnfolded = false) => isUnfolded ? 'ArrowUpSolidIcon' : 'ArrowDownSolidIcon';
5819
-
5820
- const RollupItem = UniBlock(({ className = '', isExpanded, isFoldButtonOnTop = true, label = 'Развернуть', labelIcon, labelIconBgVersion, foldButtonVersion = 'default',
5821
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
5822
- version, role, ...rest }) => {
5823
- const isMobile = useMobileMode();
5824
- return (jsx(BlockWrapper, { className: style('w-full border-0 border-b border-solid border-main-divider last:border-b-0', className), defaultPadding: "p-0", tag: "div", version: "transparent", role: role, ...rest, children: jsx(Foldable, { isFoldButtonOnTop: isFoldButtonOnTop, unfoldedByDefault: isExpanded, renderFoldableSection: ({ isUnfolded }) => (jsx(FoldableSection, { className: style('gap-lg', getFoldableStyles(isMobile)), isUnfolded: isUnfolded, children: renderChildren({
5825
- ...rest,
5826
- extraProps: { className: 'w-full', padding: 'p-0' },
5827
- }) })), renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton$2({
5828
- foldButtonVersion,
5829
- label,
5830
- labelIcon,
5831
- labelIconBgVersion,
5832
- isUnfolded,
5833
- onToggle,
5834
- isMobile,
5835
- }) }) }));
5836
- }, {
5837
- childrenTypes: { exclude: ['RollupItem'] },
5838
- });
5839
- const renderFoldButton$2 = ({ foldButtonVersion, label: defaultLabel, labelIcon, labelIconBgVersion, isUnfolded, onToggle, isMobile = false, }) => {
5840
- const label = defaultLabel || (isUnfolded ? 'Скрыть' : 'Развернуть');
5841
- const icon = getIconName(isUnfolded, isMobile);
5842
- return foldButtonVersion === 'accordion' ? (jsx(AccordionFoldButton, { label: label, labelIcon: labelIcon, labelIconBgVersion: labelIconBgVersion, icon: icon, onToggle: onToggle })) : (jsx(DefaultFoldButton, { label: label, icon: isUnfolded ? 'ArrowUpIcon' : 'ArrowDownIcon', onClick: onToggle }));
5843
- };
5844
-
5845
- const Sitemap = JSX(({ navigationItems }) => (jsx("div", { className: "w-full", role: "menu", children: renderTopItems(navigationItems) })));
5846
- const renderTopItems = (topItems) => topItems
5847
- ?.filter((_) => _.icon?.icon)
5848
- .map((item, i) => (jsx(RollupItem, { foldButtonVersion: "accordion", label: item?.text, labelIcon: item?.icon, role: "menuitem", children: item.items ? jsx(LinkList, { items: item.items }) : null }, String(i))));
5849
-
5850
- const Contacts = JSX(({ className = '', items = [] }) => items?.length ? (jsx("div", { className: style('space-y-m', className), children: items.map(renderContactsGroup) })) : null);
5851
- const renderContactsGroup = (item, i) => (jsxs("div", { className: "space-y-m", children: [jsx("div", { children: jsx(Text, { size: "text-l", font: "font-medium", children: item?.title }) }), jsx("div", { className: "space-y-m", children: item.items?.map(renderContact) })] }, String(i)));
5852
- const renderContact = (item, i) => (jsxs("div", { className: "space-y-2xs", children: [jsx("div", { children: renderText$1(item.type, item.text) }), jsx(Paragraph, { size: "text-s", font: "font-light", color: "text-secondary-text", children: item.description })] }, String(i)));
5853
- const renderText$1 = (type, text = '') => {
5854
- switch (type) {
5855
- case 'tel':
5856
- return (jsx("a", { className: "text-primary-text hover:text-primary-main no-underline", href: `tel:${formatTel(text)}`, children: jsx(Text, { size: "text-h6", children: text }) }));
5857
- case 'email':
5858
- return (jsx("a", { className: "no-underline", href: `mailto:${text}`, children: jsx(Paragraph, { size: "text-xl", font: "font-light", color: "text-primary-text", children: text }) }));
5859
- default:
5860
- return jsx("span", { children: text });
5861
- }
5862
- };
5863
- const formatTel = (s) => s.replaceAll(/\D/g, '');
5864
-
5865
- const HorizontalNavigationLink = JSX(({ className = '', index, text, ...rest }) => {
5866
- const link = useLink();
5867
- const { href, target, onClick } = link(rest);
5868
- return (jsx("a", { className: style('text-secondary-text', className), href: href, target: target, onClick: onClick, children: text || `Документ ${index}` }));
5869
- });
5870
-
5871
- const HorizontalNavigation = JSX(({ className = '', title, links }) => (jsx("div", { className: className, children: links?.length ? (jsxs("div", { className: "flex justify-between lg:items-center flex-col lg:flex-row gap-lg py-lg border-y border-y-main-divider", children: [jsx("div", { className: "lg:hidden", children: jsx(Text, { size: "text-l", font: "font-normal", children: title }) }), links.map((_, i) => (jsx(HorizontalNavigationLink, { index: i, className: "text-l font-light lg:max-w-[292px]", ..._ }, String(i))))] })) : null })));
5872
-
5873
- const LEFT_COLUMN_STYLE = 'w-full lg:w-52';
5874
-
5875
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
5876
- const renderLogoSearchBar = (common, navigationItems) => null;
5877
-
5878
- const TextInformationLink = JSX(({ className = '', index, ...rest }) => {
5879
- const link = useLink();
5880
- const { href, target, text, onClick } = link(rest);
5881
- return (jsx("a", { className: style('text-xs font-light text-secondary-text visited:text-secondary-text hover:text-primary-main inline-block no-underline max-w-[292px]', className), href: href, target: target, onClick: onClick, children: text || `Документ ${index}` }));
5882
- });
5883
-
5884
- const TextInformation = JSX(({ className = '', links, license }) => (jsxs("div", { className: style('@container space-y-lg', className), children: [license ? (jsx("div", { children: jsx(Text, { size: "text-xs", font: "font-light", color: "text-secondary-text", children: `\u00a9\u00A02000-${new Date().getFullYear()}\u00A0${license}` }) })) : null, links?.length ? (jsx("div", { className: "flex flex-col @5xl:flex-row justify-start items-start gap-x-lg gap-y-xs", children: links.map((_, i) => (jsx(TextInformationLink, { index: i, ..._ }, String(i)))) })) : null] })));
5885
-
5886
- const Footer = UniBlock(({ className, footer, ...rest }) => {
5887
- const { navigationItems } = rest.options?.page?.navigation ?? {};
5888
- rest.options?.page?.common ?? {};
5889
- const { documents, relatedEnterprises, contacts, mediaLinks = [], horizontalNavigationTitle, feedbackButton, license, otherLinks = [], } = footer ?? {};
5890
- const linkStyle = '!text-left text-s font-light';
5891
- return (jsxs(BlockWrapper, { tag: "footer", className: style('grid gap-y-xl p-4xl pb-24 lg:p-xl', className), ...rest, children: [renderLogoSearchBar(), jsxs("div", { className: "flex flex-col lg:flex-row items-center @lg:items-stretch gap-lg lg:gap-6xl ", children: [jsx(Sitemap, { navigationItems: navigationItems }), jsx("div", { className: "border-t border-main-divider lg:hidden w-full" }), jsxs("div", { className: style(LEFT_COLUMN_STYLE, 'flex flex-col shrink-0 overflow-hidden space-y-xl'), children: [jsx(Contacts, { items: contacts }), feedbackButton ? (jsx(LinkButton, { className: "w-full", version: "primary", ...feedbackButton })) : null, mediaLinks.map((_, i) => (jsx(SocialMedia, { media: _?.links ?? [], showButtonText: false, stretched: true, children: _?.title }, String(i)))), otherLinks.map((_, i) => (jsx(LinkButton, { className: linkStyle, version: "link", ..._, children: _?.text }, String(i))))] })] }), jsx(HorizontalNavigation, { title: horizontalNavigationTitle, links: relatedEnterprises }), jsx(TextInformation, { links: documents, license: license })] }));
5892
- });
5893
-
5894
- const GrantSupport = UniBlock(({ className, title, button, regionSource, data, ...rest }) => {
5895
- const [region, setRegion] = useState({ key: '' });
5896
- const regions = regionSource?.regions ?? [];
5897
- const buttonStyle = getRegularButtonClasses({
5898
- className: 'text-white',
5899
- version: button?.version || 'primary',
5900
- });
5901
- const regionHref = regions?.find((_) => _.name === region.key)?.href;
5902
- const buttonText = button?.text ? button.text : 'Перейти';
5903
- return (jsx(BlockWrapper, { className: className, defaultPadding: "p-6xl", ...rest, children: jsxs("div", { className: "container max-w-[978px] space-y-m", children: [title ? jsx(Heading, { headingType: "h3", title: title, className: "@xl:text-center" }) : null, regions ? (jsx(SelectControl, { label: "\u0412\u0430\u0448 \u0440\u0435\u0433\u0438\u043E\u043D", placeholder: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0440\u0435\u0433\u0438\u043E\u043D", isSearch: true, options: regions.map(({ name = '' }) => ({ key: name, text: name })), value: region, onChange: setRegion })) : null, regionHref ? (jsx("div", { className: "text-center", children: jsx(LinkButton, { href: regionHref, target: "_blank", className: style('p-m w-full @xl:w-auto', buttonStyle), data: getAspectsWithInclude(data, region?.key), children: buttonText }) })) : null] }) }));
5904
- });
5905
-
5906
- const BUTTON_STYLE = {
5907
- default: 'bg-main-divider text-primary-main rounded hover:text-primary-main',
5908
- transparent: 'backdrop-opacity-30 bg-white/30 hover:text-primary-hover text-white',
5909
- };
5910
- const InternetBankButton = JSX(({ version, text, mobileText, ...rest }) => {
5911
- const isMobileMode = useMobileMode();
5912
- const buttonText = isMobileMode ? mobileText : text;
5913
- return buttonText ? (jsx(LinkButton, { className: style('py-s px-lg font-light whitespace-nowrap', BUTTON_STYLE[version === 'transparent' ? 'transparent' : 'default']), ...rest, children: buttonText })) : null;
5914
- });
5915
-
5916
- const HeaderTop = JSX(({ bgColor, logo, alwaysShowLogo, internetBankButton, version, backwardButton }) => {
5917
- const router = useRouter();
5918
- const isRootLocation = router.pathname === '/';
5919
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
5920
- const { dataFooter, dataHeader, ...logoProps } = logo ?? {};
5921
- const onClick = useCallback(() => {
5922
- router.back();
5923
- }, [router]);
5924
- return (jsxs("div", { className: "flex items-center justify-between w-full", children: [alwaysShowLogo || isRootLocation ? (jsx("div", { children: jsx(Logo, { className: "my-2xs", bgColor: bgColor, logo: logoProps, data: dataHeader, showTitle: false }) })) : (renderBackButton(onClick, backwardButton)), jsx(InternetBankButton, { version: version, ...internetBankButton })] }));
5925
- });
5926
- const renderBackButton = (onClick, text) => text ? (jsxs("button", { className: "flex items-center text-l my-2xs", onClick: onClick, type: "button", "aria-label": "\u041A\u043D\u043E\u043F\u043A\u0430 \u043D\u0430\u0437\u0430\u0434", children: [jsx(Icon, { name: "ChevronLeftIcon", iconVersion: "black", width: "24", height: "24" }), text] })) : null;
5927
-
5928
- const BG_COLOR_TO_BLOCK_VERSION = {
5929
- 'bg-white': 'primary',
5930
- transparent: 'transparent',
5931
- };
5932
- const Header = UniBlock(({ bgColor = 'bg-white', alwaysShowLogo = false, version = BG_COLOR_TO_BLOCK_VERSION[bgColor], portal, logo: customLogo = {}, ...rest }) => {
5933
- const { backwardButton, logo = {} } = rest.options?.page?.common ?? {};
5934
- const { internetBankButton } = portal || {};
5935
- const logoProps = customLogo.image?.icon || customLogo.image?.src ? customLogo : logo;
5936
- return (jsx(BlockWrapper, { tag: "header", defaultPadding: "", version: version, ...rest, children: jsx("div", { className: "container px-lg py-2xs box-border", children: jsx(HeaderTop, { bgColor: bgColor, logo: logoProps, alwaysShowLogo: alwaysShowLogo, internetBankButton: internetBankButton, version: version, backwardButton: backwardButton, ...rest }) }) }));
5937
- });
5938
-
5939
- const getInnerPadding = (isPadding = false) => isPadding ? {} : { padding: 'p-0' };
5940
-
5941
- const gapStyles = {
5942
- XXL: 'gap-6xl',
5943
- XL: 'gap-5xl',
5944
- L: 'gap-3xl',
5945
- M: 'gap-m',
5946
- S: 'gap-xs',
5947
- XS: 'gap-2xs',
5948
- '': '',
5949
- };
5950
-
5951
- const VerticalLayout = UniBlock(({ className = '', padding = 'p-0', gap = '', isInnerPadding = true, version = 'transparent', isTheme = false, isCardBorder = false, image, ...rest }) => {
5952
- const router = useRouter();
5953
- return (jsx(BlockWrapper, { className: style('relative flex flex-col', gapStyles[gap], image?.src ? 'bg-right-bottom bg-no-repeat' : '', className), ...(image?.src
5954
- ? { style: { backgroundImage: `url(${adjustSrc(router)(image?.src)})` } }
5955
- : {}), padding: padding, version: version, isTheme: isTheme, ...rest, children: renderChildren({
5956
- ...rest,
5957
- extraProps: {
5958
- className: style('w-full', getBorderStyle(isCardBorder)),
5959
- ...getInnerPadding(isInnerPadding),
5960
- },
5961
- }) }));
5962
- }, { childrenTypes: [] });
5963
-
5964
- const HorizontalLayout = UniBlock((props) => jsx(VerticalLayout, { ...props }), { childrenTypes: [] });
5965
-
5966
- const ImgBlock = JSX((props) => {
5967
- const { className, align, image, ...rest } = props;
5968
- const alignStyle = align ? style('flex', AlignJustifyStyle[align]) : '';
5969
- return (jsx(BlockWrapper, { className: style(alignStyle, className), defaultPadding: "p-0", ...rest, children: jsx(Img, { image: image }) }));
5970
- });
5971
-
5972
- const KILO = 1024;
5973
- const KILO_SIZES = ['байт', 'Кб', 'Мб', 'Гб', 'Тб', 'Пб'];
5974
- const formatBytes = (bytes, decimals = 2) => {
5975
- if (bytes === 0) {
5976
- return '';
5977
- }
5978
- const i = Math.floor(Math.log(bytes) / Math.log(KILO));
5979
- return `${parseFloat((bytes / Math.pow(KILO, i)).toFixed(decimals))} ${KILO_SIZES[i]}`;
5980
- };
5981
-
5982
- const LinkDocItem = JSX(({ icon, text, href, target, fileFormat, data, fileSize }) => {
5983
- const prefix = fileSize && fileFormat ? ',' : '';
5984
- const size = fileSize ?? '';
5985
- const format = fileFormat ? String(fileFormat) : '';
5986
- return (jsxs("a", { className: "flex box-border gap-s group/item h-fit w-fit text-primary-text no-underline hover:text-primary-main", href: href, target: target, ...getAspectsAttributes(data), children: [icon, text ? (jsxs(Text, { size: "text-l", font: "font-light", children: [text, " ", addSpace(size, format), jsx(Text, { color: "text-secondary-text", children: href && `${size + prefix + format}` })] })) : null] }));
5987
- });
5988
- const addSpace = (size, format) => (size || format ? jsx("span", { children: ",\u00A0" }) : '');
5989
-
5990
- const linkIconStyle = 'min-w-11 min-h-11 h-fit p-2.5 bg-main-divider rounded-md';
5991
-
5992
- const renderDefaultItem = (router, icon) => (docBlockDef, i) => {
5993
- const href = adjustHref(router)(docBlockDef?.docType === 'Attachment' ? docBlockDef?.attachment?.src : docBlockDef?.href);
5994
- const fileSize = docBlockDef?.docType === 'Attachment'
5995
- ? formatBytes(docBlockDef?.attachment?.fileSize || 0)
5996
- : docBlockDef?.fileSize;
5997
- const fileFormat = docBlockDef?.docType === 'Attachment' ? getExtFromHref(href) : docBlockDef?.fileFormat;
5998
- return (jsxs("div", { role: "listitem", children: [jsx(LinkDocItem, { text: docBlockDef?.text, target: docBlockDef?.target, href: href, fileFormat: fileFormat, fileSize: fileSize, icon: renderImg(icon), data: docBlockDef?.data }), jsx(RichText, { __html: docBlockDef?.__html })] }, String(i)));
5999
- };
6000
- const renderImg = (icon) => icon ? jsx(Img, { className: linkIconStyle, image: icon, width: "24", height: "24" }) : null;
6001
- const getExtFromHref = (href) => {
6002
- if (!href) {
6003
- return '';
6004
- }
6005
- const index = href.lastIndexOf('.');
6006
- const regexp = new RegExp(/\/(.*)/);
6007
- const docFormat = index !== -1 ? href.substring(index + 1) : '';
6008
- return docFormat.includes('/') ? docFormat.replace(regexp, '') : docFormat;
6009
- };
6010
-
6011
- const ReportDialog = JSX(({ href, __html, target }) => {
6012
- const { close } = useDialogManager();
6013
- const router = useRouter();
6014
- const adjustedHref = adjustHref(router)(href);
6015
- const handleClose = useCallback(() => {
6016
- close();
6017
- }, []);
6018
- return (jsxs(Dialog, { className: "my-6xl min-h-fit w-fit mx-auto", children: [__html ? jsx(RichText, { __html: __html }) : null, jsxs("div", { className: "flex flex-row mx-auto w-fit gap-lg py-lg", children: [jsx(LinkButton, { text: "\u042F \u0441\u043E\u0433\u043B\u0430\u0441\u0435\u043D", version: "primary", target: target, href: adjustedHref, onClick: handleClose }), jsx(Button, { type: "button", version: "secondary", onClick: handleClose, children: "\u042F \u043D\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u0435\u043D" })] }), jsx("div", { children: "\u041D\u0430\u0436\u0438\u043C\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0443 \u00AB\u042F \u0421\u041E\u0413\u041B\u0410\u0421\u0415\u041D\u00BB \u043D\u0438\u0436\u0435 \u0412\u044B \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u0443\u0441\u043B\u043E\u0432\u0438\u044F. \u0420\u0430\u0441\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u0435 \u0438\u043B\u0438 \u0440\u0430\u0441\u043A\u0440\u044B\u0442\u0438\u0435 \u043B\u044E\u0431\u043E\u0439 \u0447\u0430\u0441\u0442\u0438 \u0434\u0430\u043D\u043D\u043E\u0433\u043E \u0417\u0430\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F \u0438\u043B\u0438 \u043B\u044E\u0431\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438, \u0438\u043B\u0438 \u0440\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0430\u0446\u0438\u0438 \u0432 \u043D\u0435\u043C \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u043E.\u00BB" })] }));
6019
- });
6020
-
6021
- const useReportDialog = (props) => {
6022
- const { open, close } = useDialogManager();
6023
- return {
6024
- open: (options = {}) => open(jsx(ReportDialog, { ...props }), options),
6025
- close,
6026
- };
6361
+ const handleInputBuy = (setCalcState, currencyRatesBuy) => (value, currencyTo, currencyFrom) => {
6362
+ setCalcState({ inputBuy: formatValue(value), selectSell: currencyFrom });
6363
+ const rate = currencyRatesBuy.find((_) => _.currency?.currency === currencyFrom)?.saleExchangeRate ||
6364
+ currencyRatesBuy.find((_) => _.currency?.currency === currencyTo)?.saleExchangeRate;
6365
+ if (rate) {
6366
+ setCalcState({
6367
+ inputSell: String(calculateResult(value, rate, currencyTo === Currency.RUB) || ''),
6368
+ });
6369
+ }
6027
6370
  };
6028
6371
 
6029
- const ReportDialogButton = JSX(({ text, href, target, __html, icon }) => {
6030
- if (!text && !__html) {
6031
- return null;
6032
- }
6033
- const reportDialog = useReportDialog({ __html, href, target });
6034
- const openReportDialog = useCallback(() => reportDialog.open(), [reportDialog]);
6035
- return (jsxs("button", { className: "flex gap-s text-primary-text no-underline hover:text-primary-main", onClick: openReportDialog, children: [renderImg(icon), jsx(Text, { font: "font-light", children: text })] }));
6372
+ const EXCHANGE_RATES_URL = `${API_BASE_URI}/exchangerates`;
6373
+ function useFetchExchangeRateData(currentRegion) {
6374
+ const regionCode = currentRegion?.code || '000';
6375
+ const { data } = useAsyncData(EXCHANGE_RATES_URL + `?regionCode=${regionCode}`, fetchJSONUnsafe);
6376
+ return data || {};
6377
+ }
6378
+
6379
+ const ExchangeRateTile = JSX(({ className = '', title = 'Курсы обмена валют', button, ...rest }) => {
6380
+ const [currentLocation] = useLocation();
6381
+ const exchangeRates = useFetchExchangeRateData(currentLocation);
6382
+ const currencyRates = getCurrencyRates(exchangeRates?.exchangeRate?.currencies);
6383
+ const currencyRatesBuy = currencyRates.filter((_) => _.buyExchangeRate);
6384
+ currencyRatesBuy.unshift({ currency: { currency: Currency.RUB } });
6385
+ const currencyRatesSell = currencyRates.filter((_) => _.saleExchangeRate);
6386
+ currencyRatesSell.push({ currency: { currency: Currency.RUB } });
6387
+ return (jsx(BlockWrapper, { className: style('box-border min-h-80', className), ...rest, children: jsx(BaseTile, { className: "h-full", title: jsx(Heading, { headingType: "h4", title: title, className: "whitespace-pre-wrap" }), children: jsxs("div", { className: "flex w-full gap-6xl flex-wrap @lg:flex-nowrap", children: [jsxs("div", { className: "w-full @2xl:w-auto @5xl:w-1/2", children: [currencyRates ? (jsx(CurrencyTable, { className: "mb-xl", exchangeCurrencyItems: currencyRates })) : null, jsx(CurrentLocation, { address: exchangeRates?.address })] }), jsx(ExchangeCurrencyCalculator, { className: "grow w-1/2", currencyRatesBuy: currencyRatesBuy, currencyRatesSell: currencyRatesSell, button: button })] }) }) }));
6036
6388
  });
6389
+ const getCurrencyRates = (currencies) => currencies?.filter((_) => [1, 2, 3].includes(_?.currency?.id)) || [];
6037
6390
 
6038
- const linkColumnsModeStyleMap = {
6039
- double: 'sm:flex-wrap sm:flex-row',
6040
- single: 'sm:flex-col',
6041
- };
6042
- const LinkDocs = UniBlock(({ className = '', title, description, align = 'text-center', documents, icon = { icon: 'DocIcon' }, columnsMode = 'double', ...rest }) => {
6043
- const router = useRouter();
6044
- return (jsxs(BlockWrapper, { className: style('space-y-lg', className), defaultPadding: "p-6xl", ...rest, children: [jsx(Headline, { title: title, description: description, align: align, headlineVersion: "M", as: "h2", isEmbedded: true }), documents?.length ? (jsx("div", { className: style('grid gap-xl', columnsMode === 'double' ? '@md:grid-cols-2' : 'grid-cols-1', linkColumnsModeStyleMap[columnsMode]), role: "list", children: documents.map(renderLinkDocItem(router, icon)) })) : null] }));
6391
+ const LinkList = JSX(({ className = '', items }) => {
6392
+ const link = useLink();
6393
+ return (jsx("ul", { className: style('flex flex-col gap-s w-full', className), children: items?.map(renderLinkListItem(link)) }));
6045
6394
  });
6046
- const renderLinkDocItem = (router, icon) => (docBlockDef, i) => {
6047
- const docType = docBlockDef?.docType;
6048
- if (docType === '') {
6395
+ const renderLinkListItem = (link) => ({ dataFooter, ...linkProps }, i) => {
6396
+ const { text, href, target, onClick } = link(linkProps);
6397
+ if (!text) {
6049
6398
  return null;
6050
6399
  }
6051
- if ('reportSource' in docBlockDef && docBlockDef?.reportSource?.__html) {
6052
- return renderModalItem(icon)(docBlockDef, i);
6053
- }
6054
- return renderDefaultItem(router, icon)(docBlockDef, i);
6055
- };
6056
- const renderModalItem = (icon) => (props, i) => {
6057
- const commonProps = {
6058
- text: props.text,
6059
- target: props.target,
6060
- __html: props.reportSource?.__html,
6061
- };
6062
- return props.reportSource?.__html && props.text ? (jsxs("div", { role: "listitem", children: [jsx(ReportDialogButton, { ...commonProps, icon: icon, href: isLinkDoc(props) ? props?.href : props?.attachment?.src }), jsx(RichText, { __html: props?.__html })] }, String(i))) : null;
6400
+ return (jsx("li", { className: "list-none", children: jsx("a", { className: "hover:text-primary-main font-light", role: "link", href: href, target: target || '_self', onClick: onClick, ...getAspectsAttributes(dataFooter), children: text ? text : null }) }, String(i)));
6063
6401
  };
6064
- const isLinkDoc = (data) => 'href' in data;
6065
6402
 
6066
- const MobileAppTile = UniBlock(({ className, padding, align = 'text-left', buttons = [], description, image, __html, headingType, qr, additionalDescription = '', title = 'Мобильное приложение', version = 'primary', ...rest }) => {
6067
- const containerStyle = version === 'secondary' ? 'p-m min-w-32' : 'min-w-24';
6068
- const img = image?.src ? jsx(Img, { className: "hidden lg:block", image: image }) : null;
6069
- return (jsx(BlockWrapper, { className: style('min-h-80', className), padding: "p-0", version: version, ...rest, children: jsxs(BaseTile, { className: "h-full", padding: padding, defaultPadding: "p-6xl", title: jsx(Heading, { headingType: headingType, title: title, className: style('whitespace-pre-wrap', align) }), rightImage: img, buttons: renderButtonsSection(buttons, { className: 'flex-wrap' }), children: [description ? (jsx(Text, { size: "text-xl", "font-weight": "font-light", children: description })) : null, jsxs("div", { className: style('gap-m', 'flex flex-1 flex-col', 'flex-col items-start @xl:flex-row @xl:items-center'), children: [__html ? jsx(RichText, { __html: __html, itemSize: "list-m" }) : null, jsx(Text, { size: "text-m", "font-weight": "font-light", color: "text-secondary-text", children: additionalDescription }), qr?.src ? (jsx("div", { className: style('flex justify-center bg-white rounded-md @xl:-order-1', containerStyle), children: jsx(Img, { className: "w-fit", image: qr }) })) : null, image?.src ? jsx(Img, { className: "lg:hidden", image: image }) : null] })] }) }));
6070
- });
6403
+ const AccordionFoldButton = JSX(({ label, labelIconBgVersion, icon, onToggle, labelIcon }) => (jsx(TextWithIcon, { tag: "button", className: style('border-none bg-transparent items-center group/button', labelIcon?.icon ? 'py-xs' : 'py-lg'), onClick: onToggle, textNode: jsxs("div", { className: "flex items-center text-start group-hover/button:text-primary-main gap-s", children: [renderRoundedIcon(labelIcon, labelIconBgVersion), label ? (jsx(Text, { size: "text-h6", font: "font-normal", children: label })) : null] }), iconNode: icon ? jsx(Icon, { name: icon, iconVersion: "color", width: "24", height: "24" }) : null })));
6071
6404
 
6072
- const getVersion = (isPrimary, type) => isPrimary && type !== 'underlined' ? 'primary' : 'secondary';
6405
+ const getFoldableStyles = (isMobile = false) => isMobile ? 'flex flex-wrap group-last:last:pb-0' : 'grid grid-cols-12 [&>*]:pb-m';
6073
6406
 
6074
- const getBadgeCount = (blocks = [], filter = {}) => blocks.filter(({ content = {} }) => targetMatchPattern(filter, content)).length;
6407
+ const getIconName = (isUnfolded = false, isMobile = false) => isMobile ? getMobileName(isUnfolded) : getDesktopName(isUnfolded);
6408
+ const getDesktopName = (isUnfolded = false) => (isUnfolded ? 'MinusIcon' : 'PlusIcon');
6409
+ const getMobileName = (isUnfolded = false) => isUnfolded ? 'ArrowUpSolidIcon' : 'ArrowDownSolidIcon';
6075
6410
 
6076
- const scalarCmp = (a, b) => a === b;
6077
- const arrCmp = (cmp = scalarCmp) => (a, b) => a === b || Boolean(a && b && a.length === b.length && a.every((_, i) => cmp(_, b[i])));
6078
- const objCmp = (cmp) => (a, b) => a === b ||
6079
- Boolean(a &&
6080
- b &&
6081
- Object.keys(a).length === Object.keys(b).length &&
6082
- Object.entries(a).every(([key, value]) => cmp(value, b[key])));
6083
- function combineBoolCmps(...comparators) {
6084
- return (a, b) => comparators.some((cmp) => cmp(a, b));
6085
- }
6411
+ const RollupItem = UniBlock(({ className = '', isExpanded, isFoldButtonOnTop = true, label = 'Развернуть', labelIcon, labelIconBgVersion, foldButtonVersion = 'default',
6412
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6413
+ version, role, ...rest }) => {
6414
+ const isMobile = useMobileMode();
6415
+ return (jsx(BlockWrapper, { className: style('w-full border-0 border-b border-solid border-main-divider last:border-b-0', className), defaultPadding: "p-0", tag: "div", version: "transparent", role: role, ...rest, children: jsx(Foldable, { isFoldButtonOnTop: isFoldButtonOnTop, unfoldedByDefault: isExpanded, renderFoldableSection: ({ isUnfolded }) => (jsx(FoldableSection, { className: style('gap-lg', getFoldableStyles(isMobile)), isUnfolded: isUnfolded, children: renderChildren({
6416
+ ...rest,
6417
+ extraProps: { className: 'w-full', padding: 'p-0' },
6418
+ }) })), renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton({
6419
+ foldButtonVersion,
6420
+ label,
6421
+ labelIcon,
6422
+ labelIconBgVersion,
6423
+ isUnfolded,
6424
+ onToggle,
6425
+ isMobile,
6426
+ }) }) }));
6427
+ }, {
6428
+ childrenTypes: { exclude: ['RollupItem'] },
6429
+ });
6430
+ const renderFoldButton = ({ foldButtonVersion, label: defaultLabel, labelIcon, labelIconBgVersion, isUnfolded, onToggle, isMobile = false, }) => {
6431
+ const label = defaultLabel || (isUnfolded ? 'Скрыть' : 'Развернуть');
6432
+ const icon = getIconName(isUnfolded, isMobile);
6433
+ return foldButtonVersion === 'accordion' ? (jsx(AccordionFoldButton, { label: label, labelIcon: labelIcon, labelIconBgVersion: labelIconBgVersion, icon: icon, onToggle: onToggle })) : (jsx(DefaultFoldButton, { label: label, icon: isUnfolded ? 'ArrowUpIcon' : 'ArrowDownIcon', onClick: onToggle }));
6434
+ };
6086
6435
 
6087
- const hotFilterRecordCmp = objCmp(combineBoolCmps(scalarCmp, arrCmp()));
6436
+ const Sitemap = JSX(({ navigationItems }) => (jsx("div", { className: "w-full", role: "menu", children: renderTopItems(navigationItems) })));
6437
+ const renderTopItems = (topItems) => topItems
6438
+ ?.filter((_) => _.icon?.icon)
6439
+ .map((item, i) => (jsx(RollupItem, { foldButtonVersion: "accordion", label: item?.text, labelIcon: item?.icon, role: "menuitem", children: item.items ? jsx(LinkList, { items: item.items }) : null }, String(i))));
6088
6440
 
6089
- const EMPTY_ARR = [];
6090
- const EMPTY_OBJ = {};
6091
- const useHotFilters = ({ hotFilters = EMPTY_ARR, filtrationState = EMPTY_OBJ, blocks = EMPTY_ARR, onFiltrationStateChange, }) => {
6092
- const activeItemIndex = useMemo(() => Math.max(0, hotFilters.findIndex((_) => hotFilterRecordCmp(_.filter, filtrationState))), [hotFilters, filtrationState]);
6093
- const items = useMemo(() => hotFilters.map((_) => ({
6094
- text: _.text,
6095
- count: getBadgeCount(blocks, _.filter),
6096
- version: getVersion(_ === hotFilters[activeItemIndex]),
6097
- })), [hotFilters, blocks, activeItemIndex]);
6098
- const handleChange = useCallback((_) => {
6099
- onFiltrationStateChange(hotFilters[items.indexOf(_)].filter);
6100
- }, [hotFilters, items]);
6101
- return {
6102
- activeItem: items[activeItemIndex],
6103
- items: items,
6104
- onChange: handleChange,
6105
- };
6441
+ const Contacts = JSX(({ className = '', items = [] }) => items?.length ? (jsx("div", { className: style('space-y-m', className), children: items.map(renderContactsGroup) })) : null);
6442
+ const renderContactsGroup = (item, i) => (jsxs("div", { className: "space-y-m", children: [jsx("div", { children: jsx(Text, { size: "text-l", font: "font-medium", children: item?.title }) }), jsx("div", { className: "space-y-m", children: item.items?.map(renderContact) })] }, String(i)));
6443
+ const renderContact = (item, i) => (jsxs("div", { className: "space-y-2xs", children: [jsx("div", { children: renderText$1(item.type, item.text) }), jsx(Paragraph, { size: "text-s", font: "font-light", color: "text-secondary-text", children: item.description })] }, String(i)));
6444
+ const renderText$1 = (type, text = '') => {
6445
+ switch (type) {
6446
+ case 'tel':
6447
+ return (jsx("a", { className: "text-primary-text hover:text-primary-main no-underline", href: `tel:${formatTel(text)}`, children: jsx(Text, { size: "text-h6", children: text }) }));
6448
+ case 'email':
6449
+ return (jsx("a", { className: "no-underline", href: `mailto:${text}`, children: jsx(Paragraph, { size: "text-xl", font: "font-light", color: "text-primary-text", children: text }) }));
6450
+ default:
6451
+ return jsx("span", { children: text });
6452
+ }
6106
6453
  };
6454
+ const formatTel = (s) => s.replaceAll(/\D/g, '');
6107
6455
 
6108
- const badgeBgStyleMap = {
6109
- primary: 'bg-white/30',
6110
- secondary: 'bg-main-divider',
6111
- };
6112
- const badgeTextColorStyleMap = {
6113
- primary: { desktop: 'text-white', mobile: 'text-primary-text' },
6114
- secondary: { desktop: 'text-secondary-text', mobile: 'text-secondary-text' },
6115
- };
6116
- const Badge$1 = JSX(({ count, version = 'secondary' }) => {
6117
- const isMobileMode = useMobileMode();
6118
- const badgeBgStyle = isMobileMode ? 'bg-main-divider' : badgeBgStyleMap[version];
6119
- const textStyle = badgeTextColorStyleMap[version][isMobileMode ? 'mobile' : 'desktop'];
6120
- return (jsx("div", { className: style('w-6 h-6 rounded-full flex items-center justify-center', badgeBgStyle), role: "status", "aria-label": `Количество ${count} доступных программ и сервисов`, children: jsx(Text, { size: "text-xs", color: textStyle, children: count }) }));
6456
+ const HorizontalNavigationLink = JSX(({ className = '', index, text, ...rest }) => {
6457
+ const link = useLink();
6458
+ const { href, target, onClick } = link(rest);
6459
+ return (jsx("a", { className: style('text-secondary-text', className), href: href, target: target, onClick: onClick, children: text || `Документ ${index}` }));
6121
6460
  });
6122
6461
 
6123
- const getButtonClassNames = (isActive) => ({
6124
- btn: `w-96 ${isActive ? 'p-m border-none bg-primary-main text-white' : 'p-s ease-in duration-300 bg-white'}`,
6125
- text: isActive ? 'mb-xs text-xl' : 'mb-2xs text-l text-primary-text',
6126
- desc: `font-light ${isActive ? 'text-l text-white' : 'text-m text-secondary-text'}`,
6127
- icon: isActive ? '' : 'text-primary-main',
6128
- iconVersion: (isActive ? 'white' : 'normal'),
6129
- oldText: 'text-m text-center',
6130
- oldDesc: 'text-m-light',
6462
+ const HorizontalNavigation = JSX(({ className = '', title, links }) => (jsx("div", { className: className, children: links?.length ? (jsxs("div", { className: "flex justify-between lg:items-center flex-col lg:flex-row gap-lg py-lg border-y border-y-main-divider", children: [jsx("div", { className: "lg:hidden", children: jsx(Text, { size: "text-l", font: "font-normal", children: title }) }), links.map((_, i) => (jsx(HorizontalNavigationLink, { index: i, className: "text-l font-light lg:max-w-[292px]", ..._ }, String(i))))] })) : null })));
6463
+
6464
+ const LEFT_COLUMN_STYLE = 'w-full lg:w-52';
6465
+
6466
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6467
+ const renderLogoSearchBar = (common, navigationItems) => null;
6468
+
6469
+ const TextInformationLink = JSX(({ className = '', index, ...rest }) => {
6470
+ const link = useLink();
6471
+ const { href, target, text, onClick } = link(rest);
6472
+ return (jsx("a", { className: style('text-xs font-light text-secondary-text visited:text-secondary-text hover:text-primary-main inline-block no-underline max-w-[292px]', className), href: href, target: target, onClick: onClick, children: text || `Документ ${index}` }));
6131
6473
  });
6132
- const renderTabItemInner = ({ text, description, icon, isActive, type, }) => {
6133
- const buttonClassNames = getButtonClassNames(isActive);
6134
- return (jsxs("div", { className: style('cursor-pointer text-left border-b-0 flex gap-2xs'), "aria-label": text, "aria-labelledby": `${text}-label`, children: [icon ? (jsx(Img, { className: style('h-6 w-6 min-w-6 min-h-6', buttonClassNames.icon), image: {
6135
- ...icon,
6136
- iconVersion: icon?.iconVersion ?? buttonClassNames.iconVersion,
6137
- }, width: "24", height: "24", alt: text })) : null, jsxs("div", { className: "border-0", children: [jsx("div", { className: type === 'animated' ? buttonClassNames.text : buttonClassNames.oldText, children: text }), jsx("div", { className: type === 'animated' ? buttonClassNames.desc : buttonClassNames.oldDesc, children: description })] })] }));
6138
- };
6139
6474
 
6140
- const tabPaddingStyleMap = {
6141
- default: 'px-xs',
6142
- underlined: 'px-m',
6143
- animated: 'px-m border border-gray cursor-pointer text-left border-b-0 mt-auto flex gap-2xs',
6144
- };
6145
- const tabTextStyle = 'text-secondary-text hover:text-primary-main';
6146
- const activeTabTextStyleMap = {
6147
- default: 'text-black sm:text-white',
6148
- underlined: 'text-primary-main border-b-2',
6149
- animated: 'text-white sm:text-white',
6150
- };
6151
- const tabBgStyleMap = {
6152
- default: 'bg-white',
6153
- underlined: 'bg-white',
6154
- animated: 'p-1 ease-in duration-300 bg-white text-primary-text h-[70px] w-96',
6155
- };
6156
- const activeTabBgStyleMap = {
6157
- default: 'bg-white sm:bg-primary-main',
6158
- underlined: 'bg-white',
6159
- animated: 'p-2 border-none bg-primary-main text-white h-20 w-96',
6160
- };
6161
- const TabItemInner = JSX(({ tag = 'div', item = {}, isActive = false, type = 'default', onClick }) => {
6162
- const Tag = tag;
6163
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
6164
- const { text, description, icon, count, tabName, ...link } = item;
6165
- return (jsx(Tag, { className: style('h-12', 'block flex-1', 'cursor-pointer', tabPaddingStyleMap[type], isActive ? activeTabBgStyleMap[type] : tabBgStyleMap[type]), role: "tablist", "aria-label": "\u0421\u043F\u0438\u0441\u043E\u043A \u0442\u0430\u0431\u043E\u0432", onClick: onClick, ...link, children: jsxs("div", { className: style('h-full', 'flex justify-center items-center', 'text-center whitespace-nowrap', isActive ? activeTabTextStyleMap[type] : tabTextStyle), role: "tab", "aria-label": `Таб ${text}`, children: [renderTabItemInner({
6166
- text,
6167
- description,
6168
- icon,
6169
- isActive,
6170
- type,
6171
- }), Number.isInteger(count) ? (jsx("div", { className: "ml-xs", role: "status", "aria-label": `Количество программ и сервисов ${count}`, children: jsx(Badge$1, { count: count, version: getVersion(isActive, type) }) })) : null] }) }));
6475
+ const TextInformation = JSX(({ className = '', links, license }) => (jsxs("div", { className: style('@container space-y-lg', className), children: [license ? (jsx("div", { children: jsx(Text, { size: "text-xs", font: "font-light", color: "text-secondary-text", children: `\u00a9\u00A02000-${new Date().getFullYear()}\u00A0${license}` }) })) : null, links?.length ? (jsx("div", { className: "flex flex-col @5xl:flex-row justify-start items-start gap-x-lg gap-y-xs", children: links.map((_, i) => (jsx(TextInformationLink, { index: i, ..._ }, String(i)))) })) : null] })));
6476
+
6477
+ const Footer = UniBlock(({ className, footer, ...rest }) => {
6478
+ const { navigationItems } = rest.options?.page?.navigation ?? {};
6479
+ rest.options?.page?.common ?? {};
6480
+ const { documents, relatedEnterprises, contacts, mediaLinks = [], horizontalNavigationTitle, feedbackButton, license, otherLinks = [], } = footer ?? {};
6481
+ const linkStyle = '!text-left text-s font-light';
6482
+ return (jsxs(BlockWrapper, { tag: "footer", className: style('grid gap-y-xl p-4xl pb-24 lg:p-xl', className), ...rest, children: [renderLogoSearchBar(), jsxs("div", { className: "flex flex-col lg:flex-row items-center @lg:items-stretch gap-lg lg:gap-6xl ", children: [jsx(Sitemap, { navigationItems: navigationItems }), jsx("div", { className: "border-t border-main-divider lg:hidden w-full" }), jsxs("div", { className: style(LEFT_COLUMN_STYLE, 'flex flex-col shrink-0 overflow-hidden space-y-xl'), children: [jsx(Contacts, { items: contacts }), feedbackButton ? (jsx(LinkButton, { className: "w-full", version: "primary", ...feedbackButton })) : null, mediaLinks.map((_, i) => (jsx(SocialMedia, { media: _?.links ?? [], showButtonText: false, stretched: true, children: _?.title }, String(i)))), otherLinks.map((_, i) => (jsx(LinkButton, { className: linkStyle, version: "link", ..._, children: _?.text }, String(i))))] })] }), jsx(HorizontalNavigation, { title: horizontalNavigationTitle, links: relatedEnterprises }), jsx(TextInformation, { links: documents, license: license })] }));
6172
6483
  });
6173
6484
 
6174
- const TabItem = JSX((props) => props?.item?.href ? jsx(LinkTabItem, { ...props }) : jsx(ButtonTabItem, { ...props }));
6175
- const LinkTabItem = JSX((props) => {
6176
- const link = useLink();
6177
- const handleClick = useCallback(() => {
6178
- props.onClick && props.onClick(props.item || {});
6179
- }, [props.onClick, props.item]);
6180
- const { onClick, ...item } = link({ ...props.item, onClick: handleClick });
6181
- return jsx(TabItemInner, { ...props, tag: "a", item: item, onClick: onClick });
6485
+ const GrantSupport = UniBlock(({ className, title, button, regionSource, data, ...rest }) => {
6486
+ const [region, setRegion] = useState({ key: '' });
6487
+ const regions = regionSource?.regions ?? [];
6488
+ const buttonStyle = getRegularButtonClasses({
6489
+ className: 'text-white',
6490
+ version: button?.version || 'primary',
6491
+ });
6492
+ const regionHref = regions?.find((_) => _.name === region.key)?.href;
6493
+ const buttonText = button?.text ? button.text : 'Перейти';
6494
+ return (jsx(BlockWrapper, { className: className, defaultPadding: "p-6xl", ...rest, children: jsxs("div", { className: "container max-w-[978px] space-y-m", children: [title ? jsx(Heading, { headingType: "h3", title: title, className: "@xl:text-center" }) : null, regions ? (jsx(SelectControl, { label: "\u0412\u0430\u0448 \u0440\u0435\u0433\u0438\u043E\u043D", placeholder: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0440\u0435\u0433\u0438\u043E\u043D", isSearch: true, options: regions.map(({ name = '' }) => ({ key: name, text: name })), value: region, onChange: setRegion })) : null, regionHref ? (jsx("div", { className: "text-center", children: jsx(LinkButton, { href: regionHref, target: "_blank", className: style('p-m w-full @xl:w-auto', buttonStyle), data: getAspectsWithInclude(data, region?.key), children: buttonText }) })) : null] }) }));
6182
6495
  });
6183
- // TODO: Update handlerDecorator (support buttons?)
6184
- const ButtonTabItem = JSX(({ item = {}, onClick, ...rest }) => {
6185
- const handleClick = useCallback(() => {
6186
- onClick && onClick(item);
6187
- }, [onClick, item]);
6188
- return jsx(TabItemInner, { item: item, onClick: handleClick, ...rest });
6496
+
6497
+ const BUTTON_STYLE = {
6498
+ default: 'bg-main-divider text-primary-main rounded hover:text-primary-main',
6499
+ transparent: 'backdrop-opacity-30 bg-white/30 hover:text-primary-hover text-white',
6500
+ };
6501
+ const InternetBankButton = JSX(({ version, text, mobileText, ...rest }) => {
6502
+ const isMobileMode = useMobileMode();
6503
+ const buttonText = isMobileMode ? mobileText : text;
6504
+ return buttonText ? (jsx(LinkButton, { className: style('py-s px-lg font-light whitespace-nowrap', BUTTON_STYLE[version === 'transparent' ? 'transparent' : 'default']), ...rest, children: buttonText })) : null;
6189
6505
  });
6190
6506
 
6191
- const renderTab = (activeTab, onClick, type) => (tab, i) => (jsx(TabItem, { isActive: tab === activeTab, onClick: onClick, type: type, item: tab }, String(i)));
6192
-
6193
- const TabsControl = JSX(({ className, tabsType = 'default', items = [], activeItem, onChange }) => (jsx("div", { className: style('flex gap-x-2xs overflow-x-auto no-scrollbar', className), role: "tabpanel", "aria-label": "\u041F\u0430\u043D\u0435\u043B\u044C \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0442\u0430\u0431\u0430\u043C\u0438", children: items.map(renderTab(activeItem, onChange, tabsType)) })));
6507
+ const HeaderTop = JSX(({ bgColor, logo, alwaysShowLogo, internetBankButton, version, backwardButton }) => {
6508
+ const router = useRouter();
6509
+ const isRootLocation = router.pathname === '/';
6510
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6511
+ const { dataFooter, dataHeader, ...logoProps } = logo ?? {};
6512
+ const onClick = useCallback(() => {
6513
+ router.back();
6514
+ }, [router]);
6515
+ return (jsxs("div", { className: "flex items-center justify-between w-full", children: [alwaysShowLogo || isRootLocation ? (jsx("div", { children: jsx(Logo, { className: "my-2xs", bgColor: bgColor, logo: logoProps, data: dataHeader, showTitle: false }) })) : (renderBackButton(onClick, backwardButton)), jsx(InternetBankButton, { version: version, ...internetBankButton })] }));
6516
+ });
6517
+ const renderBackButton = (onClick, text) => text ? (jsxs("button", { className: "flex items-center text-l my-2xs", onClick: onClick, type: "button", "aria-label": "\u041A\u043D\u043E\u043F\u043A\u0430 \u043D\u0430\u0437\u0430\u0434", children: [jsx(Icon, { name: "ChevronLeftIcon", iconVersion: "black", width: "24", height: "24" }), text] })) : null;
6194
6518
 
6195
- const initialFiltrationState = {
6196
- categories: [],
6197
- extraOptions: [],
6198
- propertyType: [],
6199
- stage: [],
6519
+ const BG_COLOR_TO_BLOCK_VERSION = {
6520
+ 'bg-white': 'primary',
6521
+ transparent: 'transparent',
6200
6522
  };
6201
- const MortgageFiltration = UniBlock(({ className, hotFilters, filtrationSchema = {}, resetButton, ...rest }) => {
6202
- const [filtrationState, { blocksToRender }, { field, reset, update: replaceFiltrationState }] = useFiltrationForm(initialFiltrationState, {
6203
- block: rest.block,
6204
- page: rest.options?.page,
6205
- });
6206
- const handleFiltrationStateChange = useCallback((_ = initialFiltrationState) => replaceFiltrationState(_), []);
6207
- const tabsControlProps = useHotFilters({
6208
- hotFilters,
6209
- filtrationState,
6210
- blocks: rest.block?.blocks,
6211
- onFiltrationStateChange: handleFiltrationStateChange,
6212
- });
6213
- return (jsxs(BlockWrapper, { className: style('space-y-2xs', className), defaultPadding: "p-0", version: "transparent", ...rest, children: [jsx(TabsControl, { ...tabsControlProps }), jsx(FiltrationForm, { filtrationSchema: filtrationSchema, resetButton: resetButton, field: field, reset: reset }), jsx(FilteredBlocks, { blocksToRender: blocksToRender, ...rest })] }));
6214
- }, {
6215
- childrenTypes: ['ProductBlock'],
6216
- childSchema: (content) => content?.filtrationSchema || {},
6523
+ const Header = UniBlock(({ bgColor = 'bg-white', alwaysShowLogo = false, version = BG_COLOR_TO_BLOCK_VERSION[bgColor], portal, logo: customLogo = {}, ...rest }) => {
6524
+ const { backwardButton, logo = {} } = rest.options?.page?.common ?? {};
6525
+ const { internetBankButton } = portal || {};
6526
+ const logoProps = customLogo.image?.icon || customLogo.image?.src ? customLogo : logo;
6527
+ return (jsx(BlockWrapper, { tag: "header", defaultPadding: "", version: version, ...rest, children: jsx("div", { className: "container px-lg py-2xs box-border", children: jsx(HeaderTop, { bgColor: bgColor, logo: logoProps, alwaysShowLogo: alwaysShowLogo, internetBankButton: internetBankButton, version: version, backwardButton: backwardButton, ...rest }) }) }));
6217
6528
  });
6218
6529
 
6219
- const isSSR = () => Boolean(typeof globalThis.process === 'object' && globalThis.process && globalThis.process.version);
6530
+ const getInnerPadding = (isPadding = false) => isPadding ? {} : { padding: 'p-0' };
6220
6531
 
6221
- const isClient = !isSSR();
6222
- const ClientOnly = JSX(({ children }) => (isClient ? children : null));
6532
+ const gapStyles = {
6533
+ XXL: 'gap-6xl',
6534
+ XL: 'gap-5xl',
6535
+ L: 'gap-3xl',
6536
+ M: 'gap-m',
6537
+ S: 'gap-xs',
6538
+ XS: 'gap-2xs',
6539
+ '': '',
6540
+ };
6223
6541
 
6224
- const MapMarkerClusterIcon = '/icons/MapMarkerClusterIcon.svg';
6225
- const MapMarkerClusterYellowIcon = '/icons/MapMarkerClusterYellowIcon.svg';
6226
- function renderClusterer({ yandexMaps, map, points, isLoad, }) {
6227
- if (isLoad || !points) {
6228
- return;
6229
- }
6230
- map.geoObjects.removeAll();
6231
- if (!points.length) {
6232
- return;
6233
- }
6234
- const clusterIconContentLayout = yandexMaps.templateLayoutFactory.createClass('<div style="margin-top: -3px;">{{properties.geoObjects.length}}</div>');
6235
- const officeClusterer = defineClusterer('offices', yandexMaps, clusterIconContentLayout);
6236
- if (points.length && points.every((_) => 'type' in _)) {
6237
- const remoteWorkplaceClusterer = defineClusterer('workplaces', yandexMaps, clusterIconContentLayout);
6238
- const remoteWorkplaceGeoObjects = defineGeoObjects(points.filter((_) => _.type === 'workplaces'), 'workplaces', yandexMaps);
6239
- const officesGeoObjects = defineGeoObjects(points.filter((_) => _.type === 'offices'), 'offices', yandexMaps);
6240
- officeClusterer.add(officesGeoObjects);
6241
- remoteWorkplaceClusterer.add(remoteWorkplaceGeoObjects);
6242
- map.geoObjects.add(remoteWorkplaceClusterer);
6243
- map.geoObjects.add(officeClusterer);
6244
- }
6245
- else {
6246
- const geoObjects = defineGeoObjects(points, 'offices', yandexMaps);
6247
- officeClusterer.add(geoObjects);
6248
- map.geoObjects.add(officeClusterer);
6249
- }
6250
- map.setBounds(yandexMaps.util.bounds.fromPoints(points.map((_) => _.coords))).then(() => {
6251
- if (map.getZoom() > 10) {
6252
- map.setZoom(10);
6253
- }
6254
- });
6255
- }
6256
- const defineClusterer = (type, yandexMaps, clusterIconContentLayout) => {
6257
- return new yandexMaps.Clusterer({
6258
- clusterIcons: [
6259
- {
6260
- href: type === 'offices' ? MapMarkerClusterIcon : MapMarkerClusterYellowIcon,
6261
- size: [78, 84],
6262
- offset: [-35, -50],
6542
+ const VerticalLayout = UniBlock(({ className = '', padding = 'p-0', gap = '', isInnerPadding = true, version = 'transparent', isTheme = false, isCardBorder = false, image, ...rest }) => {
6543
+ const router = useRouter();
6544
+ return (jsx(BlockWrapper, { className: style('relative flex flex-col', gapStyles[gap], image?.src ? 'bg-right-bottom bg-no-repeat' : '', className), ...(image?.src
6545
+ ? { style: { backgroundImage: `url(${adjustSrc(router)(image?.src)})` } }
6546
+ : {}), padding: padding, version: version, isTheme: isTheme, ...rest, children: renderChildren({
6547
+ ...rest,
6548
+ extraProps: {
6549
+ className: style('w-full', getBorderStyle(isCardBorder)),
6550
+ ...getInnerPadding(isInnerPadding),
6263
6551
  },
6264
- ],
6265
- clusterIconContentLayout,
6266
- clusterHideIconOnBalloonOpen: false,
6267
- geoObjectHideIconOnBalloonOpen: false,
6268
- });
6269
- };
6270
- const defineGeoObjects = (pointArr, type, yandexMaps) => {
6271
- return pointArr.map(({ coords, content }) => new yandexMaps.Placemark(coords, {
6272
- balloonContentHeader: content?.header,
6273
- balloonContentBody: content?.body,
6274
- balloonContentFooter: content?.footer,
6275
- hintContent: content?.hint,
6276
- }, {
6277
- iconLayout: 'default#image',
6278
- iconImageHref: type === 'offices' ? MapMarkerClusterIcon : MapMarkerClusterYellowIcon,
6279
- iconImageSize: [78, 84],
6280
- iconImageOffset: [-35, -50],
6281
- }));
6282
- };
6552
+ }) }));
6553
+ }, { childrenTypes: [] });
6283
6554
 
6284
- const defaultStyle = {
6285
- focus: 'focus:border-primary-text focus:border',
6286
- hover: 'hover:bg-primary-hover',
6287
- active: 'active:bg-primary-active',
6288
- font: 'text-center font-sans',
6289
- };
6555
+ const HorizontalLayout = UniBlock((props) => jsx(VerticalLayout, { ...props }), { childrenTypes: [] });
6290
6556
 
6291
- const styles$1 = {
6292
- ...defaultStyle,
6293
- border: 'border border-transparent rounded-md',
6294
- position: 'absolute flex items-center justify-center',
6295
- };
6296
- const renderUserGeolocation = (map, yandexMaps, className) => {
6297
- const setUserGeoLocation = () => {
6298
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
6299
- // @ts-ignore
6300
- yandexMaps.geolocation
6301
- .get({
6302
- provider: 'yandex',
6303
- autoReverseGeocode: true,
6304
- mapStateAutoApply: true,
6305
- })
6306
- .then(function (result) {
6307
- map.current.geoObjects.add(result.geoObjects);
6308
- });
6309
- };
6310
- return (jsx("div", { className: `select-none cursor-pointer py-m w-12 bg-white ${Object.values(styles$1).join(' ')} ${className}`, onClick: setUserGeoLocation, children: jsx(Icon, { name: "UserGeoLocationIcon", width: "20", height: "16" }) }));
6311
- };
6557
+ const ImgBlock = JSX((props) => {
6558
+ const { className, align, image, ...rest } = props;
6559
+ const alignStyle = align ? style('flex', AlignJustifyStyle[align]) : '';
6560
+ return (jsx(BlockWrapper, { className: style(alignStyle, className), defaultPadding: "p-0", ...rest, children: jsx(Img, { image: image }) }));
6561
+ });
6312
6562
 
6313
- const getNS = (_) => globalThis[_];
6314
- const initializeExternalNS = (namespaceName, url) => {
6315
- const script = document.getElementById(url);
6316
- if (script) {
6317
- const ns = getNS(namespaceName);
6318
- if (ns) {
6319
- return Promise.resolve(ns);
6320
- }
6321
- else {
6322
- return new Promise((resolve) => {
6323
- script.addEventListener('load', () => {
6324
- resolve(getNS(namespaceName));
6325
- });
6326
- });
6327
- }
6328
- }
6329
- else {
6330
- return new Promise((resolve, reject) => {
6331
- const newScript = document.createElement('script');
6332
- newScript.src = url;
6333
- newScript.async = true;
6334
- newScript.id = url;
6335
- newScript.addEventListener('load', () => {
6336
- resolve(getNS(namespaceName));
6337
- });
6338
- newScript.addEventListener('error', (error) => {
6339
- reject(error);
6340
- });
6341
- document.head.appendChild(newScript);
6342
- });
6563
+ const KILO = 1024;
6564
+ const KILO_SIZES = ['байт', 'Кб', 'Мб', 'Гб', 'Тб', 'Пб'];
6565
+ const formatBytes = (bytes, decimals = 2) => {
6566
+ if (bytes === 0) {
6567
+ return '';
6343
6568
  }
6569
+ const i = Math.floor(Math.log(bytes) / Math.log(KILO));
6570
+ return `${parseFloat((bytes / Math.pow(KILO, i)).toFixed(decimals))} ${KILO_SIZES[i]}`;
6344
6571
  };
6345
- function useExternalNS(namespaceName, url, unmountNS = true) {
6346
- const [externalNS, setExternalNS] = useState(undefined);
6347
- useEffect(() => {
6348
- let isMounted = true;
6349
- initializeExternalNS(namespaceName, url)
6350
- .then((ns) => {
6351
- if (isMounted) {
6352
- setExternalNS(ns);
6353
- }
6354
- })
6355
- .catch((error) => {
6356
- console.error(`Failed to initialize external namespace: ${error}`);
6357
- });
6358
- return () => {
6359
- isMounted = false;
6360
- if (unmountNS) {
6361
- const script = document.getElementById(url);
6362
- if (script) {
6363
- document.head.removeChild(script);
6364
- }
6365
- setExternalNS(undefined);
6366
- }
6367
- };
6368
- }, [namespaceName, url, unmountNS]);
6369
- return externalNS;
6370
- }
6371
6572
 
6372
- const YMAPS_NAMESPACE = 'ymaps';
6373
- const useYandexMaps = () => {
6374
- const url = `https://api-maps.yandex.ru/2.1/?apikey=${projectSettings.YANDEX_MAP_API_KEY || ''}&lang=ru_RU`;
6375
- return useExternalNS(YMAPS_NAMESPACE, url, false);
6376
- };
6573
+ const LinkDocItem = JSX(({ icon, text, href, target, fileFormat, data, fileSize }) => {
6574
+ const prefix = fileSize && fileFormat ? ',' : '';
6575
+ const size = fileSize ?? '';
6576
+ const format = fileFormat ? String(fileFormat) : '';
6577
+ return (jsxs("a", { className: "flex box-border gap-s group/item h-fit w-fit text-primary-text no-underline hover:text-primary-main", href: href, target: target, ...getAspectsAttributes(data), children: [icon, text ? (jsxs(Text, { size: "text-l", font: "font-light", children: [text, " ", addSpace(size, format), jsx(Text, { color: "text-secondary-text", children: href && `${size + prefix + format}` })] })) : null] }));
6578
+ });
6579
+ const addSpace = (size, format) => (size || format ? jsx("span", { children: ",\u00A0" }) : '');
6377
6580
 
6378
- const styles = {
6379
- ...defaultStyle,
6380
- border: 'border-b border-b-2 border-gray last:border-0',
6381
- position: 'relative flex items-center justify-center',
6581
+ const linkIconStyle = 'min-w-11 min-h-11 h-fit p-2.5 bg-main-divider rounded-md';
6582
+
6583
+ const renderDefaultItem = (router, icon) => (docBlockDef, i) => {
6584
+ const href = adjustHref(router)(docBlockDef?.docType === 'Attachment' ? docBlockDef?.attachment?.src : docBlockDef?.href);
6585
+ const fileSize = docBlockDef?.docType === 'Attachment'
6586
+ ? formatBytes(docBlockDef?.attachment?.fileSize || 0)
6587
+ : docBlockDef?.fileSize;
6588
+ const fileFormat = docBlockDef?.docType === 'Attachment' ? getExtFromHref(href) : docBlockDef?.fileFormat;
6589
+ return (jsxs("div", { role: "listitem", children: [jsx(LinkDocItem, { text: docBlockDef?.text, target: docBlockDef?.target, href: href, fileFormat: fileFormat, fileSize: fileSize, icon: renderImg(icon), data: docBlockDef?.data }), jsx(RichText, { __html: docBlockDef?.__html })] }, String(i)));
6590
+ };
6591
+ const renderImg = (icon) => icon ? jsx(Img, { className: linkIconStyle, image: icon, width: "24", height: "24" }) : null;
6592
+ const getExtFromHref = (href) => {
6593
+ if (!href) {
6594
+ return '';
6595
+ }
6596
+ const index = href.lastIndexOf('.');
6597
+ const regexp = new RegExp(/\/(.*)/);
6598
+ const docFormat = index !== -1 ? href.substring(index + 1) : '';
6599
+ return docFormat.includes('/') ? docFormat.replace(regexp, '') : docFormat;
6382
6600
  };
6383
- // TODO: Добавить метод определения центральной точки
6384
- const ZoomButton = JSX(({ yandexMaps, direction = 'in' }) => {
6385
- const iconName = direction === 'in' ? 'PlusIcon' : 'MinusIcon';
6386
- const changeZoom = () => {
6387
- const currentZoom = yandexMaps.current.getZoom();
6388
- const newZoom = direction === 'in' ? currentZoom + 1 : currentZoom - 1;
6389
- yandexMaps.current.setZoom(newZoom, { checkZoomRange: true });
6390
- };
6391
- return (jsx("div", { onClick: changeZoom, className: `${Object.values(styles).join(' ')} bg-white select-none cursor-pointer w-12 h-12`, children: jsx(Icon, { name: iconName, width: "20", height: "16" }) }));
6601
+
6602
+ const ReportDialog = JSX(({ href, __html, target }) => {
6603
+ const { close } = useDialogManager();
6604
+ const router = useRouter();
6605
+ const adjustedHref = adjustHref(router)(href);
6606
+ const handleClose = useCallback(() => {
6607
+ close();
6608
+ }, []);
6609
+ return (jsxs(Dialog, { className: "my-6xl min-h-fit w-fit mx-auto", children: [__html ? jsx(RichText, { __html: __html }) : null, jsxs("div", { className: "flex flex-row mx-auto w-fit gap-lg py-lg", children: [jsx(LinkButton, { text: "\u042F \u0441\u043E\u0433\u043B\u0430\u0441\u0435\u043D", version: "primary", target: target, href: adjustedHref, onClick: handleClose }), jsx(Button, { type: "button", version: "secondary", onClick: handleClose, children: "\u042F \u043D\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u0435\u043D" })] }), jsx("div", { children: "\u041D\u0430\u0436\u0438\u043C\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0443 \u00AB\u042F \u0421\u041E\u0413\u041B\u0410\u0421\u0415\u041D\u00BB \u043D\u0438\u0436\u0435 \u0412\u044B \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u0443\u0441\u043B\u043E\u0432\u0438\u044F. \u0420\u0430\u0441\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u0435 \u0438\u043B\u0438 \u0440\u0430\u0441\u043A\u0440\u044B\u0442\u0438\u0435 \u043B\u044E\u0431\u043E\u0439 \u0447\u0430\u0441\u0442\u0438 \u0434\u0430\u043D\u043D\u043E\u0433\u043E \u0417\u0430\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F \u0438\u043B\u0438 \u043B\u044E\u0431\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438, \u0438\u043B\u0438 \u0440\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0430\u0446\u0438\u0438 \u0432 \u043D\u0435\u043C \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u043E.\u00BB" })] }));
6392
6610
  });
6393
6611
 
6394
- const DEFAULT_CENTER_COORDS = [55.753995, 37.614069];
6395
- // TODO: Поле для поиска: невыяснено среди каких данных делать поиск (искать в имени офиса, в адресе, метро и т.д.).
6396
- // Сейчас реализован поиск среди тестовых данных
6397
- // TODO: Также выяснить что делать когда ничего не найдено
6398
- // TODO: На макетах также когда есть поле поиска нет кнопки открыть на карте.
6399
- const YandexMap = JSX(({ points, className = '', zoom = 5, isLoad }) => {
6400
- const map = useRef(null);
6401
- const yandexMaps = useYandexMaps();
6402
- useEffect(() => {
6403
- if (map.current) {
6404
- renderClusterer({ yandexMaps, map: map.current, points, isLoad });
6405
- }
6406
- else {
6407
- yandexMaps?.ready(() => {
6408
- // Ready function may be called few times, but must be called once
6409
- if (map.current) {
6410
- renderClusterer({ yandexMaps, map: map.current, points, isLoad });
6411
- return;
6412
- }
6413
- map.current = new yandexMaps.Map('map', {
6414
- center: getCenterPoint(points),
6415
- zoom,
6416
- controls: [],
6417
- suppressMapOpenBlock: true,
6418
- });
6419
- renderClusterer({ yandexMaps, map: map.current, points, isLoad });
6420
- });
6421
- }
6422
- }, [yandexMaps, points, zoom, isLoad]);
6423
- if (!yandexMaps) {
6612
+ const useReportDialog = (props) => {
6613
+ const { open, close } = useDialogManager();
6614
+ return {
6615
+ open: (options = {}) => open(jsx(ReportDialog, { ...props }), options),
6616
+ close,
6617
+ };
6618
+ };
6619
+
6620
+ const ReportDialogButton = JSX(({ text, href, target, __html, icon }) => {
6621
+ if (!text && !__html) {
6424
6622
  return null;
6425
6623
  }
6426
- const zIndex = 'z-10';
6427
- return (jsxs("div", { id: "map", className: style('relative', 'w-full', className), children: [isLoad ? jsx(Loader, {}) : null, jsxs("div", { className: style('absolute right-2 top-52 z-10 w-12 overflow-hidden border border-transparent rounded-md', zIndex), children: [jsx(ZoomButton, { yandexMaps: map }), jsx(ZoomButton, { yandexMaps: map, direction: "out" })] }), renderUserGeolocation(map, yandexMaps, style('right-2 top-80', zIndex))] }));
6624
+ const reportDialog = useReportDialog({ __html, href, target });
6625
+ const openReportDialog = useCallback(() => reportDialog.open(), [reportDialog]);
6626
+ return (jsxs("button", { className: "flex gap-s text-primary-text no-underline hover:text-primary-main", onClick: openReportDialog, children: [renderImg(icon), jsx(Text, { font: "font-light", children: text })] }));
6428
6627
  });
6429
- const getCenterPoint = (points) => {
6430
- const centerCoords = [
6431
- getArraySumAndAverage(mapByIndex(points, 0)),
6432
- getArraySumAndAverage(mapByIndex(points, 1)),
6433
- ];
6434
- return centerCoords.every((_) => _) ? centerCoords : DEFAULT_CENTER_COORDS;
6435
- };
6436
- const mapByIndex = (points, index) => points.map((_) => _.coords?.[index]);
6437
- const getArraySumAndAverage = (arr) => arr.length && arr.reduce((a, b) => a + b) / arr.length;
6438
6628
 
6439
- const INITIAL_FILTRATION_STATE$1 = {
6440
- workingSaturday: false,
6441
- premiumService: false,
6442
- privateBanking: false,
6443
- remoteWorkplace: false,
6444
- serviceDisabledPeople: false,
6445
- sellingCoins: false,
6446
- buyingCoins: false,
6447
- bullionOperations: false,
6448
- preciousMetalsOperations: false,
6449
- transferringDataToBiometricSystem: false,
6629
+ const linkColumnsModeStyleMap = {
6630
+ double: 'sm:flex-wrap sm:flex-row',
6631
+ single: 'sm:flex-col',
6450
6632
  };
6451
- const FILTRATION_LABELS = {
6452
- safeBoxCaseVolumes: 'Аренда индивидуальных сейфовых ячеек',
6453
- workingSaturday: 'Открыты по субботам',
6454
- terminalTypeAtms: 'Банкоматы',
6455
- terminalTypeTerm: 'Терминалы',
6456
- workAllTime: 'Круглосуточно',
6457
- billAcceptorEnable: 'Прием наличных',
6458
- premiumService: 'Премиальное обслуживание',
6459
- privateBanking: 'Услуга Private banking',
6460
- sellingCoins: 'Продажа монет из драгоценных металлов',
6461
- buyingCoins: 'Покупка монет из драгоценных металлов',
6462
- bullionOperations: 'Операции со слитками',
6463
- preciousMetalsOperations: 'Операции с драгоценными металлами',
6464
- transferringDataToBiometricSystem: 'Передача фото и голоса в Единую биометрическую систему',
6465
- locationDisabledPeople: 'Для маломобильных',
6466
- designDisabledPeople: 'Для слабовидящих',
6467
- remoteWorkplace: 'Удаленное рабочее место',
6468
- serviceDisabledPeople: 'Для маломобильных граждан',
6633
+ const LinkDocs = UniBlock(({ className = '', title, description, align = 'text-center', documents, icon = { icon: 'DocIcon' }, columnsMode = 'double', ...rest }) => {
6634
+ const router = useRouter();
6635
+ return (jsxs(BlockWrapper, { className: style('space-y-lg', className), defaultPadding: "p-6xl", ...rest, children: [jsx(Headline, { title: title, description: description, align: align, headlineVersion: "M", as: "h2", isEmbedded: true }), documents?.length ? (jsx("div", { className: style('grid gap-xl', columnsMode === 'double' ? '@md:grid-cols-2' : 'grid-cols-1', linkColumnsModeStyleMap[columnsMode]), role: "list", children: documents.map(renderLinkDocItem(router, icon)) })) : null] }));
6636
+ });
6637
+ const renderLinkDocItem = (router, icon) => (docBlockDef, i) => {
6638
+ const docType = docBlockDef?.docType;
6639
+ if (docType === '') {
6640
+ return null;
6641
+ }
6642
+ if ('reportSource' in docBlockDef && docBlockDef?.reportSource?.__html) {
6643
+ return renderModalItem(icon)(docBlockDef, i);
6644
+ }
6645
+ return renderDefaultItem(router, icon)(docBlockDef, i);
6469
6646
  };
6470
- const FILTRATION_PREDICATES$1 = {
6471
- workingSaturday: (item) => Boolean('workSchedule' in item && item.workSchedule?.workingSaturday),
6472
- premiumService: (item) => Boolean('premiumService' in item && item.premiumService),
6473
- privateBanking: (item) => Boolean('privateBanking' in item && item.privateBanking),
6474
- remoteWorkplace: (item) => Boolean('workScheduleDescription' in item),
6475
- serviceDisabledPeople: (item) => Boolean('serviceDisabledPeople' in item && item.serviceDisabledPeople),
6476
- sellingCoins: (item) => Boolean('sellingCoins' in item && item.sellingCoins),
6477
- buyingCoins: (item) => Boolean('buyingCoins' in item && item.buyingCoins),
6478
- bullionOperations: (item) => Boolean('bullionOperations' in item && item.bullionOperations),
6479
- preciousMetalsOperations: (item) => Boolean('preciousMetalsOperations' in item && item.preciousMetalsOperations),
6480
- transferringDataToBiometricSystem: (item) => Boolean('transferringDataToBiometricSystem' in item && item.transferringDataToBiometricSystem),
6647
+ const renderModalItem = (icon) => (props, i) => {
6648
+ const commonProps = {
6649
+ text: props.text,
6650
+ target: props.target,
6651
+ __html: props.reportSource?.__html,
6652
+ };
6653
+ return props.reportSource?.__html && props.text ? (jsxs("div", { role: "listitem", children: [jsx(ReportDialogButton, { ...commonProps, icon: icon, href: isLinkDoc(props) ? props?.href : props?.attachment?.src }), jsx(RichText, { __html: props?.__html })] }, String(i))) : null;
6481
6654
  };
6655
+ const isLinkDoc = (data) => 'href' in data;
6482
6656
 
6483
- const renderButtonsGroup = (data, activeButton, onButtonClick) => {
6484
- const allButtonVersion = getVersion(activeButton === 'all');
6485
- const businessButtonVersion = getVersion(activeButton === 'business');
6486
- const handleClick = (e, key, branches) => {
6487
- const filteredBranches = e.currentTarget === e.target && key === 'business' ? filterBranches(branches) : branches;
6488
- onButtonClick(key);
6489
- return filteredBranches;
6657
+ const MobileAppTile = UniBlock(({ className, padding, align = 'text-left', buttons = [], description, image, __html, headingType, qr, additionalDescription = '', title = 'Мобильное приложение', version = 'primary', ...rest }) => {
6658
+ const containerStyle = version === 'secondary' ? 'p-m min-w-32' : 'min-w-24';
6659
+ const img = image?.src ? jsx(Img, { className: "hidden lg:block", image: image }) : null;
6660
+ return (jsx(BlockWrapper, { className: style('min-h-80', className), padding: "p-0", version: version, ...rest, children: jsxs(BaseTile, { className: "h-full", padding: padding, defaultPadding: "p-6xl", title: jsx(Heading, { headingType: headingType, title: title, className: style('whitespace-pre-wrap', align) }), rightImage: img, buttons: renderButtonsSection(buttons, { className: 'flex-wrap' }), children: [description ? (jsx(Text, { size: "text-xl", "font-weight": "font-light", children: description })) : null, jsxs("div", { className: style('gap-m', 'flex flex-1 flex-col', 'flex-col items-start @xl:flex-row @xl:items-center'), children: [__html ? jsx(RichText, { __html: __html, itemSize: "list-m" }) : null, jsx(Text, { size: "text-m", "font-weight": "font-light", color: "text-secondary-text", children: additionalDescription }), qr?.src ? (jsx("div", { className: style('flex justify-center bg-white rounded-md @xl:-order-1', containerStyle), children: jsx(Img, { className: "w-fit", image: qr }) })) : null, image?.src ? jsx(Img, { className: "lg:hidden", image: image }) : null] })] }) }));
6661
+ });
6662
+
6663
+ const getBadgeCount = (blocks = [], filter = {}) => blocks.filter(({ content = {} }) => targetMatchPattern(filter, content)).length;
6664
+
6665
+ const scalarCmp = (a, b) => a === b;
6666
+ const arrCmp = (cmp = scalarCmp) => (a, b) => a === b || Boolean(a && b && a.length === b.length && a.every((_, i) => cmp(_, b[i])));
6667
+ const objCmp = (cmp) => (a, b) => a === b ||
6668
+ Boolean(a &&
6669
+ b &&
6670
+ Object.keys(a).length === Object.keys(b).length &&
6671
+ Object.entries(a).every(([key, value]) => cmp(value, b[key])));
6672
+ function combineBoolCmps(...comparators) {
6673
+ return (a, b) => comparators.some((cmp) => cmp(a, b));
6674
+ }
6675
+
6676
+ const hotFilterRecordCmp = objCmp(combineBoolCmps(scalarCmp, arrCmp()));
6677
+
6678
+ const EMPTY_ARR = [];
6679
+ const EMPTY_OBJ = {};
6680
+ const useHotFilters = ({ hotFilters = EMPTY_ARR, filtrationState = EMPTY_OBJ, blocks = EMPTY_ARR, onFiltrationStateChange, }) => {
6681
+ const activeItemIndex = useMemo(() => Math.max(0, hotFilters.findIndex((_) => hotFilterRecordCmp(_.filter, filtrationState))), [hotFilters, filtrationState]);
6682
+ const items = useMemo(() => hotFilters.map((_) => ({
6683
+ text: _.text,
6684
+ count: getBadgeCount(blocks, _.filter),
6685
+ version: getVersion(_ === hotFilters[activeItemIndex]),
6686
+ })), [hotFilters, blocks, activeItemIndex]);
6687
+ const handleChange = useCallback((_) => {
6688
+ onFiltrationStateChange(hotFilters[items.indexOf(_)].filter);
6689
+ }, [hotFilters, items]);
6690
+ return {
6691
+ activeItem: items[activeItemIndex],
6692
+ items: items,
6693
+ onChange: handleChange,
6490
6694
  };
6491
- const filterBranches = (branches) => branches.filter((branch) => branch.workSchedule &&
6492
- branch.workSchedule.businessScheduleVisibleTag &&
6493
- !branch.workSchedule.businessScheduleDescription);
6494
- return (jsxs("div", { className: "flex gap-lg flex-col sm:flex-row pb-lg", children: [jsx(Button, { "data-id": "all", onClick: (e) => handleClick(e, 'all', data), version: allButtonVersion, children: "\u0414\u043B\u044F \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446" }), jsx(Button, { "data-id": "business", onClick: (e) => handleClick(e, 'business', data), version: businessButtonVersion, children: "\u0414\u043B\u044F \u044E\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446" })] }));
6495
6695
  };
6496
6696
 
6497
- const renderDescriptionBlock$1 = ({ __html, list, richVersion }) => __html || list?.length ? (jsxs("div", { className: "mb-2xl border-b sm:border border-main-divider sm:rounded-md", children: [__html ? (jsx("div", { className: "mb-2xl", children: jsx(RichText, { __html: __html, richVersion: richVersion }) })) : null, list?.length ? (jsx("div", { className: "flex flex-col sm:flex-row gap-2xl sm:flex-wrap pb-2xl sm:pb-xl", children: list.map((item, i) => (jsxs("div", { className: "flex gap-xs items-center", children: [item?.image ? jsx(Img, { image: item.image }) : null, item?.text ? (jsx(Text, { size: "text-m", font: "font-light", children: item.text })) : null] }, String(i)))) })) : null] })) : null;
6498
-
6499
- const COMMON_FILTERS_STYLES = 'flex flex-col sm:flex-row sm:flex-wrap gap-3xl pb-2xl';
6500
- const renderFiltrationForm = ({ filters, field: { field, reset }, onlyOffice, labels, }) => {
6501
- const visibleFiltersNum = onlyOffice ? 5 : 6;
6502
- const filtersCheckbox = (filters || []).map((key) => (jsx(Checkbox, { text: labels[key], ...field(key) }, key)));
6503
- const [visibleFilters, hiddenFilters] = visibleFiltersNum > 0
6504
- ? [filtersCheckbox.slice(0, visibleFiltersNum), filtersCheckbox.slice(visibleFiltersNum)]
6505
- : [filtersCheckbox, []];
6506
- return (jsx("div", { children: filters?.length ? (jsx("div", { children: jsx(Foldable, { renderFoldableSection: ({ isUnfolded }) => (jsxs("div", { children: [jsx("div", { className: COMMON_FILTERS_STYLES, children: visibleFilters }), jsx(FoldableSection, { className: COMMON_FILTERS_STYLES, isUnfolded: isUnfolded, children: hiddenFilters })] })), renderFoldButton: renderFoldButton$1(reset, onlyOffice) }) })) : null }));
6697
+ const badgeBgStyleMap = {
6698
+ primary: 'bg-white/30',
6699
+ secondary: 'bg-main-divider',
6507
6700
  };
6508
- const renderFoldButton$1 = (reset, onlyOffice = false) => ({ isUnfolded, onToggle }) => {
6509
- const labels = ['Больше фильтров', 'Меньше фильтров'];
6510
- const icons = ['ArrowDownIcon', 'ArrowUpIcon'];
6511
- return (jsxs("div", { className: "flex space-x-lg", children: [onlyOffice ? (jsx(LinkButton, { version: "transparent", className: "text-secondary-text [&>*]:p-0", appendRight: jsx(Icon, { name: icons[Number(isUnfolded)], width: "16", height: "16" }), text: labels[Number(isUnfolded)], onClick: onToggle })) : null, jsx(LinkButton, { version: "transparent", className: "text-secondary-text [&>*]:p-0", onClick: reset, children: renderBtnInner() })] }));
6701
+ const badgeTextColorStyleMap = {
6702
+ primary: { desktop: 'text-white', mobile: 'text-primary-text' },
6703
+ secondary: { desktop: 'text-secondary-text', mobile: 'text-secondary-text' },
6512
6704
  };
6513
- const renderBtnInner = () => (jsxs("div", { className: "flex items-center", children: ["\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u0444\u0438\u043B\u044C\u0442\u0440", jsx(Icon, { name: "CloseIcon", width: "16", height: "16", className: "ml-2xs" })] }));
6514
-
6515
- const renderHeading = (title, lengthItems) => (jsx("div", { className: "flex flex-col sm:flex-row gap-xs mb-2xl", children: jsxs(Heading, { headingType: "h3", children: [jsx("span", { suppressHydrationWarning: true, children: title }), lengthItems ? (jsx(Text, { size: "text-h2", color: "text-secondary-text", children: jsx("span", { suppressHydrationWarning: true, children: ` (${lengthItems})` }) })) : null] }) }));
6705
+ const Badge = JSX(({ count, version = 'secondary' }) => {
6706
+ const isMobileMode = useMobileMode();
6707
+ const badgeBgStyle = isMobileMode ? 'bg-main-divider' : badgeBgStyleMap[version];
6708
+ const textStyle = badgeTextColorStyleMap[version][isMobileMode ? 'mobile' : 'desktop'];
6709
+ return (jsx("div", { className: style('w-6 h-6 rounded-full flex items-center justify-center', badgeBgStyle), role: "status", "aria-label": `Количество ${count} доступных программ и сервисов`, children: jsx(Text, { size: "text-xs", color: textStyle, children: count }) }));
6710
+ });
6516
6711
 
6517
- const defaultEmptyFunction = () => void 0;
6518
- const filtersVisibleStyles = (activeButton) => activeButton === 'all' ? 'block' : 'hidden';
6519
- const OfficesAtmsMapLayout = JSX(({ className, data = [], isLoad, remoteWorkplaces = [], renderCard = defaultEmptyFunction, renderRemoteWorkplaceCard = defaultEmptyFunction, getBalloon = defaultEmptyFunction, getBalloonRemoteWorkplaces = defaultEmptyFunction, descriptionData, title, }) => {
6520
- const onlyOffice = title?.includes('Офис');
6521
- const [filtrationState, { field, reset }] = useForm(INITIAL_FILTRATION_STATE$1);
6522
- const [filteredItems, points, filteredRemoteWorkplaces, lengthItems] = useMemo(() => {
6523
- const _filteredItems = filterItems$1(data, filtrationState);
6524
- const _filteredRemoteWorkplaces = filterItems$1(remoteWorkplaces, filtrationState);
6525
- const _points = [
6526
- ..._filteredItems.map((_) => ({
6527
- type: 'offices',
6528
- coords: [Number(_.gpsLatitude), Number(_.gpsLongitude)]?.filter(Boolean),
6529
- content: getBalloon(_),
6530
- })),
6531
- ..._filteredRemoteWorkplaces.map((_) => ({
6532
- type: 'workplaces',
6533
- coords: [Number(_.gpsLatitude), Number(_.gpsLongitude)]?.filter(Boolean),
6534
- content: getBalloonRemoteWorkplaces({
6535
- address: _.address,
6536
- workScheduleDescription: _.workScheduleDescription,
6537
- }),
6538
- })),
6539
- ].filter((_) => _.coords && _.coords.length === 2);
6540
- const itemsLength = _filteredItems.length + _filteredRemoteWorkplaces?.length;
6541
- return [_filteredItems, _points, _filteredRemoteWorkplaces, itemsLength];
6542
- }, [data, remoteWorkplaces, filtrationState]);
6543
- const [activeButton, setActiveButton] = useState('all');
6544
- const filterOptions = {
6545
- filters: getFiltersWithNonEmptyData([...data, ...remoteWorkplaces]),
6546
- field: { field, reset },
6547
- onlyOffice,
6548
- labels: FILTRATION_LABELS,
6549
- };
6550
- return (jsxs("div", { className: style('space-y-1', className), children: [jsxs("div", { className: "bg-white", children: [jsxs("div", { className: "p-3xl pb-0", children: [renderHeading(title, lengthItems), descriptionData ? renderDescriptionBlock$1(descriptionData) : null, onlyOffice && renderButtonsGroup(data, activeButton, setActiveButton), jsx("div", { className: style('pb-3xl', filtersVisibleStyles(activeButton)), children: renderFiltrationForm(filterOptions) })] }), jsx("div", { className: "h-[600px]", children: jsx(ClientOnly, { children: jsx(YandexMap, { points: points, isLoad: isLoad, className: "h-full" }) }) })] }), jsxs(ClientOnly, { children: [filteredItems.map(renderCard), filteredRemoteWorkplaces.map(renderRemoteWorkplaceCard)] })] }));
6712
+ const getButtonClassNames = (isActive) => ({
6713
+ btn: `w-96 ${isActive ? 'p-m border-none bg-primary-main text-white' : 'p-s ease-in duration-300 bg-white'}`,
6714
+ text: isActive ? 'mb-xs text-xl' : 'mb-2xs text-l text-primary-text',
6715
+ desc: `font-light ${isActive ? 'text-l text-white' : 'text-m text-secondary-text'}`,
6716
+ icon: isActive ? '' : 'text-primary-main',
6717
+ iconVersion: (isActive ? 'white' : 'normal'),
6718
+ oldText: 'text-m text-center',
6719
+ oldDesc: 'text-m-light',
6551
6720
  });
6552
- const filterItems$1 = (data, filtrationState) => {
6553
- const truthyFilters = Object.keys(filtrationState).filter((key) => filtrationState[key]);
6554
- return data.filter((item) => truthyFilters.every((_) => FILTRATION_PREDICATES$1[_](item)));
6721
+ const renderTabItemInner = ({ text, description, icon, isActive, type, }) => {
6722
+ const buttonClassNames = getButtonClassNames(isActive);
6723
+ return (jsxs("div", { className: style('cursor-pointer text-left border-b-0 flex gap-2xs'), "aria-label": text, "aria-labelledby": `${text}-label`, children: [icon ? (jsx(Img, { className: style('h-6 w-6 min-w-6 min-h-6', buttonClassNames.icon), image: {
6724
+ ...icon,
6725
+ iconVersion: icon?.iconVersion ?? buttonClassNames.iconVersion,
6726
+ }, width: "24", height: "24", alt: text })) : null, jsxs("div", { className: "border-0", children: [jsx("div", { className: type === 'animated' ? buttonClassNames.text : buttonClassNames.oldText, children: text }), jsx("div", { className: type === 'animated' ? buttonClassNames.desc : buttonClassNames.oldDesc, children: description })] })] }));
6555
6727
  };
6556
- const getFiltersWithNonEmptyData = (data) => Object.keys(INITIAL_FILTRATION_STATE$1).filter((_) => data.filter((item) => FILTRATION_PREDICATES$1[_](item)).length);
6557
6728
 
6558
- const colorStyle = {
6559
- yellow: { border: 'border-yellow-light', text: 'text-yellow' },
6560
- green: { border: 'border-green-more-light', text: 'text-green-dark' },
6561
- gray: { border: 'border-gray', text: 'text-secondary-text' },
6562
- red: { border: 'border-error/30', text: 'text-error' },
6729
+ const tabPaddingStyleMap = {
6730
+ default: 'px-xs',
6731
+ underlined: 'px-m',
6732
+ animated: 'px-m border border-gray cursor-pointer text-left border-b-0 mt-auto flex gap-2xs',
6733
+ };
6734
+ const tabTextStyle = 'text-secondary-text hover:text-primary-main';
6735
+ const activeTabTextStyleMap = {
6736
+ default: 'text-black sm:text-white',
6737
+ underlined: 'text-primary-main border-b-2',
6738
+ animated: 'text-white sm:text-white',
6739
+ };
6740
+ const tabBgStyleMap = {
6741
+ default: 'bg-white',
6742
+ underlined: 'bg-white',
6743
+ animated: 'p-1 ease-in duration-300 bg-white text-primary-text h-[70px] w-96',
6744
+ };
6745
+ const activeTabBgStyleMap = {
6746
+ default: 'bg-white sm:bg-primary-main',
6747
+ underlined: 'bg-white',
6748
+ animated: 'p-2 border-none bg-primary-main text-white h-20 w-96',
6563
6749
  };
6564
- const Badge = JSX(({ className, children, color = 'gray' }) => (jsxs("div", { className: style('sm:p-s sm:border sm:border-green rounded-md flex items-center h-fit', colorStyle[color].border, className), children: [jsx("div", { className: "block pr-m sm:pr-0 sm:hidden", children: jsx(Img, { image: { icon: 'SmallClockIcon' }, width: "24", height: "24" }) }), jsx(Text, { size: "text-m", color: colorStyle[color].text, children: children })] })));
6750
+ const TabItemInner = JSX(({ tag = 'div', item = {}, isActive = false, type = 'default', onClick }) => {
6751
+ const Tag = tag;
6752
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6753
+ const { text, description, icon, count, tabName, ...link } = item;
6754
+ return (jsx(Tag, { className: style('h-12', 'block flex-1', 'cursor-pointer', tabPaddingStyleMap[type], isActive ? activeTabBgStyleMap[type] : tabBgStyleMap[type]), role: "tablist", "aria-label": "\u0421\u043F\u0438\u0441\u043E\u043A \u0442\u0430\u0431\u043E\u0432", onClick: onClick, ...link, children: jsxs("div", { className: style('h-full', 'flex justify-center items-center', 'text-center whitespace-nowrap', isActive ? activeTabTextStyleMap[type] : tabTextStyle), role: "tab", "aria-label": `Таб ${text}`, children: [renderTabItemInner({
6755
+ text,
6756
+ description,
6757
+ icon,
6758
+ isActive,
6759
+ type,
6760
+ }), Number.isInteger(count) ? (jsx("div", { className: "ml-xs", role: "status", "aria-label": `Количество программ и сервисов ${count}`, children: jsx(Badge, { count: count, version: getVersion(isActive, type) }) })) : null] }) }));
6761
+ });
6565
6762
 
6566
- const CardCell = JSX(({ value, subText, children, isPhone, ...props }) => {
6567
- const textItems = (Array.isArray(value) ? value : value?.split(',') ?? []).filter(Boolean);
6568
- if ([textItems.length, children, subText].every((_) => !_)) {
6569
- return null;
6570
- }
6571
- return renderCardCell({ textItems, subText, children, isPhone, ...props });
6763
+ const TabItem = JSX((props) => props?.item?.href ? jsx(LinkTabItem, { ...props }) : jsx(ButtonTabItem, { ...props }));
6764
+ const LinkTabItem = JSX((props) => {
6765
+ const link = useLink();
6766
+ const handleClick = useCallback(() => {
6767
+ props.onClick && props.onClick(props.item || {});
6768
+ }, [props.onClick, props.item]);
6769
+ const { onClick, ...item } = link({ ...props.item, onClick: handleClick });
6770
+ return jsx(TabItemInner, { ...props, tag: "a", item: item, onClick: onClick });
6771
+ });
6772
+ // TODO: Update handlerDecorator (support buttons?)
6773
+ const ButtonTabItem = JSX(({ item = {}, onClick, ...rest }) => {
6774
+ const handleClick = useCallback(() => {
6775
+ onClick && onClick(item);
6776
+ }, [onClick, item]);
6777
+ return jsx(TabItemInner, { item: item, onClick: handleClick, ...rest });
6572
6778
  });
6573
- const renderCardCell = ({ label, labelSize = 'text-m', textItems, subColor, subText, className, children, isPhone = false, }) => (jsxs("div", { className: style('flex gap-2xs flex-col h-full max-w-[300px]', className), children: [label ? (jsx(Text, { color: "text-secondary-text", font: "font-light", size: labelSize, children: label })) : null, children || renderTextItems(textItems, isPhone), subText ? (jsx(Text, { color: subColor, size: "text-m", children: subText })) : null] }));
6574
- const renderTextItems = (textItems, isPhone) => textItems.filter(Boolean).map((text, i) => (jsx(Text, { size: "text-l", children: isPhone ? jsx("a", { href: `tel:${cleanPhoneNumber(text)}`, children: text.trim() }) : text.trim() }, String(i))));
6575
- const cleanPhoneNumber = (phone) => phone.replace(/\D/g, '');
6576
6779
 
6577
- const CardRow = JSX(({ className, children }) => (jsx("div", { className: style('flex flex-col sm:flex-row sm:border-t sm:border-solid sm:border-main-divider py-xl gap-x-6xl gap-y-xl', className), children: children })));
6780
+ const renderTab = (activeTab, onClick, type) => (tab, i) => (jsx(TabItem, { isActive: tab === activeTab, onClick: onClick, type: type, item: tab }, String(i)));
6578
6781
 
6579
- const ICONS = ['ArrowDownIcon', 'ArrowUpIcon'];
6580
- const labels = ['Подробнее', 'Скрыть'];
6581
- const renderFoldButton = ({ isUnfolded, onToggle }) => (jsxs("button", { className: "w-full py-2xl cursor-pointer text-primary-main flex items-center border-b border-solid border-main-divider", onClick: onToggle, type: "button", children: [jsx("div", { className: "pr-m", children: labels[Number(isUnfolded)] }), jsx(Icon, { className: "text-primary-text", name: ICONS[Number(isUnfolded)], width: "16", height: "16" })] }));
6782
+ const TabsControl = JSX(({ className, tabsType = 'default', items = [], activeItem, onChange }) => (jsx("div", { className: style('flex gap-x-2xs overflow-x-auto no-scrollbar', className), role: "tabpanel", "aria-label": "\u041F\u0430\u043D\u0435\u043B\u044C \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0442\u0430\u0431\u0430\u043C\u0438", children: items.map(renderTab(activeItem, onChange, tabsType)) })));
6783
+
6784
+ const initialFiltrationState = {
6785
+ categories: [],
6786
+ extraOptions: [],
6787
+ propertyType: [],
6788
+ stage: [],
6789
+ };
6790
+ const MortgageFiltration = UniBlock(({ className, hotFilters, filtrationSchema = {}, resetButton, ...rest }) => {
6791
+ const [filtrationState, { blocksToRender }, { field, reset, update: replaceFiltrationState }] = useFiltrationForm(initialFiltrationState, {
6792
+ block: rest.block,
6793
+ page: rest.options?.page,
6794
+ });
6795
+ const handleFiltrationStateChange = useCallback((_ = initialFiltrationState) => replaceFiltrationState(_), []);
6796
+ const tabsControlProps = useHotFilters({
6797
+ hotFilters,
6798
+ filtrationState,
6799
+ blocks: rest.block?.blocks,
6800
+ onFiltrationStateChange: handleFiltrationStateChange,
6801
+ });
6802
+ return (jsxs(BlockWrapper, { className: style('space-y-2xs', className), defaultPadding: "p-0", version: "transparent", ...rest, children: [jsx(TabsControl, { ...tabsControlProps }), jsx(FiltrationForm, { filtrationSchema: filtrationSchema, resetButton: resetButton, field: field, reset: reset }), jsx(FilteredBlocks, { blocksToRender: blocksToRender, ...rest })] }));
6803
+ }, {
6804
+ childrenTypes: ['ProductBlock'],
6805
+ childSchema: (content) => content?.filtrationSchema || {},
6806
+ });
6582
6807
 
6583
6808
  const renderAtmCard = ({ location, address, billAcceptorType, terminalType, billAcceptorEnable, atmCode = '', atmAccess = '', workTime, }, i) => {
6584
6809
  const additionalInfo = [
6585
6810
  {
6586
6811
  label: 'Устройство',
6587
- value: capitalizedFirstLetter$1(terminalType),
6812
+ value: capitalizedFirstLetter(terminalType),
6588
6813
  },
6589
6814
  { label: 'Модуль приема наличных', value: billAcceptorEnable ? 'Да' : 'Нет' },
6590
6815
  {
@@ -6597,19 +6822,19 @@
6597
6822
  },
6598
6823
  { label: 'Регистрационный номер', value: atmCode },
6599
6824
  ];
6600
- return (jsxs("div", { className: "bg-white col-span-12 p-3xl sm:border-green sm:border", children: [jsxs("div", { className: "sm:flex sm:justify-between", children: [jsxs("div", { children: [jsx(Text, { size: "text-h4", children: capitalizedFirstLetter$1(location) }), address ? (jsxs("div", { className: "flex pb-xl pt-xs gap-2xs", children: [jsx(Icon, { name: "GeolocationIcon", width: "24", height: "24" }), jsx(Text, { size: "text-l", children: address })] })) : null] }), jsx("div", { className: "whitespace-nowrap", children: jsx(Badge, { color: "green", children: capitalizedFirstLetter$1(workTime) }) })] }), jsx("div", { className: "hidden sm:block", children: jsx(CardRow, { className: "flex-wrap", children: additionalInfo?.map(renderInfo) }) }), jsx(Foldable, { className: "block sm:hidden", renderFoldableSection: ({ isUnfolded }) => {
6825
+ return (jsxs("div", { className: "bg-white col-span-12 p-3xl sm:border-green sm:border", children: [jsxs("div", { className: "sm:flex sm:justify-between", children: [jsxs("div", { children: [jsx(Text, { size: "text-h4", children: capitalizedFirstLetter(location) }), address ? (jsxs("div", { className: "flex pb-xl pt-xs gap-2xs", children: [jsx(Icon, { name: "GeolocationIcon", width: "24", height: "24" }), jsx(Text, { size: "text-l", children: address })] })) : null] }), jsx("div", { className: "whitespace-nowrap", children: jsx(Badge$1, { color: "green", children: capitalizedFirstLetter(workTime) }) })] }), jsx("div", { className: "hidden sm:block", children: jsx(CardRow, { className: "flex-wrap", children: additionalInfo?.map(renderInfo) }) }), jsx(Foldable, { className: "block sm:hidden", renderFoldableSection: ({ isUnfolded }) => {
6601
6826
  return (jsx(FoldableSection, { isUnfolded: isUnfolded, children: jsx(CardRow, { className: "flex-wrap", children: additionalInfo?.map(renderInfo) }) }));
6602
6827
  },
6603
6828
  //** TODO: Remove styles with refactoring DefaultFoldButton*/
6604
- renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton({ isUnfolded, onToggle }) })] }, String(i)));
6829
+ renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton$3({ isUnfolded, onToggle }) })] }, String(i)));
6605
6830
  };
6606
6831
  const getAtmPoint = ({ address = '', terminalType, atmCode = '' }) => {
6607
- const header = `${capitalizedFirstLetter$1(terminalType)} №${atmCode}`;
6832
+ const header = `${capitalizedFirstLetter(terminalType)} №${atmCode}`;
6608
6833
  const body = address.toUpperCase();
6609
6834
  return { header, body };
6610
6835
  };
6611
6836
  const renderInfo = (item, i) => (jsx(CardCell, { ...item }, String(i)));
6612
- const capitalizedFirstLetter$1 = (text) => text ? `${text?.charAt(0)?.toUpperCase()}${text?.slice(1)}` : '';
6837
+ const capitalizedFirstLetter = (text) => text ? `${text?.charAt(0)?.toUpperCase()}${text?.slice(1)}` : '';
6613
6838
 
6614
6839
  const EMPTY_VALUE$2 = [];
6615
6840
  function useAtms(regionCode) {
@@ -6657,172 +6882,6 @@
6657
6882
  });
6658
6883
  };
6659
6884
 
6660
- const getScheduleDescription = (workScheduleWeek) => {
6661
- const rows = getDateDescription(workScheduleWeek);
6662
- return jsx(CardCell, { label: "\u0420\u0435\u0436\u0438\u043C \u0440\u0430\u0431\u043E\u0442\u044B", value: rows, className: "max-w-none" });
6663
- };
6664
- const buildScheduleText = ({ workTime = '', lunchHour = '', daysOff = '' }, isSaturday = false) => {
6665
- if (!workTime) {
6666
- return '';
6667
- }
6668
- return [
6669
- `${isSaturday ? 'Суббота' : 'Будние дни'}: ${workTime}`,
6670
- lunchHour ? `перерыв: ${lunchHour}` : '',
6671
- daysOff ? `не работает: ${daysOff}` : '',
6672
- ]
6673
- .filter(Boolean)
6674
- .join('; ');
6675
- };
6676
- const getDateDescription = (workScheduleWeek) => {
6677
- const workingWeekday = workScheduleWeek.find((_) => _.key !== 'workingSaturday' && Boolean(_.status) && Boolean(_.workTime));
6678
- const workingSaturday = workScheduleWeek.find((_) => _.key === 'workingSaturday' && Boolean(_.status) && Boolean(_.workTime));
6679
- const daysOff = workScheduleWeek
6680
- .filter((_) => !_.status)
6681
- .map((_) => _.short?.toLowerCase())
6682
- .join(', ');
6683
- const rows = [
6684
- buildScheduleText({
6685
- workTime: workingWeekday?.workTime,
6686
- lunchHour: workingWeekday?.lunchHour,
6687
- daysOff: workingSaturday ? '' : daysOff,
6688
- }),
6689
- buildScheduleText({ workTime: workingSaturday?.workTime, lunchHour: workingSaturday?.lunchHour, daysOff }, true),
6690
- ].filter(Boolean);
6691
- return rows;
6692
- };
6693
-
6694
- const WEEKDAY_MAP = [
6695
- ['workingMonday', 'Пн', 'Понедельник'],
6696
- ['workingTuesday', 'Вт', 'Вторник'],
6697
- ['workingWednesday', 'Ср', 'Среда'],
6698
- ['workingThursday', 'Чт', 'Четверг'],
6699
- ['workingFriday', 'Пт', 'Пятница'],
6700
- ['workingSaturday', 'Сб', 'Суббота'],
6701
- ['workingSunday', 'Вс', 'Воскресенье'],
6702
- ];
6703
- const getWorkScheduleWeek = (workSchedule) => WEEKDAY_MAP.map(([key, short, title]) => ({
6704
- key,
6705
- title,
6706
- short,
6707
- status: Boolean(workSchedule?.[key]),
6708
- get workTime() {
6709
- return key === 'workingSaturday' ? workSchedule?.workTimeSaturday : workSchedule?.workTime;
6710
- },
6711
- get lunchHour() {
6712
- return key === 'workingSaturday' ? workSchedule?.lunchHourSaturday : workSchedule?.lunchHour;
6713
- },
6714
- get hasLunch() {
6715
- return /\d+/.test(this.lunchHour ?? '');
6716
- },
6717
- }));
6718
-
6719
- const renderBusinessSchedule = (scheduleDescription) => {
6720
- if (!scheduleDescription) {
6721
- return null;
6722
- }
6723
- const businessSchedule = getBusinessSchedule(scheduleDescription);
6724
- return (jsxs(CardRow, { className: "border-none", children: [jsx(CardCell, { label: "\u0414\u043B\u044F \u044E\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", labelSize: "text-l", children: jsx("div", { className: "flex gap-1", children: businessSchedule.map(renderAlternativeDay) }) }), jsx(CardCell, { label: "\u0420\u0435\u0436\u0438\u043C \u0440\u0430\u0431\u043E\u0442\u044B", className: "max-w-none", children: jsx(Text, { children: scheduleDescription }) })] }));
6725
- };
6726
- const getBusinessSchedule = (scheduleDescription) => {
6727
- const weekDayMap = WEEKDAY_MAP.map(([, short]) => ({ short, status: true }));
6728
- const splittedScheduleDescription = scheduleDescription.split('/') ?? [];
6729
- const lastPartScheduleDescription = splittedScheduleDescription[splittedScheduleDescription.length - 1]?.toLowerCase();
6730
- if (!lastPartScheduleDescription?.includes('выходной')) {
6731
- return weekDayMap;
6732
- }
6733
- return weekDayMap.map((_) => ({
6734
- ..._,
6735
- status: !lastPartScheduleDescription?.includes(_.short.toLowerCase()),
6736
- }));
6737
- };
6738
- const renderAlternativeDay = ({ short, status }, i) => (jsx("div", { className: style('w-9 h-9 rounded-md flex items-center justify-center', status ? 'bg-green-more-light text-green-dark' : 'bg-error/30 text-error'), children: jsx(Text, { size: "text-xs", children: short }) }, String(i)));
6739
-
6740
- const renderCurrency = ({ currency, buyExchangeRate, saleExchangeRate }, i) => (jsxs("div", { className: "flex gap-lg h-full", children: [currency?.currency ? jsx(CardCell, { label: "\u0412\u0430\u043B\u044E\u0442\u0430", value: currency.currency }) : null, buyExchangeRate ? jsx(CardCell, { label: "\u041A\u0443\u043F\u0438\u0442\u044C", value: String(buyExchangeRate) }) : null, saleExchangeRate ? jsx(CardCell, { label: "\u041F\u0440\u043E\u0434\u0430\u0442\u044C", value: String(saleExchangeRate) }) : null] }, String(i)));
6741
-
6742
- const currentWeekDayIdx = new Date().getDay();
6743
- //TODO: Add logic time https://github.com/redneckz/wildless-cms-uni-blocks/pull/1549
6744
- const renderCurrentDaySchedule = (workScheduleWeek) => {
6745
- const [currentWeekDay] = workScheduleWeek?.slice(currentWeekDayIdx - 1) ?? [];
6746
- if (!currentWeekDay) {
6747
- return null;
6748
- }
6749
- const { lunchHour, status, workTime, hasLunch } = currentWeekDay;
6750
- return status ? (jsxs("div", { className: "flex gap-s items-start whitespace-nowrap", children: [workTime ? jsx(Badge, { color: "green", children: workTime }) : null, lunchHour && hasLunch ? jsx(Badge, { color: "yellow", children: `перерыв: ${lunchHour}` }) : null] })) : (jsx(Badge, { color: "red", children: "\u0412\u044B\u0445\u043E\u0434\u043D\u043E\u0439" }));
6751
- };
6752
-
6753
- const getSubTextLunch = ({ lunchHour, hasLunch = false, status = false }) => {
6754
- if (!status) {
6755
- return 'Не работает';
6756
- }
6757
- return lunchHour && hasLunch ? `Перерыв ${lunchHour}` : lunchHour;
6758
- };
6759
- const renderDay = ({ title, status, workTime, lunchHour, hasLunch }, i) => (jsx(CardCell, { label: title, value: status && workTime ? workTime : '', subText: getSubTextLunch({ lunchHour, hasLunch, status }), subColor: !status || hasLunch ? 'text-error' : 'text-green-dark' }, String(i)));
6760
-
6761
- const renderWorkSchedule = (workSchedule) => {
6762
- const workScheduleWeek = getWorkScheduleWeek(workSchedule);
6763
- const timeOfWork = workSchedule ? getDateDescription(workScheduleWeek) : '';
6764
- const businessTimeOfWork = workSchedule ? workSchedule.businessScheduleDescription : '';
6765
- if (!workSchedule) {
6766
- return null;
6767
- }
6768
- if (!workSchedule.businessScheduleVisibleTag) {
6769
- return renderMatchingTimeOfWork(timeOfWork);
6770
- }
6771
- if (workSchedule.businessScheduleVisibleTag &&
6772
- workSchedule.businessScheduleDescription === null) {
6773
- return renderIndividualTimeOfWork(timeOfWork);
6774
- }
6775
- return renderDefaultTimeOfWork(timeOfWork, businessTimeOfWork);
6776
- };
6777
- const renderIndividualTimeOfWork = (timeOfWork) => `<p><b>Режим обслуживания физ.лиц:<br/></b>${timeOfWork}</p>`;
6778
- const renderMatchingTimeOfWork = (timeOfWork) => `<p><b>Режим обслуживания физ. и юр. лиц:<br/></b> ${timeOfWork}</p>`;
6779
- const renderDefaultTimeOfWork = (timeOfWork, businessTimeOfWork) => `<p><b>Режим обслуживания физ.лиц:<br/></b>${timeOfWork}</p> <p><b>Режим обслуживания юр.лиц:<br/></b>${businessTimeOfWork}</p>`;
6780
-
6781
- const renderOfficeCard = ({ name, address, phone, fax, phoneBusiness, phoneNatural, phoneCallCentre, phoneCurrencyControl, workSchedule, exchangeRate, }, i) => {
6782
- if (!workSchedule) {
6783
- return null;
6784
- }
6785
- const workScheduleWeek = getWorkScheduleWeek(workSchedule);
6786
- return (jsxs("div", { className: "bg-white col-span-12 p-3xl sm:border-green sm:border", children: [jsxs("div", { className: "sm:flex sm:justify-between", children: [jsxs("div", { children: [jsx(Text, { size: "text-h4", children: name }), address ? (jsxs("div", { className: "flex pb-xl pt-xs gap-2xs", children: [jsx(Icon, { name: "GeolocationIcon", width: "24", height: "24" }), jsx(Text, { size: "text-l", children: address })] })) : null] }), renderCurrentDaySchedule(workScheduleWeek)] }), jsx("div", { className: "hidden sm:block", children: renderCardContent$1({
6787
- phone,
6788
- fax,
6789
- phoneBusiness,
6790
- phoneNatural,
6791
- phoneCallCentre,
6792
- phoneCurrencyControl,
6793
- workSchedule,
6794
- exchangeRate,
6795
- }) }), jsx(Foldable, { className: "block sm:hidden", renderFoldableSection: ({ isUnfolded }) => {
6796
- return (jsx(FoldableSection, { isUnfolded: isUnfolded, children: renderCardContent$1({
6797
- phone,
6798
- fax,
6799
- phoneBusiness,
6800
- phoneNatural,
6801
- phoneCallCentre,
6802
- phoneCurrencyControl,
6803
- workSchedule,
6804
- exchangeRate,
6805
- }) }));
6806
- },
6807
- //** TODO: remove styles with refactoring DefaultFoldButton*/
6808
- renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton({ isUnfolded, onToggle }) })] }, String(i)));
6809
- };
6810
- const renderCardContent$1 = ({ phone, fax, phoneBusiness, phoneNatural, phoneCallCentre, phoneCurrencyControl, workSchedule, exchangeRate, }) => {
6811
- const workScheduleWeek = getWorkScheduleWeek(workSchedule);
6812
- const labelSchedule = workSchedule?.businessScheduleVisibleTag
6813
- ? 'Для физических лиц'
6814
- : 'Для физических и юридических лиц';
6815
- return (jsxs("div", { children: [jsxs(CardRow, { className: "flex-wrap border-b border-solid border-main-divider", children: [jsx(CardCell, { label: "\u0424\u0430\u043A\u0441", value: fax, isPhone: true }), jsx(CardCell, { label: "\u0422\u0435\u043B\u0435\u0444\u043E\u043D \u0444\u0438\u043B\u0438\u0430\u043B\u0430", value: phone, isPhone: true }), jsx(CardCell, { label: "\u0414\u043B\u044F \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u044E\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", value: phoneBusiness, isPhone: true }), jsx(CardCell, { label: "\u041E\u0431\u0441\u043B\u0443\u0436\u0438\u0432\u0430\u043D\u0438\u0435 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", value: phoneNatural, isPhone: true }), jsx(CardCell, { label: "\u0414\u043B\u044F \u043A\u043E\u043D\u0441\u0443\u043B\u044C\u0442\u0430\u0446\u0438\u0439 \u043F\u043E \u0432\u0430\u043B\u044E\u0442\u043D\u043E\u043C\u0443 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044E", value: phoneCurrencyControl, isPhone: true }), jsx(CardCell, { label: "\u041A\u043E\u043D\u0442\u0430\u043A\u0442-\u0446\u0435\u043D\u0442\u0440", value: phoneCallCentre, isPhone: true })] }), workSchedule?.isMatchesPattern ? (jsx(CardRow, { children: jsx(CardCell, { label: labelSchedule, labelSize: "text-l", className: "w-full max-w-none", children: jsx("div", { className: "flex flex-wrap gap-xs sm:justify-between pt-xs", children: workScheduleWeek?.map(renderDay) }) }) })) : (jsxs(CardRow, { children: [jsx(CardCell, { label: labelSchedule, labelSize: "text-l", children: jsx("div", { className: "flex gap-1", children: workScheduleWeek?.map(renderAlternativeDay) }) }), getScheduleDescription(workScheduleWeek)] })), workSchedule?.businessScheduleVisibleTag
6816
- ? renderBusinessSchedule(workSchedule?.businessScheduleDescription)
6817
- : null, exchangeRate?.currencies?.length ? (jsx(CardRow, { className: "flex-wrap", children: exchangeRate?.currencies?.map(renderCurrency) })) : null] }));
6818
- };
6819
- const capitalizedFirstLetter = (text) => text ? `${text?.charAt(0)?.toUpperCase()}${text?.slice(1)}` : '';
6820
- const getOfficePoint = ({ name = '', address = '', workSchedule }) => {
6821
- const header = capitalizedFirstLetter(name);
6822
- const body = `${address} ${renderWorkSchedule(workSchedule)}`;
6823
- return { header, body };
6824
- };
6825
-
6826
6885
  const renderRemoteWorkplaceCard = ({ address, workScheduleDescription }, i) => {
6827
6886
  if (!workScheduleDescription) {
6828
6887
  return null;
@@ -6833,7 +6892,7 @@
6833
6892
  workScheduleDescription,
6834
6893
  }) })),
6835
6894
  //** TODO: remove styles with refactoring DefaultFoldButton*/
6836
- renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton({ isUnfolded, onToggle }) })] }, String(i)));
6895
+ renderFoldButton: ({ isUnfolded, onToggle }) => renderFoldButton$3({ isUnfolded, onToggle }) })] }, String(i)));
6837
6896
  };
6838
6897
  const renderCardContent = ({ workScheduleDescription }) => {
6839
6898
  return (jsxs("div", { children: [jsxs(CardRow, { className: "flex", children: [jsx(CardCell, { label: "\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043B\u044F \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", children: jsx(Text, { children: "\u041E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u0435 \u0438 \u043E\u0431\u0441\u043B\u0443\u0436\u0438\u0432\u0430\u043D\u0438\u0435 \u043A\u0440\u0435\u0434\u0438\u0442\u043E\u0432, \u0441\u0447\u0435\u0442\u043E\u0432, \u0432\u043A\u043B\u0430\u0434\u043E\u0432" }) }), jsx(CardCell, { label: "\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043B\u044F \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", children: jsx(Text, { children: "\u041E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u0435 \u0438 \u043E\u0431\u0441\u043B\u0443\u0436\u0438\u0432\u0430\u043D\u0438\u0435 \u0431\u0430\u043D\u043A\u043E\u0432\u0441\u043A\u0438\u0445 \u043A\u0430\u0440\u0442" }) }), jsx(CardCell, { label: "\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043B\u044F \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", children: jsx(Text, { children: "\u0418\u043D\u0432\u0435\u0441\u0442\u0438\u0446\u0438\u043E\u043D\u043D\u043E\u0435 \u0438 \u043D\u0430\u043A\u043E\u043F\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u0441\u0442\u0440\u0430\u0445\u043E\u0432\u0430\u043D\u0438\u0435" }) }), jsx(CardCell, { label: "\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043B\u044F \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043B\u0438\u0446", children: jsx(Text, { children: "\u0411\u0435\u0437\u043D\u0430\u043B\u0438\u0447\u043D\u044B\u0435 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u0440\u0443\u0431\u043B\u044F\u0445, \u043F\u0435\u0440\u0435\u0432\u043E\u0434\u044B \u0431\u0435\u0437 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u044F \u0441\u0447\u0451\u0442\u0430" }) })] }), jsx("hr", { className: "text-main-divider pb-xl" }), jsx(CardCell, { label: "\u0420\u0435\u0436\u0438\u043C \u0440\u0430\u0431\u043E\u0442\u044B", className: "max-w-none", children: jsx(Text, { children: workScheduleDescription }) })] }));
@@ -7864,7 +7923,7 @@
7864
7923
  slots: () => [HEADER_SLOT, FOOTER_SLOT, STICKY_FOOTER_SLOT],
7865
7924
  });
7866
7925
 
7867
- const packageVersion = "0.14.622";
7926
+ const packageVersion = "0.14.624";
7868
7927
 
7869
7928
  exports.Blocks = Blocks;
7870
7929
  exports.ContentPage = ContentPage;