@gudhub/ssg-web-components-library 1.0.115 → 1.0.117
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/package.json +1 -1
- package/src/components/get-in-touch-form/get-in-touch-form.html +3 -0
- package/src/components/get-in-touch-form/get-in-touch-form.js +72 -16
- package/src/components/get-in-touch-form/get-in-touch-form.scss +12 -0
- package/src/components/info-table/info-table.html +68 -10
- package/src/components/info-table/info-table.json +39 -20
- package/src/components/info-table/info-table.readme.md +153 -17
- package/src/components/info-table/info-table.scss +96 -27
- package/src/components/liqpay-component/config.js +6 -0
- package/src/components/liqpay-component/liqpay-component.html +91 -0
- package/src/components/liqpay-component/liqpay-component.js +197 -0
- package/src/components/liqpay-component/liqpay-component.json +14 -0
- package/src/components/liqpay-component/liqpay-component.md +0 -0
- package/src/components/liqpay-component/liqpay-component.scss +337 -0
- package/src/components/liqpay-payment-button/config.js +6 -0
- package/src/components/liqpay-payment-button/liqpay-payment-button.html +5 -0
- package/src/components/liqpay-payment-button/liqpay-payment-button.js +23 -0
- package/src/components/liqpay-payment-button/liqpay-payment-button.json +4 -0
- package/src/components/liqpay-payment-button/liqpay-payment-button.md +0 -0
- package/src/components/liqpay-payment-button/liqpay-payment-button.scss +7 -0
- package/src/components/masonry-gallery/masonry-gallery.js +68 -24
- package/src/config.js +2 -0
|
@@ -4,53 +4,90 @@ info-table {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
.top-wrapper {
|
|
7
|
-
|
|
8
|
-
align-items: center;
|
|
7
|
+
margin-bottom: 30px;
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
font-size: 18px;
|
|
9
|
+
.title {
|
|
10
|
+
color: #05183A;
|
|
13
11
|
font-weight: 700;
|
|
14
|
-
|
|
15
|
-
line-height:
|
|
12
|
+
font-size: 30px;
|
|
13
|
+
line-height: 136%;
|
|
14
|
+
letter-spacing: 0%;
|
|
15
|
+
text-align: center;
|
|
16
|
+
text-transform: uppercase;
|
|
17
|
+
margin-bottom: 12px;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
.subtitle {
|
|
21
|
+
font-weight: 400;
|
|
20
22
|
font-size: 18px;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
line-height: 136%;
|
|
24
|
+
letter-spacing: 0%;
|
|
25
|
+
text-align: justify;
|
|
26
|
+
color: #63636F;
|
|
24
27
|
text-align: center;
|
|
25
28
|
}
|
|
26
|
-
|
|
27
|
-
.title {
|
|
28
|
-
margin-bottom: 30px;
|
|
29
|
-
}
|
|
30
29
|
}
|
|
30
|
+
|
|
31
31
|
.block {
|
|
32
|
+
width: 100%;
|
|
32
33
|
margin-bottom: 25px;
|
|
33
34
|
border: 1px solid #C8C8C8;
|
|
35
|
+
border-collapse: collapse;
|
|
36
|
+
table-layout: fixed;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.table-head {
|
|
40
|
+
th {
|
|
41
|
+
width: 50%;
|
|
42
|
+
height: 52px;
|
|
43
|
+
padding: 0 15px;
|
|
44
|
+
border-bottom: 1px solid #C8C8C8;
|
|
45
|
+
vertical-align: middle;
|
|
46
|
+
text-align: center;
|
|
47
|
+
font-size: 18px;
|
|
48
|
+
font-weight: 700;
|
|
49
|
+
color: black;
|
|
50
|
+
line-height: 120%;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
th:not(:last-child) {
|
|
54
|
+
border-right: 1px solid #C8C8C8;
|
|
55
|
+
}
|
|
34
56
|
}
|
|
35
|
-
.item {
|
|
36
|
-
display: flex;
|
|
37
57
|
|
|
58
|
+
.item {
|
|
38
59
|
&:nth-child(even) {
|
|
39
60
|
background-color: #F6F6F6;
|
|
40
61
|
}
|
|
41
|
-
|
|
62
|
+
|
|
63
|
+
td {
|
|
64
|
+
width: 50%;
|
|
65
|
+
height: 48px;
|
|
66
|
+
padding: 0 15px;
|
|
42
67
|
border-bottom: 1px solid #C8C8C8;
|
|
68
|
+
vertical-align: middle;
|
|
69
|
+
text-align: center;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
td:not(:last-child) {
|
|
73
|
+
border-right: 1px solid #C8C8C8;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&:last-child {
|
|
77
|
+
td {
|
|
78
|
+
border-bottom: none;
|
|
79
|
+
}
|
|
43
80
|
}
|
|
44
81
|
|
|
45
82
|
&-title,
|
|
46
83
|
&-price {
|
|
47
|
-
|
|
84
|
+
width: 100%;
|
|
85
|
+
margin: 0;
|
|
86
|
+
font-size: 16px;
|
|
87
|
+
font-weight: 400;
|
|
88
|
+
color: black;
|
|
89
|
+
line-height: 140%;
|
|
48
90
|
text-align: center;
|
|
49
|
-
width: 50%;
|
|
50
|
-
height: 48px;
|
|
51
|
-
}
|
|
52
|
-
&-price {
|
|
53
|
-
border-left: 1px solid #C8C8C8;
|
|
54
91
|
}
|
|
55
92
|
}
|
|
56
93
|
|
|
@@ -70,6 +107,38 @@ info-table {
|
|
|
70
107
|
@media (max-width: 700px) {
|
|
71
108
|
section {
|
|
72
109
|
padding-bottom: 40px;
|
|
73
|
-
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.top-wrapper {
|
|
113
|
+
margin-bottom: 24px;
|
|
114
|
+
|
|
115
|
+
.title {
|
|
116
|
+
font-size: 26px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.subtitle {
|
|
120
|
+
font-size: 16px;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.table-head {
|
|
125
|
+
th {
|
|
126
|
+
height: 48px;
|
|
127
|
+
padding: 0 10px;
|
|
128
|
+
font-size: 16px;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.item {
|
|
133
|
+
td {
|
|
134
|
+
height: 46px;
|
|
135
|
+
padding: 0 10px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
&-title,
|
|
139
|
+
&-price {
|
|
140
|
+
font-size: 15px;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
74
143
|
}
|
|
75
|
-
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<section class="liqpay-component">
|
|
2
|
+
<!-- <div class="liqpay-component__logo">
|
|
3
|
+
<div class="liqpay-component__logo-badge">
|
|
4
|
+
<div class="liqpay-component__logo-badge-text">
|
|
5
|
+
<span class="liqpay-component__logo-gud">GUD</span>
|
|
6
|
+
<span class="liqpay-component__logo-hub">HUB</span>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
<span class="liqpay-component__logo-crm">CRM</span>
|
|
10
|
+
</div> -->
|
|
11
|
+
|
|
12
|
+
<h1 class="liqpay-component__title" data-liqpay-title></h1>
|
|
13
|
+
|
|
14
|
+
<p class="liqpay-component__subtitle" data-liqpay-subtitle></p>
|
|
15
|
+
|
|
16
|
+
<div class="liqpay-component__card">
|
|
17
|
+
<div class="liqpay-component__amount-row">
|
|
18
|
+
<div>
|
|
19
|
+
<p class="liqpay-component__amount-label">Amount</p>
|
|
20
|
+
<p class="liqpay-component__amount" data-liqpay-amount></p>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="liqpay-component__secured-badge">
|
|
23
|
+
<div class="liqpay-component__secured-icon" aria-hidden="true">
|
|
24
|
+
<svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
25
|
+
<polyline points="2,5 4,7.5 8,3" stroke="#ffffff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
|
26
|
+
</svg>
|
|
27
|
+
</div>
|
|
28
|
+
<span class="liqpay-component__secured-text">Secured</span>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="liqpay-component__divider"></div>
|
|
33
|
+
|
|
34
|
+
<div class="liqpay-component__summary">
|
|
35
|
+
<div class="liqpay-component__summary-row">
|
|
36
|
+
<span class="liqpay-component__summary-label">Description</span>
|
|
37
|
+
<strong class="liqpay-component__summary-value" data-liqpay-description></strong>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div class="liqpay-component__summary-row" data-liqpay-order-row>
|
|
41
|
+
<span class="liqpay-component__summary-label">Order ID</span>
|
|
42
|
+
<strong class="liqpay-component__summary-value" data-liqpay-order-id></strong>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<p class="liqpay-component__text" data-liqpay-text></p>
|
|
47
|
+
|
|
48
|
+
<form
|
|
49
|
+
class="liqpay-component__form"
|
|
50
|
+
method="POST"
|
|
51
|
+
accept-charset="utf-8"
|
|
52
|
+
data-liqpay-form
|
|
53
|
+
>
|
|
54
|
+
<input type="hidden" name="data" data-liqpay-data>
|
|
55
|
+
<input type="hidden" name="signature" data-liqpay-signature>
|
|
56
|
+
|
|
57
|
+
<button class="liqpay-component__button" type="button" data-liqpay-button>
|
|
58
|
+
<svg class="liqpay-component__button-icon" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
59
|
+
<rect x="2" y="7" width="14" height="10" rx="2" stroke="#ffffff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
|
60
|
+
<path d="M6 7V5a3 3 0 016 0v2" stroke="#ffffff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
|
61
|
+
</svg>
|
|
62
|
+
<span data-liqpay-button-text></span>
|
|
63
|
+
</button>
|
|
64
|
+
</form>
|
|
65
|
+
|
|
66
|
+
<p class="liqpay-component__error" data-liqpay-error hidden></p>
|
|
67
|
+
|
|
68
|
+
<p class="liqpay-component__powered">
|
|
69
|
+
Powered by <span class="liqpay-component__powered-brand">LiqPay</span>
|
|
70
|
+
</p>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="liqpay-component__security">
|
|
74
|
+
<div class="liqpay-component__security-item">
|
|
75
|
+
<div class="liqpay-component__security-icon" aria-hidden="true">
|
|
76
|
+
<svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
77
|
+
<polyline points="2,5 4,7.5 8,3" stroke="#16a34a" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
|
78
|
+
</svg>
|
|
79
|
+
</div>
|
|
80
|
+
<span>256-bit Encryption</span>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="liqpay-component__security-item">
|
|
83
|
+
<div class="liqpay-component__security-icon" aria-hidden="true">
|
|
84
|
+
<svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
85
|
+
<polyline points="2,5 4,7.5 8,3" stroke="#16a34a" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
|
86
|
+
</svg>
|
|
87
|
+
</div>
|
|
88
|
+
<span>PCI DSS Compliant</span>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</section>
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import html from './liqpay-component.html';
|
|
2
|
+
import './liqpay-component.scss';
|
|
3
|
+
import jsonTemplate from './liqpay-component.json';
|
|
4
|
+
|
|
5
|
+
class LiqpayComponent extends window.GHComponent {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
super.setDefaultData(jsonTemplate);
|
|
9
|
+
|
|
10
|
+
this.isLoading = false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async onServerRender() {
|
|
14
|
+
super.render(html);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
onClientRender() {
|
|
18
|
+
this.initComponent();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
initComponent() {
|
|
22
|
+
this.titleElement = this.querySelector('[data-liqpay-title]');
|
|
23
|
+
this.subtitleElement = this.querySelector('[data-liqpay-subtitle]');
|
|
24
|
+
this.amountElement = this.querySelector('[data-liqpay-amount]');
|
|
25
|
+
this.descriptionElement = this.querySelector('[data-liqpay-description]');
|
|
26
|
+
this.textElement = this.querySelector('[data-liqpay-text]');
|
|
27
|
+
this.orderRowElement = this.querySelector('[data-liqpay-order-row]');
|
|
28
|
+
this.orderIdElement = this.querySelector('[data-liqpay-order-id]');
|
|
29
|
+
this.formElement = this.querySelector('[data-liqpay-form]');
|
|
30
|
+
this.dataInput = this.querySelector('[data-liqpay-data]');
|
|
31
|
+
this.signatureInput = this.querySelector('[data-liqpay-signature]');
|
|
32
|
+
this.buttonElement = this.querySelector('[data-liqpay-button]');
|
|
33
|
+
this.buttonTextElement = this.querySelector('[data-liqpay-button-text]');
|
|
34
|
+
this.errorElement = this.querySelector('[data-liqpay-error]');
|
|
35
|
+
|
|
36
|
+
this.renderPaymentInfo();
|
|
37
|
+
this.bindEvents();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getConfig() {
|
|
41
|
+
return {
|
|
42
|
+
...jsonTemplate,
|
|
43
|
+
...(this.json || {})
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
renderPaymentInfo() {
|
|
48
|
+
const config = this.getConfig();
|
|
49
|
+
|
|
50
|
+
console.log("CONFIG:", config);
|
|
51
|
+
|
|
52
|
+
const amount = Number(config.amount || 0);
|
|
53
|
+
const currency = config.currency || 'UAH';
|
|
54
|
+
|
|
55
|
+
this.titleElement.textContent = config.title || '';
|
|
56
|
+
this.subtitleElement.textContent = config.subtitle || '';
|
|
57
|
+
this.descriptionElement.textContent = config.payment_description || '';
|
|
58
|
+
this.textElement.textContent = config.description || '';
|
|
59
|
+
this.amountElement.textContent = this.formatAmount(amount, currency);
|
|
60
|
+
this.buttonTextElement.textContent = config.button_text || 'Сплатити';
|
|
61
|
+
|
|
62
|
+
if (config.order_id) {
|
|
63
|
+
this.orderIdElement.textContent = config.order_id;
|
|
64
|
+
this.orderRowElement.hidden = false;
|
|
65
|
+
} else {
|
|
66
|
+
this.orderIdElement.textContent = '';
|
|
67
|
+
this.orderRowElement.hidden = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.formElement.action = config.liqpay_checkout_url;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
bindEvents() {
|
|
74
|
+
this.buttonElement.addEventListener('click', () => this.handlePayment());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async handlePayment() {
|
|
78
|
+
if (this.isLoading) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const config = this.getConfig();
|
|
83
|
+
|
|
84
|
+
this.hideError();
|
|
85
|
+
|
|
86
|
+
if (!this.validatePaymentConfig(config)) {
|
|
87
|
+
this.showError('Некоректні дані для оплати.');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
this.setLoading(true);
|
|
93
|
+
|
|
94
|
+
const payment = await this.createPayment(config);
|
|
95
|
+
|
|
96
|
+
this.dataInput.value = payment.data;
|
|
97
|
+
this.signatureInput.value = payment.signature;
|
|
98
|
+
|
|
99
|
+
this.formElement.submit();
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('Failed to create LiqPay payment:', error);
|
|
102
|
+
this.showError(
|
|
103
|
+
config.error_text || 'Не вдалося підготувати оплату. Спробуйте ще раз.'
|
|
104
|
+
);
|
|
105
|
+
} finally {
|
|
106
|
+
this.setLoading(false);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async createPayment(config) {
|
|
111
|
+
const response = await fetch(`https://gudhub-nodejs.ngrok.io:443${config.create_payment_url}`, {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
headers: {
|
|
114
|
+
'Content-Type': 'application/json'
|
|
115
|
+
},
|
|
116
|
+
body: JSON.stringify({
|
|
117
|
+
amount: config.amount,
|
|
118
|
+
currency: config.currency,
|
|
119
|
+
order_id: config.order_id,
|
|
120
|
+
description: config.payment_description
|
|
121
|
+
})
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
const errorText = await response.text();
|
|
126
|
+
|
|
127
|
+
throw new Error(`Payment request failed with status ${response.status}: ${errorText}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const payment = await response.json();
|
|
131
|
+
|
|
132
|
+
if (!payment?.data || !payment?.signature) {
|
|
133
|
+
throw new Error('Invalid payment response');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return payment;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
validatePaymentConfig(config) {
|
|
140
|
+
const amount = Number(config.amount);
|
|
141
|
+
|
|
142
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!config.currency) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!config.order_id) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!config.payment_description) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!config.create_payment_url) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!config.liqpay_checkout_url) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
setLoading(isLoading) {
|
|
170
|
+
const config = this.getConfig();
|
|
171
|
+
|
|
172
|
+
this.isLoading = isLoading;
|
|
173
|
+
this.buttonElement.disabled = isLoading;
|
|
174
|
+
this.buttonTextElement.textContent = isLoading
|
|
175
|
+
? config.loading_text || 'Підготовка оплати...'
|
|
176
|
+
: config.button_text || 'Сплатити';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
showError(message) {
|
|
180
|
+
this.errorElement.textContent = message;
|
|
181
|
+
this.errorElement.hidden = false;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
hideError() {
|
|
185
|
+
this.errorElement.textContent = '';
|
|
186
|
+
this.errorElement.hidden = true;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
formatAmount(amount, currency) {
|
|
190
|
+
return new Intl.NumberFormat('uk-UA', {
|
|
191
|
+
style: 'currency',
|
|
192
|
+
currency
|
|
193
|
+
}).format(amount);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
window.customElements.define('liqpay-component', LiqpayComponent);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Test Payment",
|
|
3
|
+
"subtitle": "Complete your test payment securely with LiqPay.",
|
|
4
|
+
"description": "After clicking the button you will be redirected to the LiqPay secure payment page.",
|
|
5
|
+
"amount": 1,
|
|
6
|
+
"currency": "UAH",
|
|
7
|
+
"order_id": "test-order-001",
|
|
8
|
+
"payment_description": "Test LiqPay payment",
|
|
9
|
+
"button_text": "Сплатити",
|
|
10
|
+
"loading_text": "Підготовка оплати...",
|
|
11
|
+
"error_text": "Не вдалося підготувати оплату. Спробуйте ще раз.",
|
|
12
|
+
"create_payment_url": "/liqpay/create-payment",
|
|
13
|
+
"liqpay_checkout_url": "https://www.liqpay.ua/api/3/checkout"
|
|
14
|
+
}
|
|
File without changes
|