@redneckz/wildless-cms-uni-blocks 0.2.46 → 0.2.49
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/README.md +3 -0
- package/dist/BenefitsBlock.d.ts +2 -2
- package/dist/Blocks.d.ts +15 -0
- package/dist/Blocks.js +13 -7
- package/dist/Blocks.js.map +1 -1
- package/dist/ContentPage.d.ts +2 -2
- package/dist/ContentPage.js +3 -3
- package/dist/ContentPage.js.map +1 -1
- package/dist/ContentPageContext.d.ts +6 -3
- package/dist/ExchangeRateTile.d.ts +7 -0
- package/dist/ExchangeRateTile.js +32 -0
- package/dist/ExchangeRateTile.js.map +1 -0
- package/dist/Footer/Contacts.d.ts +2 -2
- package/dist/Footer/Footer.d.ts +3 -4
- package/dist/Footer/Footer.js.map +1 -1
- package/dist/Footer/FooterLink.d.ts +2 -2
- package/dist/Footer/Sitemap.d.ts +2 -2
- package/dist/Footer/Sitemap.js +8 -5
- package/dist/Footer/Sitemap.js.map +1 -1
- package/dist/Footer/SocialMedia.d.ts +2 -2
- package/dist/Footer/SocialMedia.js +5 -5
- package/dist/Footer/SocialMedia.js.map +1 -1
- package/dist/Footer/index.d.ts +1 -1
- package/dist/Header/Header.d.ts +2 -2
- package/dist/Header/Header.js +3 -2
- package/dist/Header/Header.js.map +1 -1
- package/dist/Icons/DollarIcon.d.ts +1 -0
- package/dist/Icons/DollarIcon.js +6 -0
- package/dist/Icons/DollarIcon.js.map +1 -0
- package/dist/Icons/EuroIcon.d.ts +1 -0
- package/dist/Icons/EuroIcon.js +6 -0
- package/dist/Icons/EuroIcon.js.map +1 -0
- package/dist/Icons/index.d.ts +17 -16
- package/dist/Icons/index.js +26 -22
- package/dist/Icons/index.js.map +1 -1
- package/dist/Img.js +1 -1
- package/dist/Img.js.map +1 -1
- package/dist/LikeControl.d.ts +2 -2
- package/dist/LikeControl.js.map +1 -1
- package/dist/MobileAppTile.d.ts +8 -0
- package/dist/MobileAppTile.js +9 -0
- package/dist/MobileAppTile.js.map +1 -0
- package/dist/Placeholder.d.ts +3 -1
- package/dist/Placeholder.js +9 -2
- package/dist/Placeholder.js.map +1 -1
- package/dist/ProductBlock.d.ts +2 -2
- package/dist/ProductBlockInner.d.ts +2 -2
- package/dist/ProductBlockInner.js +2 -1
- package/dist/ProductBlockInner.js.map +1 -1
- package/dist/ProductGallery.d.ts +2 -2
- package/dist/ProductGallery.js +3 -3
- package/dist/ProductGallery.js.map +1 -1
- package/dist/ProductTile.d.ts +17 -0
- package/dist/ProductTile.js +27 -0
- package/dist/ProductTile.js.map +1 -0
- package/dist/ProjectSettings.d.ts +18 -0
- package/dist/ProjectSettings.js +30 -0
- package/dist/ProjectSettings.js.map +1 -0
- package/dist/StepsBlock.d.ts +2 -2
- package/dist/StepsBlock.js +7 -3
- package/dist/StepsBlock.js.map +1 -1
- package/dist/Tile.d.ts +2 -2
- package/dist/Tile.js +15 -7
- package/dist/Tile.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +3 -10
- package/dist/ui-kit/SearchBar.d.ts +2 -2
- package/dist/ui-kit/SearchBar.js.map +1 -1
- package/dist/useSitemap.d.ts +3 -0
- package/dist/useSitemap.js +16 -0
- package/dist/useSitemap.js.map +1 -0
- package/dist/utils/joinList.d.ts +1 -0
- package/dist/utils/joinList.js +7 -0
- package/dist/utils/joinList.js.map +1 -0
- package/lib/BenefitsBlock.d.ts +2 -2
- package/lib/Blocks.d.ts +15 -0
- package/lib/Blocks.js +10 -4
- package/lib/Blocks.js.map +1 -1
- package/lib/ContentPage.d.ts +2 -2
- package/lib/ContentPage.js +3 -3
- package/lib/ContentPage.js.map +1 -1
- package/lib/ContentPageContext.d.ts +6 -3
- package/lib/ExchangeRateTile.d.ts +7 -0
- package/lib/ExchangeRateTile.js +30 -0
- package/lib/ExchangeRateTile.js.map +1 -0
- package/lib/Footer/Contacts.d.ts +2 -2
- package/lib/Footer/Footer.d.ts +3 -4
- package/lib/Footer/Footer.js.map +1 -1
- package/lib/Footer/FooterLink.d.ts +2 -2
- package/lib/Footer/Sitemap.d.ts +2 -2
- package/lib/Footer/Sitemap.js +8 -5
- package/lib/Footer/Sitemap.js.map +1 -1
- package/lib/Footer/SocialMedia.d.ts +2 -2
- package/lib/Footer/SocialMedia.js +5 -5
- package/lib/Footer/SocialMedia.js.map +1 -1
- package/lib/Footer/index.d.ts +1 -1
- package/lib/Header/Header.d.ts +2 -2
- package/lib/Header/Header.js +3 -2
- package/lib/Header/Header.js.map +1 -1
- package/lib/Icons/DollarIcon.d.ts +1 -0
- package/lib/Icons/DollarIcon.js +3 -0
- package/lib/Icons/DollarIcon.js.map +1 -0
- package/lib/Icons/EuroIcon.d.ts +1 -0
- package/lib/Icons/EuroIcon.js +3 -0
- package/lib/Icons/EuroIcon.js.map +1 -0
- package/lib/Icons/index.d.ts +17 -16
- package/lib/Icons/index.js +17 -16
- package/lib/Icons/index.js.map +1 -1
- package/lib/Img.js +1 -1
- package/lib/Img.js.map +1 -1
- package/lib/LikeControl.d.ts +2 -2
- package/lib/LikeControl.js.map +1 -1
- package/lib/MobileAppTile.d.ts +8 -0
- package/lib/MobileAppTile.js +7 -0
- package/lib/MobileAppTile.js.map +1 -0
- package/lib/Placeholder.d.ts +3 -1
- package/lib/Placeholder.js +9 -2
- package/lib/Placeholder.js.map +1 -1
- package/lib/ProductBlock.d.ts +2 -2
- package/lib/ProductBlockInner.d.ts +2 -2
- package/lib/ProductBlockInner.js +2 -1
- package/lib/ProductBlockInner.js.map +1 -1
- package/lib/ProductGallery.d.ts +2 -2
- package/lib/ProductGallery.js +3 -3
- package/lib/ProductGallery.js.map +1 -1
- package/lib/ProductTile.d.ts +17 -0
- package/lib/ProductTile.js +25 -0
- package/lib/ProductTile.js.map +1 -0
- package/lib/ProjectSettings.d.ts +18 -0
- package/lib/ProjectSettings.js +28 -0
- package/lib/ProjectSettings.js.map +1 -0
- package/lib/StepsBlock.d.ts +2 -2
- package/lib/StepsBlock.js +7 -3
- package/lib/StepsBlock.js.map +1 -1
- package/lib/Tile.d.ts +2 -2
- package/lib/Tile.js +15 -7
- package/lib/Tile.js.map +1 -1
- package/lib/common.css +1 -1
- package/lib/index.d.ts +6 -3
- package/lib/index.js +4 -2
- package/lib/index.js.map +1 -1
- package/lib/types.d.ts +3 -10
- package/lib/ui-kit/SearchBar.d.ts +2 -2
- package/lib/ui-kit/SearchBar.js.map +1 -1
- package/lib/useSitemap.d.ts +3 -0
- package/lib/useSitemap.js +13 -0
- package/lib/useSitemap.js.map +1 -0
- package/lib/utils/joinList.d.ts +1 -0
- package/lib/utils/joinList.js +4 -0
- package/lib/utils/joinList.js.map +1 -0
- package/package.json +3 -2
- package/src/BenefitsBlock.fixture.tsx +34 -0
- package/src/BenefitsBlock.tsx +45 -0
- package/src/Blocks.ts +39 -0
- package/src/ContentPage.fixture.tsx +38 -0
- package/src/ContentPage.page.json +680 -0
- package/src/ContentPage.tsx +83 -0
- package/src/ContentPageContext.tsx +34 -0
- package/src/ContentPageHead.tsx +26 -0
- package/src/ExchangeRateTile.fixture.tsx +11 -0
- package/src/ExchangeRateTile.tsx +80 -0
- package/src/Footer/Contacts.tsx +71 -0
- package/src/Footer/Footer.fixture.tsx +265 -0
- package/src/Footer/Footer.tsx +47 -0
- package/src/Footer/FooterLink.ts +6 -0
- package/src/Footer/HorizontalNavigation.tsx +46 -0
- package/src/Footer/Sitemap.tsx +57 -0
- package/src/Footer/SocialMedia.tsx +46 -0
- package/src/Footer/TextInformation.tsx +50 -0
- package/src/Footer/index.ts +2 -0
- package/src/Header/Header.fixture.tsx +21 -0
- package/src/Header/Header.tsx +55 -0
- package/src/Header/HeaderContent.ts +6 -0
- package/src/Header/HeaderSecondaryMenu.tsx +42 -0
- package/src/Header/HeaderSecondaryMenuButton.tsx +21 -0
- package/src/Header/index.ts +3 -0
- package/src/Header/isSubItemActive.ts +9 -0
- package/src/Header/isTopItemActive.ts +13 -0
- package/src/Icons/ActualBalanceIcon.tsx +202 -0
- package/src/Icons/CalendarIcon.tsx +19 -0
- package/src/Icons/ClockIcon.tsx +212 -0
- package/src/Icons/ComfortableCompIcon.tsx +379 -0
- package/src/Icons/DollarIcon.tsx +12 -0
- package/src/Icons/EmptyWalletIcon.tsx +25 -0
- package/src/Icons/EuroIcon.tsx +12 -0
- package/src/Icons/GridIcon.tsx +9 -0
- package/src/Icons/LoupeIcon.tsx +11 -0
- package/src/Icons/NewDocIcon.tsx +262 -0
- package/src/Icons/OkIcon.tsx +8 -0
- package/src/Icons/PassSendIcon.tsx +250 -0
- package/src/Icons/PercentageSquareIcon.tsx +18 -0
- package/src/Icons/ProfileIcon.tsx +18 -0
- package/src/Icons/SignDocsIcon.tsx +295 -0
- package/src/Icons/TelegramIcon.tsx +8 -0
- package/src/Icons/VKIcon.tsx +10 -0
- package/src/Icons/index.ts +17 -0
- package/src/Img.tsx +22 -0
- package/src/LikeControl.fixture.tsx +5 -0
- package/src/LikeControl.tsx +23 -0
- package/src/MobileAppTile.fixture.tsx +15 -0
- package/src/MobileAppTile.tsx +34 -0
- package/src/Placeholder.fixture.tsx +5 -0
- package/src/Placeholder.tsx +33 -0
- package/src/ProductBlock.fixture.tsx +95 -0
- package/src/ProductBlock.tsx +15 -0
- package/src/ProductBlockInner.tsx +111 -0
- package/src/ProductGallery.fixture.tsx +138 -0
- package/src/ProductGallery.tsx +88 -0
- package/src/ProductTile.fixture.tsx +147 -0
- package/src/ProductTile.tsx +95 -0
- package/src/ProjectSettings.ts +38 -0
- package/src/StepsBlock.fixture.tsx +23 -0
- package/src/StepsBlock.tsx +65 -0
- package/src/Tile.fixture.tsx +124 -0
- package/src/Tile.tsx +89 -0
- package/src/api/LikeAPI.ts +141 -0
- package/src/common.css +39 -0
- package/src/content-page-repository/ContentPageRepository.ts +38 -0
- package/src/content-page-repository/TransformationOptions.ts +4 -0
- package/src/content-page-repository/index.ts +1 -0
- package/src/content-page-repository/mapJSON.spec.ts +28 -0
- package/src/content-page-repository/mapJSON.ts +23 -0
- package/src/content-page-repository/transformContentPage.ts +26 -0
- package/src/content-page-repository/transformMarkdown.ts +10 -0
- package/src/content-page-repository/transformPicture.ts +61 -0
- package/src/cosmos.decorator.tsx +19 -0
- package/src/index.ts +20 -0
- package/src/mergeTopItems.spec.ts +20 -0
- package/src/mergeTopItems.ts +13 -0
- package/src/setup-fixture.ts +49 -0
- package/src/types.ts +94 -0
- package/src/ui-kit/BlockItem.fixture.tsx +5 -0
- package/src/ui-kit/BlockItem.tsx +36 -0
- package/src/ui-kit/Breadcrumb.tsx +26 -0
- package/src/ui-kit/Button.fixture.tsx +113 -0
- package/src/ui-kit/Button.tsx +66 -0
- package/src/ui-kit/HeaderItem.fixture.tsx +8 -0
- package/src/ui-kit/HeaderItem.tsx +25 -0
- package/src/ui-kit/LikeButton.fixture.tsx +6 -0
- package/src/ui-kit/LikeButton.tsx +41 -0
- package/src/ui-kit/Logo.fixture.tsx +5 -0
- package/src/ui-kit/Logo.tsx +35 -0
- package/src/ui-kit/SVG.tsx +32 -0
- package/src/ui-kit/SearchBar.tsx +33 -0
- package/src/ui-kit/TopItem.fixture.tsx +8 -0
- package/src/ui-kit/TopItem.tsx +37 -0
- package/src/useLink.ts +28 -0
- package/src/useSitemap.ts +17 -0
- package/src/utils/joinList.ts +7 -0
- package/src/utils/url.ts +22 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import { EmptyWalletIcon, PercentageSquareIcon, CalendarIcon } from './Icons/index';
|
|
3
|
+
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
|
+
|
|
12
|
+
const ICONS = { EmptyWalletIcon, PercentageSquareIcon, CalendarIcon };
|
|
13
|
+
|
|
14
|
+
export interface ProductBlockInnerContent {
|
|
15
|
+
title?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
breadcrumbs?: BreadcrumbProps[];
|
|
18
|
+
image?: Picture;
|
|
19
|
+
benefits?: Benefit[];
|
|
20
|
+
items?: string[];
|
|
21
|
+
buttons?: ButtonProps[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ProductBlockInnerProps extends ProductBlockInnerContent, UniBlockProps {}
|
|
25
|
+
|
|
26
|
+
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
|
+
|
|
31
|
+
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}
|
|
49
|
+
{title && (
|
|
50
|
+
<h1 className="font-medium text-title-lg m-0 whitespace-pre-wrap max-w-[600px]">
|
|
51
|
+
{title}
|
|
52
|
+
</h1>
|
|
53
|
+
)}
|
|
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}
|
|
74
|
+
</div>
|
|
75
|
+
{image?.src && <Img image={image} className="mt-auto" />}
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
function renderBenefit(benefit: Benefit, i: number) {
|
|
82
|
+
return (
|
|
83
|
+
<div key={String(i)} className="flex gap-4 items-center">
|
|
84
|
+
{benefit.icon && (
|
|
85
|
+
<div className="w-[50px] h-[50px] min-w-[50px] min-h-[50px] bg-main rounded-full p-[10px] box-border">
|
|
86
|
+
{ICONS[benefit.icon as keyof typeof ICONS]?.()}
|
|
87
|
+
</div>
|
|
88
|
+
)}
|
|
89
|
+
<div className="flex gap-1 flex-col h-full">
|
|
90
|
+
<h4 className="font-medium text-xl m-0">{benefit.label}</h4>
|
|
91
|
+
{benefit.description && (
|
|
92
|
+
<div className="font-normal text-sm text-secondary-text">{benefit.description}</div>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
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
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { context } from './setup-fixture';
|
|
2
|
+
|
|
3
|
+
import { ProductGallery } from './ProductGallery';
|
|
4
|
+
import { Picture } from './types';
|
|
5
|
+
|
|
6
|
+
const moneyImage: Picture = {
|
|
7
|
+
src: 'money-1.png',
|
|
8
|
+
format: 'webp',
|
|
9
|
+
size: {
|
|
10
|
+
width: 300,
|
|
11
|
+
height: 300,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const worker: Picture = {
|
|
16
|
+
src: 'worker.png',
|
|
17
|
+
format: 'webp',
|
|
18
|
+
size: {
|
|
19
|
+
width: 300,
|
|
20
|
+
height: 300,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const creditCard: Picture = {
|
|
25
|
+
src: 'credit-card-1.png',
|
|
26
|
+
format: 'webp',
|
|
27
|
+
size: {
|
|
28
|
+
width: 300,
|
|
29
|
+
height: 300,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default (
|
|
34
|
+
<ProductGallery
|
|
35
|
+
context={context}
|
|
36
|
+
slides={[
|
|
37
|
+
{
|
|
38
|
+
nav: {
|
|
39
|
+
title: 'Деньги на любые цели',
|
|
40
|
+
desc: 'Ставка от 12,5% годовых на срок до 5 лет',
|
|
41
|
+
},
|
|
42
|
+
productBlock: {
|
|
43
|
+
title: 'Ставка от 12,5% годовых на срок до 5 лет!»',
|
|
44
|
+
description:
|
|
45
|
+
'Кредит наличными без залога и поручительства. Потребительский кредит на любые цели. Нужен только паспорт.',
|
|
46
|
+
items: [
|
|
47
|
+
'Потребительский кредит по специальной процентной ставке',
|
|
48
|
+
'Получите деньги без залога и поручительства',
|
|
49
|
+
'Кредитный лимит до 5 млн рублей',
|
|
50
|
+
],
|
|
51
|
+
buttons: [
|
|
52
|
+
{
|
|
53
|
+
href: 'https://rshb.ru',
|
|
54
|
+
text: 'Подробнее',
|
|
55
|
+
target: '_blank',
|
|
56
|
+
version: 'primary',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
image: moneyImage,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
nav: {
|
|
64
|
+
title: 'Для людей в возрасте',
|
|
65
|
+
desc: 'Ставка от 12,5% годовых на срок до 3 лет',
|
|
66
|
+
},
|
|
67
|
+
productBlock: {
|
|
68
|
+
title: 'Ставка от 12,5% годовых на срок до 3 лет!»',
|
|
69
|
+
description:
|
|
70
|
+
'Кредит наличными без залога и поручительства. Потребительский кредит на любые цели. Нужен только паспорт.',
|
|
71
|
+
items: [
|
|
72
|
+
'Потребительский кредит по специальной процентной ставке',
|
|
73
|
+
'Получите деньги без залога и поручительства',
|
|
74
|
+
'Кредитный лимит до 5 млн рублей',
|
|
75
|
+
],
|
|
76
|
+
buttons: [
|
|
77
|
+
{
|
|
78
|
+
href: 'https://rshb.ru',
|
|
79
|
+
text: 'Подробнее',
|
|
80
|
+
target: '_blank',
|
|
81
|
+
version: 'primary',
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
image: worker,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
nav: {
|
|
89
|
+
title: 'Выгодно покупать',
|
|
90
|
+
desc: 'Дополнительные бонусные баллы за покупки',
|
|
91
|
+
},
|
|
92
|
+
productBlock: {
|
|
93
|
+
title: 'Дополнительные бонусные баллы за покупки!»',
|
|
94
|
+
description:
|
|
95
|
+
'Кредит наличными без залога и поручительства. Потребительский кредит на любые цели. Нужен только паспорт.',
|
|
96
|
+
items: [
|
|
97
|
+
'Потребительский кредит по специальной процентной ставке',
|
|
98
|
+
'Получите деньги без залога и поручительства',
|
|
99
|
+
'Кредитный лимит до 5 млн рублей',
|
|
100
|
+
],
|
|
101
|
+
buttons: [
|
|
102
|
+
{
|
|
103
|
+
href: 'https://rshb.ru',
|
|
104
|
+
text: 'Подробнее',
|
|
105
|
+
target: '_blank',
|
|
106
|
+
version: 'primary',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
image: creditCard,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
nav: {
|
|
114
|
+
title: 'Карты Unionpay',
|
|
115
|
+
desc: 'Кэшбэк до 20% у партнеров',
|
|
116
|
+
},
|
|
117
|
+
productBlock: {
|
|
118
|
+
title: 'Карты Unionpay»',
|
|
119
|
+
description: 'Кэшбэк до 20% у партнеров',
|
|
120
|
+
items: [
|
|
121
|
+
'Потребительский кредит по специальной процентной ставке',
|
|
122
|
+
'Получите деньги без залога и поручительства',
|
|
123
|
+
'Кредитный лимит до 5 млн рублей',
|
|
124
|
+
],
|
|
125
|
+
buttons: [
|
|
126
|
+
{
|
|
127
|
+
href: 'https://rshb.ru',
|
|
128
|
+
text: 'Подробнее',
|
|
129
|
+
target: '_blank',
|
|
130
|
+
version: 'primary',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
image: creditCard,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
]}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { ProductBlockInnerContent } from './ProductBlockInner';
|
|
3
|
+
import { ProductBlockInner } from './ProductBlockInner';
|
|
4
|
+
import type { UniBlockProps } from './types';
|
|
5
|
+
|
|
6
|
+
interface ProductGalleryNav {
|
|
7
|
+
title: string;
|
|
8
|
+
desc: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ProductSlideContent {
|
|
12
|
+
nav: ProductGalleryNav;
|
|
13
|
+
productBlock: ProductBlockInnerContent;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ProductGalleryContent {
|
|
17
|
+
duration?: number;
|
|
18
|
+
slides?: ProductSlideContent[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ProductGalleryProps extends ProductGalleryContent, UniBlockProps {}
|
|
22
|
+
|
|
23
|
+
export const ProductGallery = JSX<ProductGalleryProps>(
|
|
24
|
+
({ className, context, duration = 0, slides = [] }) => {
|
|
25
|
+
const galleryNav = slides.map((s) => s.nav);
|
|
26
|
+
const galleryBlocks = slides.map((s) => s.productBlock);
|
|
27
|
+
const [activeSlideIndex, setActiveSlideIndex] = context.useState(0);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<section className={`font-sans bg-white overflow-hidden w-100 ${className || ''}`}>
|
|
31
|
+
<div
|
|
32
|
+
className={`flex duration-1000`}
|
|
33
|
+
style={{ transform: `translateX(-${activeSlideIndex}00%)` }}
|
|
34
|
+
role="list"
|
|
35
|
+
>
|
|
36
|
+
{galleryBlocks.map((_, i) => renderProductBlock(_, i, context))}
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div className={`border-t border-solid border-main-divider flex`}>
|
|
40
|
+
{galleryNav.map((slide, i) =>
|
|
41
|
+
renderNavButton({
|
|
42
|
+
slide,
|
|
43
|
+
i,
|
|
44
|
+
activeSlideIndex,
|
|
45
|
+
onClick: () => setActiveSlideIndex(i),
|
|
46
|
+
duration,
|
|
47
|
+
}),
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
</section>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
function renderProductBlock(block: ProductBlockInnerContent, i: number, context) {
|
|
56
|
+
return (
|
|
57
|
+
<section key={String(i)} className="grow-0 shrink-0 basis-full" role="listitem">
|
|
58
|
+
<div className="p-11 pr-[7.5rem] ">
|
|
59
|
+
<ProductBlockInner context={context} {...block} />
|
|
60
|
+
</div>
|
|
61
|
+
</section>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function renderNavButton({ slide, i, activeSlideIndex, onClick, duration }) {
|
|
66
|
+
const isActiveBtn = i === activeSlideIndex;
|
|
67
|
+
const progressBarClassName = isActiveBtn ? 'animate-slide' : '';
|
|
68
|
+
const btnTitleClassName = isActiveBtn ? 'text-primary-text' : 'text-secondary-text';
|
|
69
|
+
return (
|
|
70
|
+
<button
|
|
71
|
+
type="button"
|
|
72
|
+
key={String(i)}
|
|
73
|
+
onClick={onClick}
|
|
74
|
+
className={`group relative overflow-hidden border-0 bg-inherit cursor-pointer text-left px-0 py-4 grow basis-0`}
|
|
75
|
+
>
|
|
76
|
+
<div className="border-0 border-r border-solid border-main-divider px-6">
|
|
77
|
+
<div className={`text-sm font-medium group-hover:text-primary-text ${btnTitleClassName}`}>
|
|
78
|
+
{slide?.title}
|
|
79
|
+
</div>
|
|
80
|
+
<div className="text-xs text-secondary-text">{slide.desc}</div>
|
|
81
|
+
</div>
|
|
82
|
+
<div
|
|
83
|
+
className={`absolute bottom-0 left-0 w-full h-[3px] bg-primary-main -translate-x-full ${progressBarClassName}`}
|
|
84
|
+
style={{ animationDuration: `${duration}s` }}
|
|
85
|
+
></div>
|
|
86
|
+
</button>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { context } from './setup-fixture';
|
|
2
|
+
|
|
3
|
+
import { ProductTile } from './ProductTile';
|
|
4
|
+
import { Picture } from './types';
|
|
5
|
+
|
|
6
|
+
const cardWithMoney: Picture = {
|
|
7
|
+
src: 'card-with-diamond.png',
|
|
8
|
+
alt: 'Кредиты в РСХБ',
|
|
9
|
+
format: 'webp',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const letterWithMoney: Picture = {
|
|
13
|
+
src: 'letter-with-money.png',
|
|
14
|
+
alt: 'Пенсионный кредит в РСХБ',
|
|
15
|
+
format: 'webp',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const building: Picture = {
|
|
19
|
+
src: 'building.png',
|
|
20
|
+
alt: 'Кредит под залог недвижимости в РСХБ',
|
|
21
|
+
format: 'webp',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
credit: (
|
|
26
|
+
<div className="grid grid-cols-12">
|
|
27
|
+
<ProductTile
|
|
28
|
+
context={context}
|
|
29
|
+
className="col-span-6"
|
|
30
|
+
title="Акция! “Кредит На все, что хочется!”"
|
|
31
|
+
description="Потребительский кредит на любые цели, без залога и поручительства"
|
|
32
|
+
benefits={[
|
|
33
|
+
{
|
|
34
|
+
label: 'Кредитный лимит',
|
|
35
|
+
description: 'до 5 млн Р',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
label: 'Процентная ставка',
|
|
39
|
+
description: 'от 12,5%',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
label: 'Срок кредитования',
|
|
43
|
+
description: 'до 5 лет',
|
|
44
|
+
},
|
|
45
|
+
]}
|
|
46
|
+
button={{
|
|
47
|
+
text: 'Подробнее',
|
|
48
|
+
href: '/credit-cards',
|
|
49
|
+
version: 'secondary',
|
|
50
|
+
}}
|
|
51
|
+
image={cardWithMoney}
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
),
|
|
55
|
+
pension: (
|
|
56
|
+
<div className="grid grid-cols-12">
|
|
57
|
+
<ProductTile
|
|
58
|
+
context={context}
|
|
59
|
+
className="col-span-6"
|
|
60
|
+
title="Акция! “Пенсионный кредит”"
|
|
61
|
+
description={'Потребительский кредит на любые цели, без залога и поручительства'}
|
|
62
|
+
benefits={[
|
|
63
|
+
{
|
|
64
|
+
label: 'Кредитный лимит',
|
|
65
|
+
description: 'до 3 млн Р',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
label: 'Процентная ставка',
|
|
69
|
+
description: 'от 12,5%',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
label: 'Срок кредитования',
|
|
73
|
+
description: 'до 3 лет',
|
|
74
|
+
},
|
|
75
|
+
]}
|
|
76
|
+
button={{
|
|
77
|
+
href: 'https://rshb.ru',
|
|
78
|
+
text: 'Подробнее',
|
|
79
|
+
target: '_blank',
|
|
80
|
+
version: 'secondary',
|
|
81
|
+
}}
|
|
82
|
+
image={letterWithMoney}
|
|
83
|
+
/>
|
|
84
|
+
</div>
|
|
85
|
+
),
|
|
86
|
+
'credit-card': (
|
|
87
|
+
<div className="grid grid-cols-12">
|
|
88
|
+
<ProductTile
|
|
89
|
+
context={context}
|
|
90
|
+
className="col-span-8"
|
|
91
|
+
title="Кредит под залог недвижимости"
|
|
92
|
+
description={'Без переоформления залогой недвижимости на банк'}
|
|
93
|
+
benefits={[
|
|
94
|
+
{
|
|
95
|
+
label: 'Кредитный лимит',
|
|
96
|
+
description: 'до 10 млн Р',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: 'Процентная ставка',
|
|
100
|
+
description: 'от 21,5%',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: 'Срок кредитования',
|
|
104
|
+
description: 'до 10 лет',
|
|
105
|
+
},
|
|
106
|
+
]}
|
|
107
|
+
button={{
|
|
108
|
+
href: 'https://rshb.ru',
|
|
109
|
+
text: 'Подробнее',
|
|
110
|
+
target: '_blank',
|
|
111
|
+
version: 'secondary',
|
|
112
|
+
}}
|
|
113
|
+
image={building}
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
),
|
|
117
|
+
'pension-credit': (
|
|
118
|
+
<div className="grid grid-cols-12">
|
|
119
|
+
<ProductTile
|
|
120
|
+
context={context}
|
|
121
|
+
className="col-span-4"
|
|
122
|
+
title="Кредит пенсионный"
|
|
123
|
+
description={'Для людей в возрасте до 75 лет'}
|
|
124
|
+
benefits={[
|
|
125
|
+
{
|
|
126
|
+
label: 'Кредитный лимит',
|
|
127
|
+
description: 'до 3 млн Р',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
label: 'Процентная ставка',
|
|
131
|
+
description: 'от 16,8%',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
label: 'Срок кредитования',
|
|
135
|
+
description: 'до 5 лет',
|
|
136
|
+
},
|
|
137
|
+
]}
|
|
138
|
+
button={{
|
|
139
|
+
href: 'https://rshb.ru',
|
|
140
|
+
text: 'Подробнее',
|
|
141
|
+
target: '_blank',
|
|
142
|
+
version: 'secondary',
|
|
143
|
+
}}
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
),
|
|
147
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
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';
|
|
9
|
+
|
|
10
|
+
export interface ProductTileContent {
|
|
11
|
+
title?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
benefits?: Benefit[];
|
|
14
|
+
image?: Picture;
|
|
15
|
+
button?: ButtonProps;
|
|
16
|
+
version?: BlockVersion;
|
|
17
|
+
}
|
|
18
|
+
|
|
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
|
+
};
|
|
28
|
+
|
|
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
|
+
);
|
|
77
|
+
|
|
78
|
+
function renderBenefitLabel(benefit: Benefit, i: number, version = 'primary') {
|
|
79
|
+
const labelStyleMap: Record<BlockVersion, string> = {
|
|
80
|
+
primary: 'text-secondary-text',
|
|
81
|
+
secondary: 'text-white',
|
|
82
|
+
};
|
|
83
|
+
return (
|
|
84
|
+
<div key={String(i)} className={`text-sm mb-4 ${labelStyleMap[version]}`}>
|
|
85
|
+
{benefit.label}
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
function renderBenefitDescription(benefit: Benefit, i: number) {
|
|
90
|
+
return (
|
|
91
|
+
<div key={String(i)} className="text-xl font-medium mb-2.5">
|
|
92
|
+
{benefit.description}
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface ProjectSettings {
|
|
2
|
+
TEST_BRANCH?: string;
|
|
3
|
+
RC_BRANCH?: string;
|
|
4
|
+
PROD_BRANCH: string;
|
|
5
|
+
FORCED_DRAFT_FLOW: boolean;
|
|
6
|
+
ENABLE_ASSIST?: boolean;
|
|
7
|
+
SITEMAP?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const projectSettings = new (class implements ProjectSettings {
|
|
11
|
+
_: ProjectSettings = {
|
|
12
|
+
PROD_BRANCH: 'master',
|
|
13
|
+
FORCED_DRAFT_FLOW: false,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
setup(_: ProjectSettings) {
|
|
17
|
+
this._ = _;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get TEST_BRANCH() {
|
|
21
|
+
return this._.TEST_BRANCH;
|
|
22
|
+
}
|
|
23
|
+
get RC_BRANCH() {
|
|
24
|
+
return this._.RC_BRANCH;
|
|
25
|
+
}
|
|
26
|
+
get PROD_BRANCH() {
|
|
27
|
+
return this._.PROD_BRANCH;
|
|
28
|
+
}
|
|
29
|
+
get FORCED_DRAFT_FLOW() {
|
|
30
|
+
return this._.FORCED_DRAFT_FLOW;
|
|
31
|
+
}
|
|
32
|
+
get ENABLE_ASSIST() {
|
|
33
|
+
return this._.ENABLE_ASSIST;
|
|
34
|
+
}
|
|
35
|
+
get SITEMAP() {
|
|
36
|
+
return this._.SITEMAP;
|
|
37
|
+
}
|
|
38
|
+
})();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { context } from './setup-fixture';
|
|
2
|
+
import { StepsBlock } from './StepsBlock';
|
|
3
|
+
|
|
4
|
+
export default (
|
|
5
|
+
<StepsBlock
|
|
6
|
+
context={context}
|
|
7
|
+
title="Рассчитайте условия на онлайн-калькуляторе и оставьте заявку на потребительский кредит"
|
|
8
|
+
steps={[
|
|
9
|
+
{
|
|
10
|
+
label: 'Заявка на кредит',
|
|
11
|
+
description: 'Оставьте онлайн-заявку на потребительский кредит',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
label: 'В случае одобрения',
|
|
15
|
+
description: 'Менеджер свяжется с вами и согласует встречу',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
label: 'Получение наличных',
|
|
19
|
+
description: 'Получите наличные в отделении банка',
|
|
20
|
+
},
|
|
21
|
+
]}
|
|
22
|
+
/>
|
|
23
|
+
);
|