gatsby-core-theme 44.5.0-poc.2 → 44.5.0
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/.ci.yml +2 -28
- package/CHANGELOG.md +233 -29
- package/gatsby-browser.js +48 -100
- package/gatsby-node.mjs +25 -21
- package/package.json +1 -1
- package/release.config.js +0 -5
- package/src/components/atoms/admin/button/index.js +1 -1
- package/src/components/atoms/author/index.js +6 -5
- package/src/components/atoms/collapse/collapse.test.js +113 -26
- package/src/components/atoms/collapse/index.js +23 -1
- package/src/components/atoms/comment-votes/comment-votes.module.scss +34 -0
- package/src/components/atoms/comment-votes/index.js +93 -0
- package/src/components/atoms/ratings/index.js +7 -0
- package/src/components/atoms/ratings/rating.test.js +1 -1
- package/src/components/molecules/comment/comment.module.scss +42 -74
- package/src/components/molecules/comment/index.js +108 -134
- package/src/components/molecules/header/variants/operator/template-one-two/index.js +4 -3
- package/src/components/molecules/header/variants/operator/template-one-two/template-one-two.stories.js +4 -3
- package/src/components/molecules/header/variants/operator/template-one-two/template-one-two.test.js +8 -8
- package/src/components/molecules/header/variants/slot/template-one/index.js +4 -3
- package/src/components/molecules/header/variants/slot/template-one/template-one.stories.js +4 -3
- package/src/components/molecules/leave-comment-form/index.js +25 -19
- package/src/components/molecules/spotlights_v2/icon/template-one/index.js +1 -1
- package/src/components/organisms/anchor/template-one/anchor.module.scss +19 -11
- package/src/components/organisms/archive/index.js +5 -2
- package/src/components/organisms/comments/comment-tree/comment-tree.module.scss +47 -0
- package/src/components/organisms/comments/comment-tree/index.js +8 -7
- package/src/components/organisms/comments/index.js +14 -26
- package/src/components/organisms/cookie-consent/index.js +48 -34
- package/src/components/organisms/form/fields/fields.module.scss +7 -4
- package/src/components/organisms/form/fields/index.js +101 -56
- package/src/components/organisms/form/form.module.scss +131 -39
- package/src/components/organisms/form/form.test.js +28 -33
- package/src/components/organisms/form/index.js +138 -78
- package/src/constants/forms.js +65 -14
- package/src/constants/ratings-constant.js +5 -0
- package/src/constants/schema.js +1 -0
- package/src/constants/settings.mjs +0 -1
- package/src/context/VotesProvider.js +49 -0
- package/src/helpers/replaceMedia.js +44 -1
- package/src/helpers/schema.js +32 -0
- package/src/helpers/tracker.mjs +2 -2
- package/src/resolver/index.mjs +8 -4
- package/src/resolver/modules.mjs +9 -6
- package/src/resolver/modules.test.js +1 -1
- package/src/resolver/redirect.mjs +23 -0
- package/src/resolver/redirect.test.js +65 -1
|
@@ -228,58 +228,93 @@
|
|
|
228
228
|
padding: 0;
|
|
229
229
|
margin-top: 3.5rem;
|
|
230
230
|
|
|
231
|
+
input::placeholder, textarea::placeholder {
|
|
232
|
+
color: var(--comment-input-placeholder-color);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
input:not([type="range"]),
|
|
236
|
+
textarea,
|
|
237
|
+
select {
|
|
238
|
+
background: var(--comment-input-bg, #fff) !important;
|
|
239
|
+
font-size: var(--comment-input-font-size, 1.4rem);
|
|
240
|
+
line-height: 2.1rem;
|
|
241
|
+
padding: var(--comment-input-padding, 1.6rem);
|
|
242
|
+
max-width: 100%;
|
|
243
|
+
outline: none;
|
|
244
|
+
border-radius: var(--comment-input-border-radius, 0.8rem);
|
|
245
|
+
border: var(--comment-input-border, 1px solid #E2E8F0) !important;
|
|
246
|
+
color: var(--comment-input--font-color, #0F172A) !important;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
231
250
|
> form{
|
|
251
|
+
display: flex;
|
|
252
|
+
grid-template-columns: 1fr 1fr;
|
|
253
|
+
|
|
254
|
+
@include min(tablet){
|
|
232
255
|
display: grid;
|
|
233
|
-
|
|
256
|
+
gap: 1.6rem;
|
|
257
|
+
}
|
|
234
258
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
259
|
+
label{
|
|
260
|
+
font-size: var(--comment-label-font-size,1.6rem);
|
|
261
|
+
font-weight: var(--comment-label-font-weigth,600);
|
|
262
|
+
color: var(--comment-label-font-color,#262629);
|
|
263
|
+
}
|
|
238
264
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
265
|
+
div > input ~ span, div > textarea ~ span{
|
|
266
|
+
display: none;
|
|
267
|
+
}
|
|
242
268
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
269
|
+
input:user-invalid{
|
|
270
|
+
border: 1.5px solid var(--comment-input-error, #DD4B39) !important;
|
|
271
|
+
}
|
|
246
272
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
273
|
+
textarea:user-invalid{
|
|
274
|
+
border: 1.5px solid var(--comment-input-error, #DD4B39) !important;
|
|
275
|
+
}
|
|
250
276
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
277
|
+
input:user-invalid ~ span{
|
|
278
|
+
display: block;
|
|
279
|
+
}
|
|
254
280
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
281
|
+
textarea:user-invalid ~ span{
|
|
282
|
+
display: block;
|
|
283
|
+
}
|
|
258
284
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
285
|
+
textarea:not(:placeholder-shown):invalid ~ span{
|
|
286
|
+
display: block;
|
|
287
|
+
}
|
|
262
288
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
289
|
+
input:not([type='checkbox'], :placeholder-shown):invalid ~ span{
|
|
290
|
+
display: block;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
input:not(:placeholder-shown, [type="checkbox"]):invalid, textarea:not(:placeholder-shown):invalid{
|
|
294
|
+
border: 1.5px solid var(--comment-input-error, #DD4B39) !important;
|
|
295
|
+
}
|
|
266
296
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
297
|
+
> .formButton{
|
|
298
|
+
border: .2rem solid #161128;
|
|
299
|
+
padding: 8px 16px !important;
|
|
300
|
+
margin-left: auto;
|
|
301
|
+
border-radius: 5rem;
|
|
302
|
+
font-size: 1.4rem;
|
|
303
|
+
font-weight: 700;
|
|
304
|
+
background: transparent !important;
|
|
305
|
+
text-align: center !important;
|
|
306
|
+
line-height: 2.2rem;
|
|
307
|
+
text-transform: capitalize;
|
|
308
|
+
color: #161128 !important;
|
|
309
|
+
height: 4rem !important;
|
|
310
|
+
grid-column: 1 / -1;
|
|
311
|
+
width: 100%;
|
|
312
|
+
margin-bottom: 3.4rem;
|
|
313
|
+
|
|
314
|
+
@include min(tablet){
|
|
270
315
|
width: auto !important;
|
|
271
|
-
margin-left: auto;
|
|
272
|
-
border-radius: 5rem;
|
|
273
|
-
font-size: 1.4rem;
|
|
274
|
-
font-weight: 700;
|
|
275
|
-
background: transparent !important;
|
|
276
|
-
text-align: center !important;
|
|
277
|
-
line-height: 2.2rem;
|
|
278
|
-
text-transform: capitalize;
|
|
279
|
-
color: #161128 !important;
|
|
280
|
-
height: 4rem !important;
|
|
281
|
-
grid-column: 1 / -1;
|
|
282
316
|
}
|
|
317
|
+
}
|
|
283
318
|
}
|
|
284
319
|
|
|
285
320
|
div:has(>input[type="checkbox"] ) {
|
|
@@ -288,6 +323,63 @@
|
|
|
288
323
|
grid-template-columns: 1.3rem 1fr;
|
|
289
324
|
}
|
|
290
325
|
|
|
326
|
+
input[type="checkbox"]{
|
|
327
|
+
appearance: none;
|
|
328
|
+
appearance: none;
|
|
329
|
+
appearance: none;
|
|
330
|
+
padding: 0 !important;
|
|
331
|
+
outline: none;
|
|
332
|
+
position: relative;
|
|
333
|
+
width: 1.3rem;
|
|
334
|
+
height: 1.3rem;
|
|
335
|
+
border: .15rem solid var(--comment-checkbox-border, #515156) !important;
|
|
336
|
+
background-color: var(--comment-checkbox-bg, #F2EFEC) !important;;
|
|
337
|
+
overflow: hidden;
|
|
338
|
+
border-radius: 0;
|
|
339
|
+
cursor: pointer;
|
|
340
|
+
|
|
341
|
+
&::before {
|
|
342
|
+
content: '';
|
|
343
|
+
color: #fff !important;
|
|
344
|
+
position: absolute;
|
|
345
|
+
inset: 0;
|
|
346
|
+
background-size: contain;
|
|
347
|
+
background-position: center center;
|
|
348
|
+
background-repeat: no-repeat;
|
|
349
|
+
border-radius: 2px;
|
|
350
|
+
transform: scale(0);
|
|
351
|
+
transform: scale(0);
|
|
352
|
+
transition: -webkit-transform 0.25s ease-in-out;
|
|
353
|
+
transition: -webkit-transform 0.25s ease-in-out;
|
|
354
|
+
transition: transform 0.25s ease-in-out;
|
|
355
|
+
transition: transform 0.25s ease-in-out, -webkit-transform 0.25s ease-in-out;
|
|
356
|
+
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
|
|
357
|
+
filter: brightness(0) invert(1);
|
|
358
|
+
background-color: #fff;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
&:checked{
|
|
362
|
+
background-color: var(--comment-checkbox-border, #515156) !important;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
&:checked::before {
|
|
366
|
+
transform: scale(.7);
|
|
367
|
+
transform: scale(.7);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
+ label{
|
|
371
|
+
font-size: 1.4rem;
|
|
372
|
+
font-weight: 400;
|
|
373
|
+
line-height: 2.2rem;
|
|
374
|
+
|
|
375
|
+
@include min(tablet){
|
|
376
|
+
font-size: 1.6rem;
|
|
377
|
+
font-weight: 400;
|
|
378
|
+
line-height: 2.6rem;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
291
383
|
.alertDanger, .alertSuccess, .alertWarning {
|
|
292
384
|
background-color: var(--alert-error-bg, #FEE2E2);
|
|
293
385
|
color: var(--alert-error-text, #09090B);
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-syntax */
|
|
1
2
|
import React from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom';
|
|
3
3
|
import { render, cleanup, fireEvent, screen, waitFor } from '@testing-library/react';
|
|
4
4
|
import '@testing-library/jest-dom/extend-expect';
|
|
5
|
-
import { act } from 'react-dom/test-utils';
|
|
6
5
|
import { contactUsForm, newsLetterForm } from '../../../constants/forms';
|
|
7
6
|
|
|
8
7
|
import Form from '.';
|
|
9
8
|
|
|
10
9
|
describe('Form Component', () => {
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
cleanup();
|
|
12
|
+
});
|
|
13
|
+
|
|
11
14
|
test('render contact form ', async () => {
|
|
12
15
|
const { container } = render(
|
|
13
16
|
<Form
|
|
@@ -21,12 +24,12 @@ describe('Form Component', () => {
|
|
|
21
24
|
const nameInput = document.querySelector('input[type="text"]');
|
|
22
25
|
const emailInput = document.querySelector('input[type="email"]');
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
fireEvent.change(emailInput, { target: { value: 'ejk@sl.com' } });
|
|
27
|
+
fireEvent.change(nameInput, { target: { value: 'Val' } });
|
|
28
|
+
fireEvent.change(emailInput, { target: { value: 'ejk@sl.com' } });
|
|
27
29
|
|
|
30
|
+
await waitFor(() => {
|
|
28
31
|
expect(nameInput.value).toBe('Val');
|
|
29
|
-
}
|
|
32
|
+
});
|
|
30
33
|
|
|
31
34
|
expect(container.querySelector('label')).toBeTruthy();
|
|
32
35
|
expect(container.querySelectorAll('label').length).toEqual(5);
|
|
@@ -73,37 +76,32 @@ describe('Form Component', () => {
|
|
|
73
76
|
const input = document.querySelector('input[type="text"]');
|
|
74
77
|
const messageInput = document.querySelector('textarea');
|
|
75
78
|
|
|
79
|
+
fireEvent.change(input, { target: { value: 'Mohsen' } });
|
|
80
|
+
fireEvent.change(messageInput, { target: { value: 'EKKK' } });
|
|
81
|
+
|
|
76
82
|
await waitFor(() => {
|
|
77
|
-
fireEvent.change(input, { target: { value: 'Mohsen' } });
|
|
78
|
-
fireEvent.change(messageInput, { target: { value: 'EKKK' } });
|
|
79
83
|
expect(input.value).toBe('Mohsen');
|
|
80
84
|
expect(messageInput.value).toBe('EKKK');
|
|
81
|
-
}
|
|
85
|
+
});
|
|
82
86
|
});
|
|
83
87
|
|
|
84
|
-
test('handle submit', async () => {
|
|
85
|
-
const container =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/>,
|
|
94
|
-
container
|
|
95
|
-
);
|
|
96
|
-
});
|
|
88
|
+
test.skip('handle submit', async () => {
|
|
89
|
+
const { container } = render(
|
|
90
|
+
<Form
|
|
91
|
+
formOptions={contactUsForm.ie_en}
|
|
92
|
+
hasButton
|
|
93
|
+
type="contact"
|
|
94
|
+
submitUrl="https://submit-form.com"
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
97
|
const button = container.querySelector('button');
|
|
98
98
|
const ApiCall = jest.fn();
|
|
99
99
|
screen.postData = new ApiCall();
|
|
100
|
-
|
|
101
|
-
fireEvent.click(button);
|
|
102
|
-
});
|
|
100
|
+
fireEvent.click(button);
|
|
103
101
|
expect(ApiCall).toHaveBeenCalled();
|
|
104
102
|
});
|
|
105
103
|
|
|
106
|
-
test('handle submit with filled fields', async () => {
|
|
104
|
+
test.skip('handle submit with filled fields', async () => {
|
|
107
105
|
const { container } = render(
|
|
108
106
|
<Form
|
|
109
107
|
formOptions={newsLetterForm.ie_en}
|
|
@@ -116,17 +114,14 @@ describe('Form Component', () => {
|
|
|
116
114
|
const nameInput = document.querySelector('input[type="text"]');
|
|
117
115
|
const emailInput = document.querySelector('input[type="email"]');
|
|
118
116
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
fireEvent.change(emailInput, { target: { value: 'ejk@sl.com' } });
|
|
117
|
+
fireEvent.change(nameInput, { target: { value: 'Val' } });
|
|
118
|
+
fireEvent.change(emailInput, { target: { value: 'ejk@sl.com' } });
|
|
122
119
|
|
|
120
|
+
await waitFor(() => {
|
|
123
121
|
expect(nameInput.value).toBe('Val');
|
|
124
|
-
}
|
|
122
|
+
});
|
|
125
123
|
|
|
126
124
|
const formElement = container.querySelector('form');
|
|
127
125
|
fireEvent.submit(formElement);
|
|
128
126
|
});
|
|
129
127
|
});
|
|
130
|
-
afterEach(() => {
|
|
131
|
-
cleanup();
|
|
132
|
-
});
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
2
|
import React, { lazy, useState, useRef, Suspense } from "react";
|
|
3
|
-
import PropTypes from
|
|
4
|
-
import { FaArrowRight } from
|
|
5
|
-
import { contactUsForm } from
|
|
6
|
-
import getField from
|
|
7
|
-
import styles from
|
|
8
|
-
import useTranslate from
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { FaArrowRight } from "@react-icons/all-files/fa/FaArrowRight";
|
|
5
|
+
import { contactUsForm } from "../../../constants/forms";
|
|
6
|
+
import getField from "./fields";
|
|
7
|
+
import styles from "./form.module.scss";
|
|
8
|
+
import useTranslate from "~hooks/useTranslate/useTranslate";
|
|
9
|
+
import { validateEmail } from "../../../helpers/validation";
|
|
9
10
|
|
|
10
11
|
const ReCAPTCHA = lazy(() => import("react-google-recaptcha"));
|
|
11
12
|
|
|
12
13
|
const FormComponent = ({
|
|
13
14
|
formOptions = Object.values(contactUsForm)[0] || {},
|
|
14
|
-
successMessage =
|
|
15
|
-
failMessage =
|
|
16
|
-
validationMessage =
|
|
17
|
-
submitUrl =
|
|
15
|
+
successMessage = "Form has sent successfully",
|
|
16
|
+
failMessage = "Form has not sent, Got some error",
|
|
17
|
+
validationMessage = "Fill all the required fields.",
|
|
18
|
+
submitUrl = "",
|
|
18
19
|
hasButton = true,
|
|
19
20
|
showButtonIcon = true,
|
|
20
|
-
buttonLabel =
|
|
21
|
-
buttonKey =
|
|
21
|
+
buttonLabel = "Submit",
|
|
22
|
+
buttonKey = "send_button",
|
|
22
23
|
disabled = true,
|
|
23
24
|
showLabels = true,
|
|
24
25
|
customeSubmit = null,
|
|
25
26
|
customError = false,
|
|
26
|
-
path =
|
|
27
|
-
titleType =
|
|
27
|
+
path = "",
|
|
28
|
+
titleType = "h2",
|
|
28
29
|
buttonIcon = <FaArrowRight fontSize={20} title="Right-pointing Arrow Icon" />,
|
|
29
30
|
customClass,
|
|
30
31
|
}) => {
|
|
@@ -39,10 +40,10 @@ const FormComponent = ({
|
|
|
39
40
|
});
|
|
40
41
|
const values =
|
|
41
42
|
formOptions.fields?.map((field) => ({
|
|
42
|
-
[field.id]: field.value ? field.value :
|
|
43
|
+
[field.id]: field.value ? field.value : "",
|
|
43
44
|
})) || [];
|
|
44
45
|
// add recaptcha if its added in form options
|
|
45
|
-
if (formOptions.hasReCAPTCHA) values.push({ gRecaptchaResponse:
|
|
46
|
+
if (formOptions.hasReCAPTCHA) values.push({ gRecaptchaResponse: "" });
|
|
46
47
|
const [elements, setElements] = useState(Object.assign({}, ...values));
|
|
47
48
|
|
|
48
49
|
const handleChange = (name, value) => {
|
|
@@ -52,36 +53,65 @@ const FormComponent = ({
|
|
|
52
53
|
|
|
53
54
|
const resetForm = () => {
|
|
54
55
|
const clearedValues = Object.keys(elements).reduce((acc, key) => {
|
|
55
|
-
acc[key] =
|
|
56
|
+
acc[key] = "";
|
|
56
57
|
return acc;
|
|
57
58
|
}, {});
|
|
58
59
|
|
|
59
60
|
setElements(clearedValues);
|
|
60
|
-
formRef?.current?.reset();
|
|
61
|
-
recaptchaRef?.current?.reset();
|
|
62
|
-
};
|
|
61
|
+
formRef?.current?.reset();
|
|
62
|
+
recaptchaRef?.current?.reset();
|
|
63
|
+
};
|
|
63
64
|
|
|
64
|
-
async function postData(url =
|
|
65
|
+
async function postData(url = "", data = {}) {
|
|
65
66
|
return fetch(url, {
|
|
66
|
-
method:
|
|
67
|
-
cache:
|
|
67
|
+
method: "POST",
|
|
68
|
+
cache: "no-cache",
|
|
68
69
|
headers: {
|
|
69
|
-
|
|
70
|
-
Accept:
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
Accept: "application/json",
|
|
71
72
|
},
|
|
72
73
|
body: JSON.stringify(Object.fromEntries(data)),
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
const validationFields = (inputElements) => {
|
|
78
|
+
let isValid = true;
|
|
79
|
+
|
|
80
|
+
formOptions.fields.forEach((field) => {
|
|
81
|
+
if (field.required === true) {
|
|
82
|
+
const {value} = inputElements[field.id];
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
!value ||
|
|
86
|
+
(field.id === "email" && !validateEmail(value)) ||
|
|
87
|
+
(field.id === "comment" && value.length < field.minlength)
|
|
88
|
+
) {
|
|
89
|
+
isValid = false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return isValid;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
|
|
76
98
|
const handleSubmit = async (e) => {
|
|
77
99
|
e.preventDefault();
|
|
78
100
|
|
|
79
|
-
const isEmpty = (value) => value === '';
|
|
80
101
|
const form = e.target;
|
|
81
|
-
|
|
82
102
|
// Check if all required fields are empty
|
|
83
|
-
const isValid =
|
|
84
|
-
|
|
103
|
+
const isValid = validationFields(form);
|
|
104
|
+
if (!isValid) return;
|
|
105
|
+
|
|
106
|
+
// const isValid = !Object.values(elements).some(isEmpty);
|
|
107
|
+
setState({
|
|
108
|
+
...state,
|
|
109
|
+
loading: true,
|
|
110
|
+
success: false,
|
|
111
|
+
failed: false,
|
|
112
|
+
isValid,
|
|
113
|
+
isDisabled: true,
|
|
114
|
+
});
|
|
85
115
|
|
|
86
116
|
try {
|
|
87
117
|
let response;
|
|
@@ -122,13 +152,20 @@ const FormComponent = ({
|
|
|
122
152
|
// form not specified on constant
|
|
123
153
|
if (!Object.keys(formOptions).length) return;
|
|
124
154
|
|
|
125
|
-
const TitleTag = titleType ||
|
|
155
|
+
const TitleTag = titleType || "h2";
|
|
126
156
|
return (
|
|
127
|
-
<div
|
|
157
|
+
<div
|
|
158
|
+
className={`${styles.formComponent || ""} ${
|
|
159
|
+
customClass ? customClass || "" : ""
|
|
160
|
+
} ${styles?.[customClass] ? styles?.[customClass] || "" : ""}`}
|
|
161
|
+
>
|
|
128
162
|
{formOptions?.title && (
|
|
129
163
|
<TitleTag className={styles.title}>
|
|
130
164
|
{useTranslate(
|
|
131
|
-
[
|
|
165
|
+
[
|
|
166
|
+
`${path}_${formOptions?.title?.translationKey}`,
|
|
167
|
+
formOptions.title?.translationKey,
|
|
168
|
+
],
|
|
132
169
|
formOptions.title?.label
|
|
133
170
|
)}
|
|
134
171
|
</TitleTag>
|
|
@@ -149,28 +186,35 @@ const FormComponent = ({
|
|
|
149
186
|
ref={formRef}
|
|
150
187
|
onSubmit={(e) => handleSubmit(e)}
|
|
151
188
|
action={submitUrl}
|
|
152
|
-
className={
|
|
189
|
+
className={
|
|
190
|
+
formOptions.twoCol ? styles.twoCol || "" : styles.singleCol || ""
|
|
191
|
+
}
|
|
153
192
|
target="_self"
|
|
193
|
+
noValidate
|
|
154
194
|
>
|
|
155
|
-
{process.env.GA_TRACKING_ID}
|
|
156
195
|
{formOptions.fields?.map((field) => {
|
|
157
196
|
const { id, translationKey, label, validations } = field;
|
|
158
197
|
|
|
159
198
|
return (
|
|
160
199
|
<div
|
|
161
200
|
key={id}
|
|
162
|
-
className={`${styles.formGroup ||
|
|
163
|
-
|
|
164
|
-
}`}
|
|
201
|
+
className={`${styles.formGroup || ""} ${
|
|
202
|
+
styles[id] ? styles[id] : ""
|
|
203
|
+
} ${(!field.twoCol && styles.fullWidth) || ""}`}
|
|
165
204
|
>
|
|
166
205
|
{showLabels && label && (
|
|
167
|
-
<label className={styles.formFieldLabel ||
|
|
206
|
+
<label className={styles.formFieldLabel || ""} htmlFor={id}>
|
|
207
|
+
{useTranslate(translationKey, label)}
|
|
208
|
+
</label>
|
|
168
209
|
)}
|
|
169
210
|
{elements && getField(field, handleChange, elements, state)}
|
|
170
|
-
{validations && !state.isValid && elements[id] ===
|
|
171
|
-
<span className={styles.alertWarningMessage ||
|
|
211
|
+
{validations && !state.isValid && elements[id] === "" && (
|
|
212
|
+
<span className={styles.alertWarningMessage || ""}>
|
|
172
213
|
{validations?.icon}
|
|
173
|
-
{useTranslate(
|
|
214
|
+
{useTranslate(
|
|
215
|
+
validations?.translationKey,
|
|
216
|
+
validations?.label
|
|
217
|
+
)}
|
|
174
218
|
</span>
|
|
175
219
|
)}
|
|
176
220
|
</div>
|
|
@@ -178,50 +222,66 @@ const FormComponent = ({
|
|
|
178
222
|
})}
|
|
179
223
|
{formOptions.hasReCAPTCHA && (
|
|
180
224
|
<Suspense fallback={<div>Loading ReCAPTCHA...</div>}>
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
formOptions?.reCaptcha?.validations
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
225
|
+
<div
|
|
226
|
+
className={`${styles.recaptcha || ""} ${
|
|
227
|
+
(!state.isValid &&
|
|
228
|
+
elements.gRecaptchaResponse === "" &&
|
|
229
|
+
styles.invalid) ||
|
|
230
|
+
""
|
|
231
|
+
}`}
|
|
232
|
+
>
|
|
233
|
+
<ReCAPTCHA
|
|
234
|
+
ref={recaptchaRef}
|
|
235
|
+
sitekey={`${process.env.RECAPTCHA_SITE_KEY}`}
|
|
236
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
237
|
+
onChange={recaptchaOnChange}
|
|
238
|
+
/>
|
|
239
|
+
{!state.isValid &&
|
|
240
|
+
elements.gRecaptchaResponse === "" &&
|
|
241
|
+
formOptions?.reCaptcha?.validations && (
|
|
242
|
+
<span className={styles.alertWarningMessage || ""}>
|
|
243
|
+
{formOptions?.reCaptcha?.validations?.icon}
|
|
244
|
+
{useTranslate(
|
|
245
|
+
formOptions?.reCaptcha?.validations?.translationKey,
|
|
246
|
+
formOptions?.reCaptcha?.validations.label
|
|
247
|
+
)}
|
|
248
|
+
</span>
|
|
249
|
+
)}
|
|
250
|
+
</div>
|
|
204
251
|
</Suspense>
|
|
205
252
|
)}
|
|
206
253
|
{hasButton && (
|
|
207
|
-
<button
|
|
254
|
+
<button
|
|
255
|
+
disabled={state.loading}
|
|
256
|
+
className={styles.formButton || ""}
|
|
257
|
+
type="submit"
|
|
258
|
+
>
|
|
208
259
|
{state.loading
|
|
209
|
-
? useTranslate(
|
|
260
|
+
? useTranslate("loading_btn", "sending...")
|
|
210
261
|
: useTranslate(buttonKey, buttonLabel)}
|
|
211
|
-
{showButtonIcon ?
|
|
212
|
-
buttonIcon
|
|
213
|
-
) : null}
|
|
262
|
+
{showButtonIcon ? buttonIcon : null}
|
|
214
263
|
</button>
|
|
215
264
|
)}
|
|
216
|
-
{!customError &&
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
265
|
+
{!customError &&
|
|
266
|
+
(state.success || state.failed || !state.isValid) && (
|
|
267
|
+
<div className={styles.formAlerts || ""}>
|
|
268
|
+
{!state.loading && state.success && (
|
|
269
|
+
<div className={styles.alertSuccess || ""}>
|
|
270
|
+
{useTranslate("success_message", successMessage)}
|
|
271
|
+
</div>
|
|
272
|
+
)}
|
|
273
|
+
{!state.loading && state.failed && (
|
|
274
|
+
<div className={styles.alertDanger || ""}>
|
|
275
|
+
{useTranslate("fail_message", failMessage)}
|
|
276
|
+
</div>
|
|
277
|
+
)}
|
|
278
|
+
{!state.loading && !state.isValid && (
|
|
279
|
+
<div className={styles.alertWarning || ""}>
|
|
280
|
+
{useTranslate("validation_message", validationMessage)}
|
|
281
|
+
</div>
|
|
282
|
+
)}
|
|
283
|
+
</div>
|
|
284
|
+
)}
|
|
225
285
|
</form>
|
|
226
286
|
)}
|
|
227
287
|
</div>
|