@redneckz/wildless-cms-uni-blocks 0.2.52 → 0.2.55

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 (114) hide show
  1. package/dist/BaseTile.d.ts +13 -0
  2. package/dist/BaseTile.js +35 -0
  3. package/dist/BaseTile.js.map +1 -0
  4. package/dist/Blocks.d.ts +2 -2
  5. package/dist/Blocks.js.map +1 -1
  6. package/dist/ContentPageContext.d.ts +2 -0
  7. package/dist/ExchangeRateTile.js +7 -5
  8. package/dist/ExchangeRateTile.js.map +1 -1
  9. package/dist/Header/Header.js +2 -2
  10. package/dist/Header/Header.js.map +1 -1
  11. package/dist/Header/HeaderContent.d.ts +1 -1
  12. package/dist/Header/HeaderSecondaryMenu.d.ts +5 -2
  13. package/dist/Header/HeaderSecondaryMenu.js +3 -2
  14. package/dist/Header/HeaderSecondaryMenu.js.map +1 -1
  15. package/dist/MobileAppTile.js +1 -1
  16. package/dist/MobileAppTile.js.map +1 -1
  17. package/dist/ProductBlock.d.ts +2 -0
  18. package/dist/ProductBlock.js +7 -2
  19. package/dist/ProductBlock.js.map +1 -1
  20. package/dist/ProductBlockInner.d.ts +3 -10
  21. package/dist/ProductBlockInner.js +3 -15
  22. package/dist/ProductBlockInner.js.map +1 -1
  23. package/dist/ProductTile.d.ts +4 -13
  24. package/dist/ProductTile.js +4 -11
  25. package/dist/ProductTile.js.map +1 -1
  26. package/dist/Tile.d.ts +3 -11
  27. package/dist/Tile.js +4 -26
  28. package/dist/Tile.js.map +1 -1
  29. package/dist/api/DaDataAPI.d.ts +3 -0
  30. package/dist/api/DaDataAPI.js +33 -0
  31. package/dist/api/DaDataAPI.js.map +1 -0
  32. package/dist/api/LikeAPI.d.ts +1 -1
  33. package/dist/api/LikeAPI.js +2 -2
  34. package/dist/api/LikeAPI.js.map +1 -1
  35. package/dist/content-page-repository/ContentPageRepository.d.ts +1 -0
  36. package/dist/content-page-repository/ContentPageRepository.js +6 -0
  37. package/dist/content-page-repository/ContentPageRepository.js.map +1 -1
  38. package/dist/content-page-repository/toMobilePage.d.ts +2 -0
  39. package/dist/content-page-repository/toMobilePage.js +23 -0
  40. package/dist/content-page-repository/toMobilePage.js.map +1 -0
  41. package/dist/types.d.ts +14 -0
  42. package/dist/utils/getCurrentPosition.d.ts +1 -0
  43. package/dist/utils/getCurrentPosition.js +5 -0
  44. package/dist/utils/getCurrentPosition.js.map +1 -0
  45. package/lib/BaseTile.d.ts +13 -0
  46. package/lib/BaseTile.js +33 -0
  47. package/lib/BaseTile.js.map +1 -0
  48. package/lib/Blocks.d.ts +2 -2
  49. package/lib/Blocks.js.map +1 -1
  50. package/lib/ContentPageContext.d.ts +2 -0
  51. package/lib/ExchangeRateTile.js +7 -5
  52. package/lib/ExchangeRateTile.js.map +1 -1
  53. package/lib/Header/Header.js +2 -2
  54. package/lib/Header/Header.js.map +1 -1
  55. package/lib/Header/HeaderContent.d.ts +1 -1
  56. package/lib/Header/HeaderSecondaryMenu.d.ts +5 -2
  57. package/lib/Header/HeaderSecondaryMenu.js +3 -2
  58. package/lib/Header/HeaderSecondaryMenu.js.map +1 -1
  59. package/lib/MobileAppTile.js +1 -1
  60. package/lib/MobileAppTile.js.map +1 -1
  61. package/lib/ProductBlock.d.ts +2 -0
  62. package/lib/ProductBlock.js +8 -3
  63. package/lib/ProductBlock.js.map +1 -1
  64. package/lib/ProductBlockInner.d.ts +3 -10
  65. package/lib/ProductBlockInner.js +3 -15
  66. package/lib/ProductBlockInner.js.map +1 -1
  67. package/lib/ProductTile.d.ts +4 -13
  68. package/lib/ProductTile.js +4 -11
  69. package/lib/ProductTile.js.map +1 -1
  70. package/lib/Tile.d.ts +3 -11
  71. package/lib/Tile.js +5 -27
  72. package/lib/Tile.js.map +1 -1
  73. package/lib/api/DaDataAPI.d.ts +3 -0
  74. package/lib/api/DaDataAPI.js +30 -0
  75. package/lib/api/DaDataAPI.js.map +1 -0
  76. package/lib/api/LikeAPI.d.ts +1 -1
  77. package/lib/api/LikeAPI.js +2 -2
  78. package/lib/api/LikeAPI.js.map +1 -1
  79. package/lib/common.css +1 -1
  80. package/lib/content-page-repository/ContentPageRepository.d.ts +1 -0
  81. package/lib/content-page-repository/ContentPageRepository.js +6 -0
  82. package/lib/content-page-repository/ContentPageRepository.js.map +1 -1
  83. package/lib/content-page-repository/toMobilePage.d.ts +2 -0
  84. package/lib/content-page-repository/toMobilePage.js +20 -0
  85. package/lib/content-page-repository/toMobilePage.js.map +1 -0
  86. package/lib/types.d.ts +14 -0
  87. package/lib/utils/getCurrentPosition.d.ts +1 -0
  88. package/lib/utils/getCurrentPosition.js +2 -0
  89. package/lib/utils/getCurrentPosition.js.map +1 -0
  90. package/package.json +9 -3
  91. package/src/BaseTile.tsx +87 -0
  92. package/src/Blocks.ts +3 -2
  93. package/src/ContentPage.page.json +212 -76
  94. package/src/ContentPageContext.tsx +3 -0
  95. package/src/ExchangeRateTile.tsx +7 -5
  96. package/src/Header/Header.fixture.tsx +1 -1
  97. package/src/Header/Header.tsx +6 -2
  98. package/src/Header/HeaderContent.ts +1 -1
  99. package/src/Header/HeaderSecondaryMenu.tsx +48 -34
  100. package/src/MobileAppTile.tsx +1 -1
  101. package/src/ProductBlock.fixture.tsx +3 -2
  102. package/src/ProductBlock.tsx +25 -3
  103. package/src/ProductBlockInner.tsx +13 -70
  104. package/src/ProductTile.fixture.tsx +31 -23
  105. package/src/ProductTile.tsx +21 -70
  106. package/src/Tile.fixture.tsx +39 -29
  107. package/src/Tile.tsx +10 -79
  108. package/src/api/DaDataAPI.ts +34 -0
  109. package/src/api/LikeAPI.ts +12 -9
  110. package/src/content-page-repository/ContentPageRepository.ts +7 -0
  111. package/src/content-page-repository/toMobilePage.ts +21 -0
  112. package/src/setup-fixture.ts +15 -0
  113. package/src/types.ts +17 -0
  114. package/src/utils/getCurrentPosition.ts +4 -0
@@ -1,78 +1,35 @@
1
1
  import { JSX } from '@redneckz/uni-jsx';
2
2
  import { EmptyWalletIcon, PercentageSquareIcon, CalendarIcon } from './Icons/index';
3
+ import type { UniBlockProps, Benefit } from './types';
4
+ import { BaseTile } from './BaseTile';
5
+ import type { BaseTileContent } from './BaseTile';
3
6
  import { Img } from './Img';
4
- import type { Picture, UniBlockProps, Benefit } from './types';
5
- import { BlockItem } from './ui-kit/BlockItem';
6
- import type { ButtonProps } from './ui-kit/Button';
7
- import { Button } from './ui-kit/Button';
8
- import { Breadcrumb, BreadcrumbProps } from './ui-kit/Breadcrumb';
9
- import { useLink } from './useLink';
10
- import { joinList } from './utils/joinList';
11
7
 
12
8
  const ICONS = { EmptyWalletIcon, PercentageSquareIcon, CalendarIcon };
13
9
 
14
- export interface ProductBlockInnerContent {
15
- title?: string;
16
- description?: string;
17
- breadcrumbs?: BreadcrumbProps[];
18
- image?: Picture;
10
+ export interface ProductBlockInnerContent extends BaseTileContent {
19
11
  benefits?: Benefit[];
20
- items?: string[];
21
- buttons?: ButtonProps[];
22
12
  }
23
13
 
24
14
  export interface ProductBlockInnerProps extends ProductBlockInnerContent, UniBlockProps {}
25
15
 
26
16
  export const ProductBlockInner = JSX<ProductBlockInnerProps>(
27
- ({ className, context, title, description, breadcrumbs, benefits, buttons, image, items }) => {
28
- const router = context.useRouter();
29
- const { handlerDecorator } = context;
30
-
17
+ ({ className, context, title, description, benefits, buttons, image, items }) => {
31
18
  return (
32
- <div className={`font-sans flex justify-between items-stretch ${className || ''}`}>
33
- <div className="flex flex-col">
34
- {breadcrumbs?.length ? (
35
- <div className="text-xs mb-6">
36
- {joinList(<span className="text-secondary-text mx-2">/</span>)(
37
- breadcrumbs.map((breadcrumb, i) => (
38
- <Breadcrumb
39
- key={String(i)}
40
- {...useLink(
41
- { router, handlerDecorator },
42
- { className: 'text-secondary-text', ...breadcrumb },
43
- )}
44
- />
45
- )),
46
- )}
47
- </div>
48
- ) : null}
19
+ <div className={`flex justify-between items-stretch ${className || ''}`}>
20
+ <div className={'flex flex-col'}>
49
21
  {title && (
50
22
  <h1 className="font-medium text-title-lg m-0 whitespace-pre-wrap max-w-[600px]">
51
23
  {title}
52
24
  </h1>
53
25
  )}
54
- {description && (
55
- <div className="font-normal text-base max-w-[600px] mt-4">{description}</div>
56
- )}
57
- {benefits?.length ? (
58
- <div className="flex gap-6 mt-7">{benefits.map(renderBenefit)}</div>
59
- ) : null}
60
- {items?.length ? (
61
- <section className="mt-5" role="list">
62
- {items.map((_, i) => (
63
- <BlockItem className="mb-2" key={String(i)} text={_} />
64
- ))}
65
- </section>
66
- ) : null}
67
- {buttons?.length ? (
68
- <div className="flex mt-auto gap-4">
69
- {buttons.map((button, index) =>
70
- renderButton(useLink({ router, handlerDecorator }, button), index),
71
- )}
72
- </div>
73
- ) : null}
26
+ <BaseTile context={context} description={description} items={items} buttons={buttons}>
27
+ {benefits?.length ? (
28
+ <div className="flex gap-6 mt-6 mb-12">{benefits.map(renderBenefit)}</div>
29
+ ) : null}
30
+ </BaseTile>
74
31
  </div>
75
- {image?.src && <Img image={image} className="mt-auto" />}
32
+ {image?.src && <Img className="mt-auto" image={image} />}
76
33
  </div>
77
34
  );
78
35
  },
@@ -95,17 +52,3 @@ function renderBenefit(benefit: Benefit, i: number) {
95
52
  </div>
96
53
  );
97
54
  }
98
-
99
- function renderButton(button: ButtonProps, i: number) {
100
- return button?.text ? (
101
- <Button key={String(i)} {...button} className="mt-8" version={button.version} />
102
- ) : null;
103
- }
104
-
105
- function join<E>(sep: E): (list: E[]) => E[] {
106
- return (list) =>
107
- list.reduce(
108
- (acc, el, i) => (acc.length ? acc.concat({ ...sep, key: i }, el) : [el]),
109
- [] as E[],
110
- );
111
- }
@@ -43,11 +43,13 @@ export default {
43
43
  description: 'до 5 лет',
44
44
  },
45
45
  ]}
46
- button={{
47
- text: 'Подробнее',
48
- href: '/credit-cards',
49
- version: 'secondary',
50
- }}
46
+ buttons={[
47
+ {
48
+ text: 'Подробнее',
49
+ href: '/credit-cards',
50
+ version: 'secondary',
51
+ },
52
+ ]}
51
53
  image={cardWithMoney}
52
54
  />
53
55
  </div>
@@ -73,12 +75,14 @@ export default {
73
75
  description: 'до 3 лет',
74
76
  },
75
77
  ]}
76
- button={{
77
- href: 'https://rshb.ru',
78
- text: 'Подробнее',
79
- target: '_blank',
80
- version: 'secondary',
81
- }}
78
+ buttons={[
79
+ {
80
+ href: 'https://rshb.ru',
81
+ text: 'Подробнее',
82
+ target: '_blank',
83
+ version: 'secondary',
84
+ },
85
+ ]}
82
86
  image={letterWithMoney}
83
87
  />
84
88
  </div>
@@ -104,12 +108,14 @@ export default {
104
108
  description: 'до 10 лет',
105
109
  },
106
110
  ]}
107
- button={{
108
- href: 'https://rshb.ru',
109
- text: 'Подробнее',
110
- target: '_blank',
111
- version: 'secondary',
112
- }}
111
+ buttons={[
112
+ {
113
+ href: 'https://rshb.ru',
114
+ text: 'Подробнее',
115
+ target: '_blank',
116
+ version: 'secondary',
117
+ },
118
+ ]}
113
119
  image={building}
114
120
  />
115
121
  </div>
@@ -135,12 +141,14 @@ export default {
135
141
  description: 'до 5 лет',
136
142
  },
137
143
  ]}
138
- button={{
139
- href: 'https://rshb.ru',
140
- text: 'Подробнее',
141
- target: '_blank',
142
- version: 'secondary',
143
- }}
144
+ buttons={[
145
+ {
146
+ href: 'https://rshb.ru',
147
+ text: 'Подробнее',
148
+ target: '_blank',
149
+ version: 'secondary',
150
+ },
151
+ ]}
144
152
  />
145
153
  </div>
146
154
  ),
@@ -1,79 +1,30 @@
1
1
  import { JSX } from '@redneckz/uni-jsx';
2
- import type { ContentPageContext } from './ContentPageContext';
3
- import { Img } from './Img';
4
- import { BlockVersion, Picture } from './types';
5
- import type { ButtonProps } from './ui-kit/Button';
6
- import { Button } from './ui-kit/Button';
7
- import { useLink } from './useLink';
8
- import type { Benefit } from './types';
2
+ import type { UniBlockProps, Benefit } from './types';
3
+ import { BlockVersion } from './types';
4
+ import { Tile } from './Tile';
5
+ import type { BaseTileContent } from './BaseTile';
9
6
 
10
- export interface ProductTileContent {
11
- title?: string;
12
- description?: string;
7
+ export interface ProductTileContent extends BaseTileContent {
13
8
  benefits?: Benefit[];
14
- image?: Picture;
15
- button?: ButtonProps;
16
- version?: BlockVersion;
17
9
  }
18
10
 
19
- export interface ProductTileProps extends ProductTileContent {
20
- className?: string;
21
- context: ContentPageContext;
22
- }
23
-
24
- const productTileStyleMap: Record<BlockVersion, string> = {
25
- primary: 'bg-white text-primary-text',
26
- secondary: 'bg-primary-main text-white',
27
- };
11
+ export interface ProductTileProps extends ProductTileContent, UniBlockProps {}
28
12
 
29
- export const ProductTile = JSX<ProductTileProps>(
30
- ({ className, context, title, description, button, image, benefits, version = 'primary' }) => {
31
- const router = context.useRouter();
32
- const { handlerDecorator } = context;
33
- return (
34
- <section className={`font-sans p-9 ${className || ''} ${productTileStyleMap[version]}`}>
35
- <div className="flex flex-col w-full">
36
- {title && (
37
- <h3 className="font-medium text-title-sm m-0 whitespace-pre-wrap max-w-[600px]">
38
- {title}
39
- </h3>
40
- )}
41
- {description && (
42
- <div className="font-normal text-base max-w-[600px] mt-4">{description}</div>
43
- )}
44
- <div className="flex mt-5">
45
- <div className="grow flex flex-col">
46
- <div className="flex">
47
- {benefits?.length ? (
48
- <div className="mr-8">{benefits.map(renderBenefitDescription)}</div>
49
- ) : null}
50
- {benefits?.length ? (
51
- <div className="pt-1">
52
- {benefits.map((_, i) => renderBenefitLabel(_, i, version))}
53
- </div>
54
- ) : null}
55
- </div>
56
- {button?.text && (
57
- <div className="mt-auto">
58
- <Button
59
- className="mt-8"
60
- {...useLink({ router, handlerDecorator }, button)}
61
- version="secondary"
62
- />
63
- </div>
64
- )}
65
- </div>
66
- {image && (
67
- <div className="mt-auto flex-none h-[220px] w-[220px]">
68
- <Img image={image} />
69
- </div>
70
- )}
71
- </div>
72
- </div>
73
- </section>
74
- );
75
- },
76
- );
13
+ export const ProductTile = JSX<ProductTileProps>((props) => {
14
+ const { benefits, version } = props;
15
+ return (
16
+ <Tile {...props}>
17
+ <div className="flex mt-5 mb-10">
18
+ {benefits?.length ? (
19
+ <div className="mr-8">{benefits.map(renderBenefitDescription)}</div>
20
+ ) : null}
21
+ {benefits?.length ? (
22
+ <div className="pt-1">{benefits.map((_, i) => renderBenefitLabel(_, i, version))}</div>
23
+ ) : null}
24
+ </div>
25
+ </Tile>
26
+ );
27
+ });
77
28
 
78
29
  function renderBenefitLabel(benefit: Benefit, i: number, version = 'primary') {
79
30
  const labelStyleMap: Record<BlockVersion, string> = {
@@ -35,11 +35,13 @@ export default {
35
35
  'Кредиты наличными на любые цели',
36
36
  'Получите деньги без залога и поручителей',
37
37
  ]}
38
- button={{
39
- text: 'Подробнее',
40
- href: '/credit-cards',
41
- version: 'secondary',
42
- }}
38
+ buttons={[
39
+ {
40
+ text: 'Подробнее',
41
+ href: '/credit-cards',
42
+ version: 'secondary',
43
+ },
44
+ ]}
43
45
  image={image}
44
46
  />
45
47
  </div>
@@ -54,12 +56,14 @@ export default {
54
56
  description={
55
57
  'Широкий выбор ипотечных программ с государственной поддержкой. Специальные предложения от 12,2 %'
56
58
  }
57
- button={{
58
- href: 'https://rshb.ru',
59
- text: 'Подробнее',
60
- target: '_blank',
61
- version: 'secondary',
62
- }}
59
+ buttons={[
60
+ {
61
+ href: 'https://rshb.ru',
62
+ text: 'Подробнее',
63
+ target: '_blank',
64
+ version: 'secondary',
65
+ },
66
+ ]}
63
67
  />
64
68
  </div>
65
69
  ),
@@ -70,12 +74,14 @@ export default {
70
74
  className="col-span-6"
71
75
  title="Банковские пластиковые карты"
72
76
  items={['Счета в разных валютах', 'Бесплатное обслуживание', 'Кэшбэк до 15% от покупок']}
73
- button={{
74
- href: 'https://rshb.ru',
75
- text: 'Подробнее',
76
- target: '_blank',
77
- version: 'secondary',
78
- }}
77
+ buttons={[
78
+ {
79
+ href: 'https://rshb.ru',
80
+ text: 'Подробнее',
81
+ target: '_blank',
82
+ version: 'secondary',
83
+ },
84
+ ]}
79
85
  image={image2}
80
86
  />
81
87
  </div>
@@ -89,12 +95,14 @@ export default {
89
95
  description={
90
96
  'Выделенные зоны обслуживания и персональный финансовый консультант. Полный спектр премиальных продуктов, подчеркивающих ваш статус'
91
97
  }
92
- button={{
93
- href: 'https://rshb.ru',
94
- text: 'Подробнее',
95
- target: '_blank',
96
- version: 'secondary',
97
- }}
98
+ buttons={[
99
+ {
100
+ href: 'https://rshb.ru',
101
+ text: 'Подробнее',
102
+ target: '_blank',
103
+ version: 'secondary',
104
+ },
105
+ ]}
98
106
  image={image3}
99
107
  />
100
108
  </div>
@@ -111,12 +119,14 @@ export default {
111
119
  'Площадки для создания комфортной жизни за городом',
112
120
  'Подробная база вакансий для жителей сельской местности',
113
121
  ]}
114
- button={{
115
- href: 'https://rshb.ru',
116
- text: 'Подробнее',
117
- target: '_blank',
118
- version: 'secondary',
119
- }}
122
+ buttons={[
123
+ {
124
+ href: 'https://rshb.ru',
125
+ text: 'Подробнее',
126
+ target: '_blank',
127
+ version: 'secondary',
128
+ },
129
+ ]}
120
130
  image={image4}
121
131
  />
122
132
  </div>
package/src/Tile.tsx CHANGED
@@ -1,89 +1,20 @@
1
1
  import { JSX } from '@redneckz/uni-jsx';
2
- import { Img } from './Img';
3
2
  import type { BlockVersion, Picture, UniBlockProps } from './types';
4
- import { BlockItem } from './ui-kit/BlockItem';
5
- import type { ButtonProps } from './ui-kit/Button';
6
- import { Button } from './ui-kit/Button';
7
- import { useLink } from './useLink';
3
+ import { BaseTile } from './BaseTile';
4
+ import type { BaseTileContent } from './BaseTile';
8
5
 
9
- export interface TileContent {
10
- title?: string;
11
- description?: string;
12
- image?: Picture;
13
- items?: string[];
14
- button?: ButtonProps;
15
- version?: BlockVersion;
16
- }
17
-
18
- export interface TileProps extends TileContent, UniBlockProps {}
6
+ export interface TileProps extends BaseTileContent, UniBlockProps {}
19
7
 
20
8
  const tileStyleMap: Record<BlockVersion, string> = {
21
9
  primary: 'bg-white text-primary-text',
22
10
  secondary: 'bg-primary-main text-white',
23
11
  };
24
12
 
25
- const TITLE_CLASSES = 'font-medium m-0 whitespace-pre-wrap max-w-[600px]';
26
-
27
- export const Tile = JSX<TileProps>(
28
- ({
29
- className,
30
- context,
31
- title,
32
- description,
33
- children,
34
- button,
35
- image,
36
- items,
37
- version = 'primary',
38
- }) => {
39
- const router = context.useRouter();
40
- const { handlerDecorator } = context;
41
- return (
42
- <section
43
- className={`flex flex-col font-sans p-9 ${className || ''} ${tileStyleMap[version]}`}
44
- >
45
- {title && renderTitle(title, className)}
46
- <div className="grow flex justify-between mt-6">
47
- <div className="flex flex-col justify-between items-start">
48
- {description || children ? (
49
- <div className="font-normal text-base max-w-[600px]">{description || children}</div>
50
- ) : (
51
- renderItems(items, version)
52
- )}
53
- {button?.text && (
54
- <Button
55
- className="mt-6"
56
- {...useLink({ router, handlerDecorator }, button)}
57
- version="secondary"
58
- />
59
- )}
60
- </div>
61
- {image?.src && <Img className="mt-auto h-[220px] w-[220px]" image={image} />}
62
- </div>
63
- </section>
64
- );
65
- },
66
- );
67
-
68
- function renderTitle(title: string, className: string = '') {
69
- const colSpanPrefix = 'col-span-';
70
- const colSpanStr = className.split(/\s+/).find((_) => _.startsWith(colSpanPrefix));
71
- const colSpan = colSpanStr ? parseInt(colSpanStr.substring(colSpanPrefix.length), 10) : 12;
72
- if (colSpan <= 4) {
73
- return <h3 className={`${TITLE_CLASSES} text-title-xs`}>{title}</h3>;
74
- } else if (colSpan <= 8) {
75
- return <h3 className={`${TITLE_CLASSES} text-title-sm`}>{title}</h3>;
76
- } else {
77
- return <h2 className={`${TITLE_CLASSES} text-title`}>{title}</h2>;
78
- }
79
- }
80
-
81
- function renderItems(items?: string[], version?: BlockVersion) {
82
- return items?.length ? (
83
- <section className="max-w-[600px]" role="list">
84
- {items.map((_, i) => (
85
- <BlockItem key={String(i)} className={i ? 'mt-2.5' : ''} text={_} version={version} />
86
- ))}
13
+ export const Tile = JSX<TileProps>((props) => {
14
+ const { children, className, version = 'primary' } = props;
15
+ return (
16
+ <section className={`font-sans p-9 ${className || ''} ${tileStyleMap[version]}`}>
17
+ <BaseTile {...props}>{children}</BaseTile>
87
18
  </section>
88
- ) : null;
89
- }
19
+ );
20
+ });
@@ -0,0 +1,34 @@
1
+ import { getCurrentPosition } from '../utils/getCurrentPosition';
2
+
3
+ import type { DaDataResult } from '../types';
4
+
5
+ export function DaDataAPI(baseURL = '') {
6
+ async function getFetcherAddress() {
7
+ if (!('geolocation' in navigator)) {
8
+ return null;
9
+ }
10
+
11
+ try {
12
+ const coords = await getCurrentPosition();
13
+ const response = await fetch(`${baseURL}/geolocate`, {
14
+ method: 'POST',
15
+ mode: 'cors',
16
+ body: JSON.stringify({
17
+ lat: coords.latitude,
18
+ lon: coords.longitude,
19
+ count: 1,
20
+ }),
21
+ });
22
+
23
+ const data = (await response.json()) as DaDataResult;
24
+ return data?.suggestions?.[0]?.data?.city;
25
+ } catch (e) {
26
+ console.error(e);
27
+ return null;
28
+ }
29
+ }
30
+
31
+ return {
32
+ getFetcherAddress,
33
+ };
34
+ }
@@ -10,7 +10,7 @@ export interface LikeData {
10
10
  const AUTH_PREFIX = 'guest';
11
11
  const STORAGE_KEY = 'likesToken';
12
12
 
13
- export function LikeAPI(projectId: string, baseURL: string) {
13
+ export function LikeAPI(projectId: string, baseURL = '') {
14
14
  async function getLikeCount(...nodeIds: string[]): Promise<LikeData[]> {
15
15
  if (!nodeIds.length) {
16
16
  return [];
@@ -19,14 +19,17 @@ export function LikeAPI(projectId: string, baseURL: string) {
19
19
  const { token: Authorization } = await auth();
20
20
 
21
21
  try {
22
- const response = await fetch(`/assist/v1/public/projects/${projectId}/nodes/likes`, {
23
- method: 'POST',
24
- mode: 'cors',
25
- headers: { 'Content-Type': 'application/json', Authorization },
26
- body: JSON.stringify({
27
- node_ids: nodeIds,
28
- }),
29
- });
22
+ const response = await fetch(
23
+ `${baseURL}/assist/v1/public/projects/${projectId}/nodes/likes`,
24
+ {
25
+ method: 'POST',
26
+ mode: 'cors',
27
+ headers: { 'Content-Type': 'application/json', Authorization },
28
+ body: JSON.stringify({
29
+ node_ids: nodeIds,
30
+ }),
31
+ },
32
+ );
30
33
 
31
34
  const { likes } = await response.json();
32
35
 
@@ -1,6 +1,7 @@
1
1
  import glob from 'glob';
2
2
  import util from 'util';
3
3
  import type { ContentPageDef } from '../types';
4
+ import { toMobilePage } from './toMobilePage';
4
5
  import type { TransformationOptions } from './TransformationOptions';
5
6
  import { transformContentPage } from './transformContentPage';
6
7
 
@@ -20,6 +21,11 @@ export function ContentPageRepository({
20
21
  return pages.find((content) => content.slug === slug);
21
22
  }
22
23
 
24
+ async function getMobilePageBySlug(slug: string): Promise<ContentPageDef | undefined> {
25
+ const page = await getContentPageBySlug(slug);
26
+ return page && toMobilePage(page);
27
+ }
28
+
23
29
  const cache: Record<string, ContentPageDef> = {};
24
30
  async function readPage(filePath: string): Promise<ContentPageDef> {
25
31
  if (!(filePath in cache)) {
@@ -34,5 +40,6 @@ export function ContentPageRepository({
34
40
  return {
35
41
  getAllContentPages,
36
42
  getContentPageBySlug,
43
+ getMobilePageBySlug,
37
44
  };
38
45
  }
@@ -0,0 +1,21 @@
1
+ import type { BlockDef, ContentPageDef } from '../types';
2
+
3
+ export function toMobilePage(contentPage: ContentPageDef): ContentPageDef {
4
+ const blocks = contentPage.blocks?.filter(({ mobile }) => !mobile?.hidden).map(toMobileBlock);
5
+ return {
6
+ ...contentPage,
7
+ blocks,
8
+ };
9
+ }
10
+
11
+ function toMobileBlock(block: BlockDef): BlockDef {
12
+ const { mobile } = block;
13
+ if (mobile) {
14
+ return {
15
+ ...block,
16
+ style: mobile.style?.length ? mobile.style : block.style,
17
+ };
18
+ } else {
19
+ return block;
20
+ }
21
+ }
@@ -1,6 +1,8 @@
1
1
  import { setup } from '@redneckz/uni-jsx';
2
+
2
3
  import runtime from 'react/jsx-runtime';
3
4
  import { useState, useEffect } from 'react';
5
+ import { DaDataAPI } from './api/DaDataAPI';
4
6
  import type { ContentPageContext } from './ContentPageContext';
5
7
 
6
8
  const { jsx, jsxs } = runtime as any;
@@ -8,6 +10,8 @@ setup(jsx, jsxs);
8
10
 
9
11
  const TEST_ORIGIN = 'http://localhost:5001';
10
12
 
13
+ const DaData = DaDataAPI('https://10.80.4.9');
14
+
11
15
  export const context: ContentPageContext = {
12
16
  useState,
13
17
  useRouter: () => ({
@@ -27,6 +31,17 @@ export const context: ContentPageContext = {
27
31
  }, [key, fetcher]);
28
32
  return { data };
29
33
  },
34
+ useGeolocation: (defaultLocation) => {
35
+ const [city, setCity] = useState(defaultLocation);
36
+
37
+ const getCity = () => {
38
+ DaData.getFetcherAddress().then((_) => {
39
+ setCity(_ || defaultLocation);
40
+ });
41
+ };
42
+
43
+ return [city, getCity];
44
+ },
30
45
  useLikeService: () => ({
31
46
  likeCount: 0,
32
47
  like: () => {