@redneckz/wildless-cms-uni-blocks 0.2.53 → 0.2.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BaseTile.d.ts +13 -0
- package/dist/BaseTile.js +35 -0
- package/dist/BaseTile.js.map +1 -0
- package/dist/Blocks.d.ts +2 -2
- package/dist/Blocks.js.map +1 -1
- package/dist/ContentPage.d.ts +4 -1
- package/dist/ContentPage.js +3 -4
- package/dist/ContentPage.js.map +1 -1
- package/dist/ContentPageContext.d.ts +2 -0
- package/dist/ExchangeRateTile.js +7 -5
- package/dist/ExchangeRateTile.js.map +1 -1
- package/dist/Footer/Footer.mobile.d.ts +5 -0
- package/dist/Footer/Footer.mobile.js +7 -0
- package/dist/Footer/Footer.mobile.js.map +1 -0
- package/dist/Header/Header.js +2 -2
- package/dist/Header/Header.js.map +1 -1
- package/dist/Header/HeaderContent.d.ts +1 -1
- package/dist/Header/HeaderSecondaryMenu.d.ts +5 -2
- package/dist/Header/HeaderSecondaryMenu.js +3 -2
- package/dist/Header/HeaderSecondaryMenu.js.map +1 -1
- package/dist/MobileBlocks.d.ts +13 -0
- package/dist/MobileBlocks.js +27 -0
- package/dist/MobileBlocks.js.map +1 -0
- package/dist/ProductBlock.d.ts +2 -0
- package/dist/ProductBlock.js +7 -2
- package/dist/ProductBlock.js.map +1 -1
- package/dist/ProductBlockInner.d.ts +3 -10
- package/dist/ProductBlockInner.js +3 -15
- package/dist/ProductBlockInner.js.map +1 -1
- package/dist/ProductTile.d.ts +4 -13
- package/dist/ProductTile.js +4 -11
- package/dist/ProductTile.js.map +1 -1
- package/dist/Tile.d.ts +3 -11
- package/dist/Tile.js +4 -26
- package/dist/Tile.js.map +1 -1
- package/dist/api/DaDataAPI.d.ts +3 -0
- package/dist/api/DaDataAPI.js +33 -0
- package/dist/api/DaDataAPI.js.map +1 -0
- package/dist/api/LikeAPI.d.ts +1 -1
- package/dist/api/LikeAPI.js +2 -2
- package/dist/api/LikeAPI.js.map +1 -1
- package/dist/content-page-repository/ContentPageRepository.d.ts +1 -0
- package/dist/content-page-repository/ContentPageRepository.js +6 -0
- package/dist/content-page-repository/ContentPageRepository.js.map +1 -1
- package/dist/content-page-repository/index.d.ts +1 -0
- package/dist/content-page-repository/index.js +3 -1
- package/dist/content-page-repository/index.js.map +1 -1
- package/dist/content-page-repository/toMobilePage.d.ts +2 -0
- package/dist/content-page-repository/toMobilePage.js +23 -0
- package/dist/content-page-repository/toMobilePage.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/utils/getCurrentPosition.d.ts +1 -0
- package/dist/utils/getCurrentPosition.js +5 -0
- package/dist/utils/getCurrentPosition.js.map +1 -0
- package/lib/BaseTile.d.ts +13 -0
- package/lib/BaseTile.js +33 -0
- package/lib/BaseTile.js.map +1 -0
- package/lib/Blocks.d.ts +2 -2
- package/lib/Blocks.js.map +1 -1
- package/lib/ContentPage.d.ts +4 -1
- package/lib/ContentPage.js +3 -4
- package/lib/ContentPage.js.map +1 -1
- package/lib/ContentPageContext.d.ts +2 -0
- package/lib/ExchangeRateTile.js +7 -5
- package/lib/ExchangeRateTile.js.map +1 -1
- package/lib/Footer/Footer.mobile.d.ts +5 -0
- package/lib/Footer/Footer.mobile.js +5 -0
- package/lib/Footer/Footer.mobile.js.map +1 -0
- package/lib/Header/Header.js +2 -2
- package/lib/Header/Header.js.map +1 -1
- package/lib/Header/HeaderContent.d.ts +1 -1
- package/lib/Header/HeaderSecondaryMenu.d.ts +5 -2
- package/lib/Header/HeaderSecondaryMenu.js +3 -2
- package/lib/Header/HeaderSecondaryMenu.js.map +1 -1
- package/lib/MobileBlocks.d.ts +13 -0
- package/lib/MobileBlocks.js +25 -0
- package/lib/MobileBlocks.js.map +1 -0
- package/lib/ProductBlock.d.ts +2 -0
- package/lib/ProductBlock.js +8 -3
- package/lib/ProductBlock.js.map +1 -1
- package/lib/ProductBlockInner.d.ts +3 -10
- package/lib/ProductBlockInner.js +3 -15
- package/lib/ProductBlockInner.js.map +1 -1
- package/lib/ProductTile.d.ts +4 -13
- package/lib/ProductTile.js +4 -11
- package/lib/ProductTile.js.map +1 -1
- package/lib/Tile.d.ts +3 -11
- package/lib/Tile.js +5 -27
- package/lib/Tile.js.map +1 -1
- package/lib/api/DaDataAPI.d.ts +3 -0
- package/lib/api/DaDataAPI.js +30 -0
- package/lib/api/DaDataAPI.js.map +1 -0
- package/lib/api/LikeAPI.d.ts +1 -1
- package/lib/api/LikeAPI.js +2 -2
- package/lib/api/LikeAPI.js.map +1 -1
- package/lib/common.css +1 -1
- package/lib/content-page-repository/ContentPageRepository.d.ts +1 -0
- package/lib/content-page-repository/ContentPageRepository.js +6 -0
- package/lib/content-page-repository/ContentPageRepository.js.map +1 -1
- package/lib/content-page-repository/index.d.ts +1 -0
- package/lib/content-page-repository/index.js +1 -0
- package/lib/content-page-repository/index.js.map +1 -1
- package/lib/content-page-repository/toMobilePage.d.ts +2 -0
- package/lib/content-page-repository/toMobilePage.js +20 -0
- package/lib/content-page-repository/toMobilePage.js.map +1 -0
- package/lib/index.d.ts +5 -2
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/types.d.ts +14 -0
- package/lib/utils/getCurrentPosition.d.ts +1 -0
- package/lib/utils/getCurrentPosition.js +2 -0
- package/lib/utils/getCurrentPosition.js.map +1 -0
- package/package.json +9 -3
- package/src/BaseTile.tsx +87 -0
- package/src/Blocks.ts +3 -2
- package/src/ContentPage.fixture.tsx +23 -3
- package/src/ContentPage.page.json +255 -77
- package/src/ContentPage.tsx +10 -5
- package/src/ContentPageContext.tsx +3 -0
- package/src/ExchangeRateTile.tsx +7 -5
- package/src/Footer/Footer.mobile.tsx +12 -0
- package/src/Header/Header.fixture.tsx +1 -1
- package/src/Header/Header.tsx +6 -2
- package/src/Header/HeaderContent.ts +1 -1
- package/src/Header/HeaderSecondaryMenu.tsx +48 -34
- package/src/MobileBlocks.ts +25 -0
- package/src/ProductBlock.fixture.tsx +3 -2
- package/src/ProductBlock.tsx +25 -3
- package/src/ProductBlockInner.tsx +13 -70
- package/src/ProductTile.fixture.tsx +31 -23
- package/src/ProductTile.tsx +21 -70
- package/src/Tile.fixture.tsx +39 -29
- package/src/Tile.tsx +10 -79
- package/src/api/DaDataAPI.ts +34 -0
- package/src/api/LikeAPI.ts +12 -9
- package/src/content-page-repository/ContentPageRepository.ts +7 -0
- package/src/content-page-repository/index.ts +1 -0
- package/src/content-page-repository/toMobilePage.ts +21 -0
- package/src/index.ts +14 -2
- package/src/setup-fixture.ts +15 -0
- package/src/types.ts +17 -0
- package/src/utils/getCurrentPosition.ts +4 -0
package/src/ContentPage.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
-
import {
|
|
1
|
+
import { JSX, PropsWithChildren } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { BlockContent } from './Blocks';
|
|
3
3
|
import { LikeControl } from './LikeControl';
|
|
4
4
|
import { Placeholder } from './Placeholder';
|
|
5
5
|
import type { BlockDef, ContentPageDef, UniBlockProps } from './types';
|
|
@@ -16,6 +16,10 @@ export type BlockDecorator<VNode = any> = (
|
|
|
16
16
|
) => any;
|
|
17
17
|
|
|
18
18
|
export interface ContentPageProps extends UniBlockProps {
|
|
19
|
+
blocksRegistry: Record<
|
|
20
|
+
string,
|
|
21
|
+
(props: PropsWithChildren<UniBlockProps & BlockContent, any>, context?: any) => any
|
|
22
|
+
>;
|
|
19
23
|
data: ContentPageDef;
|
|
20
24
|
blockDecorator?: BlockDecorator;
|
|
21
25
|
}
|
|
@@ -26,8 +30,9 @@ const defaultBlockDecorator: BlockDecorator = ({ blockClassName, block, render }
|
|
|
26
30
|
export const ContentPage = JSX<ContentPageProps>(
|
|
27
31
|
({
|
|
28
32
|
className,
|
|
29
|
-
data: { style: pageStyle, blocks, likeControl, colorPalette = 'pc' },
|
|
30
33
|
context,
|
|
34
|
+
blocksRegistry,
|
|
35
|
+
data: { style: pageStyle, blocks, likeControl, colorPalette = 'pc' },
|
|
31
36
|
blockDecorator = defaultBlockDecorator,
|
|
32
37
|
}) => {
|
|
33
38
|
return (
|
|
@@ -48,11 +53,11 @@ export const ContentPage = JSX<ContentPageProps>(
|
|
|
48
53
|
|
|
49
54
|
function renderBlock(block: BlockDef, i: number) {
|
|
50
55
|
const { type } = block;
|
|
51
|
-
if (!(type in
|
|
56
|
+
if (!(type in blocksRegistry)) {
|
|
52
57
|
console.warn(`No block with "${type}" is registered`);
|
|
53
58
|
}
|
|
54
59
|
|
|
55
|
-
const BlockComponent =
|
|
60
|
+
const BlockComponent = blocksRegistry[type] || Placeholder;
|
|
56
61
|
return blockDecorator(
|
|
57
62
|
{
|
|
58
63
|
blockClassName: style2className(block.style),
|
|
@@ -24,10 +24,13 @@ export type AsyncDataHook = <Data, Error = any>(
|
|
|
24
24
|
fetcher: () => Promise<Data>,
|
|
25
25
|
) => { data?: Data; error?: Error };
|
|
26
26
|
|
|
27
|
+
export type GeolocationHook = (defaultLocation: string) => [string, () => void];
|
|
28
|
+
|
|
27
29
|
export interface ContentPageContext {
|
|
28
30
|
useRouter: () => Router;
|
|
29
31
|
useState: <State>(initialState: State) => [State, (_: State) => void];
|
|
30
32
|
useAsyncData: AsyncDataHook;
|
|
33
|
+
useGeolocation: GeolocationHook;
|
|
31
34
|
useLikeService: () => LikeService;
|
|
32
35
|
useSearch: () => Search;
|
|
33
36
|
handlerDecorator?: HandlerDecorator;
|
package/src/ExchangeRateTile.tsx
CHANGED
|
@@ -18,10 +18,12 @@ const CURRENCY_ICONS_MAP = {
|
|
|
18
18
|
EUR: EuroIcon,
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const buttons: ButtonProps[] = [
|
|
22
|
+
{
|
|
23
|
+
text: 'Все показатели',
|
|
24
|
+
href: 'https://cbr.ru/currency_base/daily/',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
25
27
|
|
|
26
28
|
export const ExchangeRateTile = JSX<ExchangeRateTileProps>(({ className, context, title }) => {
|
|
27
29
|
const { data } = context.useAsyncData(CBR_EXCHANGE_RATE_URL, fetchExchangeRate);
|
|
@@ -30,7 +32,7 @@ export const ExchangeRateTile = JSX<ExchangeRateTileProps>(({ className, context
|
|
|
30
32
|
className={className}
|
|
31
33
|
context={context}
|
|
32
34
|
title={title || 'Курсы обмена валют'}
|
|
33
|
-
|
|
35
|
+
buttons={buttons}
|
|
34
36
|
>
|
|
35
37
|
<table>
|
|
36
38
|
<thead>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { UniBlockProps } from '../types';
|
|
3
|
+
import type { FooterContent } from './Footer';
|
|
4
|
+
import { TextInformation } from './TextInformation';
|
|
5
|
+
|
|
6
|
+
export interface FooterProps extends FooterContent, UniBlockProps {}
|
|
7
|
+
|
|
8
|
+
export const Footer = JSX<FooterProps>(({ className, context }) => (
|
|
9
|
+
<footer className={`${className} px-9 py-2 bg-white rounded-bl-3xl rounded-br-3xl`}>
|
|
10
|
+
<TextInformation context={context} />
|
|
11
|
+
</footer>
|
|
12
|
+
));
|
package/src/Header/Header.tsx
CHANGED
|
@@ -13,7 +13,7 @@ import { isTopItemActive } from './isTopItemActive';
|
|
|
13
13
|
|
|
14
14
|
export interface HeaderProps extends HeaderContent, UniBlockProps {}
|
|
15
15
|
|
|
16
|
-
export const Header = JSX<HeaderProps>(({ className,
|
|
16
|
+
export const Header = JSX<HeaderProps>(({ className, defaultLocation, context, topItems }) => {
|
|
17
17
|
const router = context.useRouter();
|
|
18
18
|
const sitemap = useSitemap(context.useAsyncData);
|
|
19
19
|
const { handlerDecorator } = context;
|
|
@@ -46,7 +46,11 @@ export const Header = JSX<HeaderProps>(({ className, location, context, topItems
|
|
|
46
46
|
<div className="flex items-center">
|
|
47
47
|
<Logo className="mr-8" />
|
|
48
48
|
{topMenu}
|
|
49
|
-
<HeaderSecondaryMenu
|
|
49
|
+
<HeaderSecondaryMenu
|
|
50
|
+
context={context}
|
|
51
|
+
className="ml-auto"
|
|
52
|
+
defaultLocation={defaultLocation}
|
|
53
|
+
/>
|
|
50
54
|
</div>
|
|
51
55
|
<div className="mt-5 h-[1px] bg-main-divider" />
|
|
52
56
|
<nav className="mt-5">{subMenu}</nav>
|
|
@@ -2,41 +2,55 @@ import { JSX } from '@redneckz/uni-jsx';
|
|
|
2
2
|
import { GridIcon, LoupeIcon, ProfileIcon } from '../Icons/index';
|
|
3
3
|
import { TopItem } from '../ui-kit/TopItem';
|
|
4
4
|
import { HeaderSecondaryMenuButton } from './HeaderSecondaryMenuButton';
|
|
5
|
+
import type { UniBlockProps } from '../types';
|
|
5
6
|
|
|
6
|
-
interface
|
|
7
|
-
|
|
7
|
+
interface HeaderSecondaryMenuContent {
|
|
8
|
+
defaultLocation?: string;
|
|
8
9
|
className?: string;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
12
|
+
export interface HeaderSecondaryMenuProps extends HeaderSecondaryMenuContent, UniBlockProps {}
|
|
13
|
+
|
|
14
|
+
export const HeaderSecondaryMenu = JSX<HeaderSecondaryMenuProps>(
|
|
15
|
+
({ context, className, defaultLocation = '' }) => {
|
|
16
|
+
const [city, getCity] = context.useGeolocation(defaultLocation);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className={`flex items-center ${className || ''}`}>
|
|
20
|
+
<TopItem
|
|
21
|
+
className="mr-5"
|
|
22
|
+
flat={true}
|
|
23
|
+
href="#"
|
|
24
|
+
text={city}
|
|
25
|
+
ariaLabel="Местоположение"
|
|
26
|
+
onClick={getCity}
|
|
27
|
+
/>
|
|
28
|
+
<TopItem
|
|
29
|
+
className="mr-7"
|
|
30
|
+
flat={true}
|
|
31
|
+
href="#"
|
|
32
|
+
text="Офисы и банкоматы"
|
|
33
|
+
ariaLabel="Список всех доступных офисов и банкоматов"
|
|
34
|
+
/>
|
|
35
|
+
<HeaderSecondaryMenuButton
|
|
36
|
+
className="mr-5 text-primary-text hover:text-primary-main"
|
|
37
|
+
ariaLabel="Поиск по сайту"
|
|
38
|
+
>
|
|
39
|
+
{LoupeIcon({ 'aria-hidden': true })}
|
|
40
|
+
</HeaderSecondaryMenuButton>
|
|
41
|
+
<HeaderSecondaryMenuButton
|
|
42
|
+
className="mr-5 text-primary-text hover:text-primary-main"
|
|
43
|
+
ariaLabel="Профиль"
|
|
44
|
+
>
|
|
45
|
+
{ProfileIcon({ 'aria-hidden': true })}
|
|
46
|
+
</HeaderSecondaryMenuButton>
|
|
47
|
+
<HeaderSecondaryMenuButton
|
|
48
|
+
className="mr-5 text-secondary-light hover:text-secondary-active min-w-[32px] min-h-[32px]"
|
|
49
|
+
ariaLabel="Дополнительные ссылки"
|
|
50
|
+
>
|
|
51
|
+
{GridIcon({ 'aria-hidden': true })}
|
|
52
|
+
</HeaderSecondaryMenuButton>
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BenefitsBlock } from './BenefitsBlock';
|
|
2
|
+
import { ExchangeRateTile } from './ExchangeRateTile';
|
|
3
|
+
import { Footer } from './Footer/Footer.mobile';
|
|
4
|
+
import { Header } from './Header/index';
|
|
5
|
+
import { MobileAppTile } from './MobileAppTile';
|
|
6
|
+
import { Placeholder } from './Placeholder';
|
|
7
|
+
import { ProductBlock } from './ProductBlock';
|
|
8
|
+
import { ProductGallery } from './ProductGallery';
|
|
9
|
+
import { ProductTile } from './ProductTile';
|
|
10
|
+
import { StepsBlock } from './StepsBlock';
|
|
11
|
+
import { Tile } from './Tile';
|
|
12
|
+
|
|
13
|
+
export const MobileBlocks = {
|
|
14
|
+
Header,
|
|
15
|
+
Footer,
|
|
16
|
+
Placeholder,
|
|
17
|
+
Tile,
|
|
18
|
+
ProductTile,
|
|
19
|
+
ProductBlock,
|
|
20
|
+
StepsBlock,
|
|
21
|
+
BenefitsBlock,
|
|
22
|
+
ProductGallery,
|
|
23
|
+
ExchangeRateTile,
|
|
24
|
+
MobileAppTile,
|
|
25
|
+
};
|
|
@@ -7,8 +7,8 @@ const image: Picture = {
|
|
|
7
7
|
src: 'money-1.png',
|
|
8
8
|
format: 'webp',
|
|
9
9
|
size: {
|
|
10
|
-
width:
|
|
11
|
-
height:
|
|
10
|
+
width: 280,
|
|
11
|
+
height: 280,
|
|
12
12
|
},
|
|
13
13
|
};
|
|
14
14
|
|
|
@@ -70,6 +70,7 @@ export default {
|
|
|
70
70
|
context={context}
|
|
71
71
|
title={'Оплата проходит \nв 180 странах мира'}
|
|
72
72
|
breadcrumbs={[]}
|
|
73
|
+
description="Кредит наличными без залога и поручительства. Потребительский кредит на любые цели. Нужен только паспорт."
|
|
73
74
|
items={[
|
|
74
75
|
'Совершайте любые личные покупки',
|
|
75
76
|
'Используйте корпоративную карту как обычную дебетовую, если вы ИП',
|
package/src/ProductBlock.tsx
CHANGED
|
@@ -2,13 +2,35 @@ import { JSX } from '@redneckz/uni-jsx';
|
|
|
2
2
|
import { ProductBlockInner } from './ProductBlockInner';
|
|
3
3
|
import type { ProductBlockInnerContent } from './ProductBlockInner';
|
|
4
4
|
import type { UniBlockProps } from './types';
|
|
5
|
+
import { Breadcrumb, BreadcrumbProps } from './ui-kit/Breadcrumb';
|
|
6
|
+
import { useLink } from './useLink';
|
|
7
|
+
import { joinList } from './utils/joinList';
|
|
5
8
|
|
|
6
|
-
export interface ProductBlockProps extends ProductBlockInnerContent, UniBlockProps {
|
|
9
|
+
export interface ProductBlockProps extends ProductBlockInnerContent, UniBlockProps {
|
|
10
|
+
breadcrumbs?: BreadcrumbProps[];
|
|
11
|
+
}
|
|
7
12
|
|
|
8
13
|
export const ProductBlock = JSX<ProductBlockProps>((props) => {
|
|
9
|
-
const className = props
|
|
14
|
+
const { context, className, breadcrumbs } = props;
|
|
15
|
+
const router = context.useRouter();
|
|
16
|
+
const { handlerDecorator } = context;
|
|
10
17
|
return (
|
|
11
|
-
<section className={`bg-white
|
|
18
|
+
<section className={`font-sans bg-white pl-12 pr-[7.5rem] py-10 ${className || ''}`}>
|
|
19
|
+
{breadcrumbs?.length ? (
|
|
20
|
+
<div className="text-xs mb-6">
|
|
21
|
+
{joinList(<span className="text-secondary-text mx-2">/</span>)(
|
|
22
|
+
breadcrumbs.map((breadcrumb, i) => (
|
|
23
|
+
<Breadcrumb
|
|
24
|
+
key={String(i)}
|
|
25
|
+
{...useLink(
|
|
26
|
+
{ router, handlerDecorator },
|
|
27
|
+
{ className: 'text-secondary-text', ...breadcrumb },
|
|
28
|
+
)}
|
|
29
|
+
/>
|
|
30
|
+
)),
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
) : null}
|
|
12
34
|
<ProductBlockInner {...props} />
|
|
13
35
|
</section>
|
|
14
36
|
);
|
|
@@ -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,
|
|
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={`
|
|
33
|
-
<div className=
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
),
|
package/src/ProductTile.tsx
CHANGED
|
@@ -1,79 +1,30 @@
|
|
|
1
1
|
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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> = {
|