umwd-components 0.1.69 → 0.1.71
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/cjs/components/ContactForm.js +43 -16
- package/dist/cjs/components/Page.js +6 -0
- package/dist/cjs/components/TextImageSection.js +1 -1
- package/dist/cjs/components/WhatsAppClickToChatButton.js +77 -0
- package/dist/cjs/index.js +2 -0
- package/dist/esm/components/ContactForm.js +44 -17
- package/dist/esm/components/Page.js +6 -0
- package/dist/esm/components/TextImageSection.js +1 -1
- package/dist/esm/components/WhatsAppClickToChatButton.js +73 -0
- package/dist/esm/index.js +1 -0
- package/package.json +2 -1
- package/src/components/ContactForm.tsx +179 -0
- package/src/components/Page.js +4 -0
- package/src/components/TextImageSection.tsx +1 -1
- package/src/components/WhatsAppClickToChatButton.tsx +72 -0
- package/src/index.js +2 -1
- package/src/stories/Page.stories.js +5 -0
- package/src/stories/WhatsAppClickToChatButton.stories.js +69 -0
- package/src/components/ContactForm.js +0 -131
|
@@ -10,11 +10,16 @@
|
|
|
10
10
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
11
11
|
|
|
12
12
|
var React = require('react');
|
|
13
|
-
require('prop-types');
|
|
14
13
|
var material = require('@mui/material');
|
|
15
14
|
var isEmail = require('validator/lib/isEmail');
|
|
16
15
|
|
|
17
16
|
function ContactForm(_ref) {
|
|
17
|
+
let {
|
|
18
|
+
data
|
|
19
|
+
} = _ref;
|
|
20
|
+
const {
|
|
21
|
+
maxWidth = "lg"
|
|
22
|
+
} = data;
|
|
18
23
|
const [formValues, setFormValues] = React.useState({
|
|
19
24
|
name: "",
|
|
20
25
|
email: "",
|
|
@@ -23,14 +28,24 @@ function ContactForm(_ref) {
|
|
|
23
28
|
});
|
|
24
29
|
const [formErrors, setFormErrors] = React.useState({});
|
|
25
30
|
const handleBlur = e => {
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
const {
|
|
32
|
+
id
|
|
33
|
+
} = e.target;
|
|
28
34
|
const errors = validate(formValues);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
if (errors[id]) {
|
|
36
|
+
setFormErrors(prevErrors => ({
|
|
37
|
+
...prevErrors,
|
|
38
|
+
[id]: errors[id]
|
|
39
|
+
}));
|
|
40
|
+
} else {
|
|
41
|
+
setFormErrors(prevErrors => {
|
|
42
|
+
const updatedErrors = {
|
|
43
|
+
...prevErrors
|
|
44
|
+
};
|
|
45
|
+
delete updatedErrors[id];
|
|
46
|
+
return updatedErrors;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
34
49
|
};
|
|
35
50
|
const handleChange = e => {
|
|
36
51
|
const {
|
|
@@ -41,10 +56,14 @@ function ContactForm(_ref) {
|
|
|
41
56
|
...formValues,
|
|
42
57
|
[id]: value
|
|
43
58
|
});
|
|
44
|
-
console.log("formValues", formValues);
|
|
45
59
|
};
|
|
46
60
|
const handleClear = () => {
|
|
47
|
-
setFormValues({
|
|
61
|
+
setFormValues({
|
|
62
|
+
name: "",
|
|
63
|
+
email: "",
|
|
64
|
+
subject: "",
|
|
65
|
+
message: ""
|
|
66
|
+
});
|
|
48
67
|
};
|
|
49
68
|
const handleSendCallback = () => {
|
|
50
69
|
console.log("Send callback");
|
|
@@ -69,7 +88,16 @@ function ContactForm(_ref) {
|
|
|
69
88
|
console.log("errors from validate", errors);
|
|
70
89
|
return errors;
|
|
71
90
|
};
|
|
72
|
-
return /*#__PURE__*/React.createElement(material.
|
|
91
|
+
return /*#__PURE__*/React.createElement(material.Container, {
|
|
92
|
+
maxWidth: maxWidth || "lg",
|
|
93
|
+
sx: {
|
|
94
|
+
my: 1
|
|
95
|
+
}
|
|
96
|
+
}, /*#__PURE__*/React.createElement(material.Paper, {
|
|
97
|
+
sx: {
|
|
98
|
+
p: 2
|
|
99
|
+
}
|
|
100
|
+
}, /*#__PURE__*/React.createElement(material.Stack, {
|
|
73
101
|
spacing: 2
|
|
74
102
|
}, /*#__PURE__*/React.createElement(material.Typography, {
|
|
75
103
|
variant: "h6",
|
|
@@ -82,8 +110,8 @@ function ContactForm(_ref) {
|
|
|
82
110
|
label: "Name",
|
|
83
111
|
value: formValues.name,
|
|
84
112
|
variant: "outlined",
|
|
85
|
-
onBlur:
|
|
86
|
-
onChange:
|
|
113
|
+
onBlur: handleBlur,
|
|
114
|
+
onChange: handleChange,
|
|
87
115
|
error: formErrors.name != undefined ? true : false,
|
|
88
116
|
helperText: formErrors.name
|
|
89
117
|
}), /*#__PURE__*/React.createElement(material.TextField, {
|
|
@@ -122,13 +150,12 @@ function ContactForm(_ref) {
|
|
|
122
150
|
}, /*#__PURE__*/React.createElement(material.Button, {
|
|
123
151
|
variant: "outlined",
|
|
124
152
|
color: "primary",
|
|
125
|
-
onClick:
|
|
153
|
+
onClick: handleClear
|
|
126
154
|
}, "Clear"), /*#__PURE__*/React.createElement(material.Button, {
|
|
127
155
|
variant: "contained",
|
|
128
156
|
color: "primary",
|
|
129
157
|
onClick: handleSendCallback
|
|
130
|
-
}, "Send")));
|
|
158
|
+
}, "Send")))));
|
|
131
159
|
}
|
|
132
|
-
ContactForm.propTypes = {};
|
|
133
160
|
|
|
134
161
|
exports.default = ContactForm;
|
|
@@ -16,6 +16,7 @@ var HeroSection = require('./HeroSection.js');
|
|
|
16
16
|
var FeaturesSection = require('./FeaturesSection.js');
|
|
17
17
|
var IconSection = require('./IconSection.js');
|
|
18
18
|
var material = require('@mui/material');
|
|
19
|
+
var ContactForm = require('./ContactForm.js');
|
|
19
20
|
|
|
20
21
|
function blockRenderer(block) {
|
|
21
22
|
switch (block.__component) {
|
|
@@ -29,6 +30,11 @@ function blockRenderer(block) {
|
|
|
29
30
|
key: block.id,
|
|
30
31
|
data: block
|
|
31
32
|
});
|
|
33
|
+
case "layout.contact-section":
|
|
34
|
+
return /*#__PURE__*/React.createElement(ContactForm.default, {
|
|
35
|
+
key: block.id,
|
|
36
|
+
data: block
|
|
37
|
+
});
|
|
32
38
|
case "layout.text-image-section":
|
|
33
39
|
return /*#__PURE__*/React.createElement(TextImageSection.default, {
|
|
34
40
|
key: block.id,
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UMWD-Components
|
|
3
|
+
* @copyright Jelle Paulus
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
|
+
|
|
11
|
+
var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
|
|
12
|
+
var React = require('react');
|
|
13
|
+
var material = require('@mui/material');
|
|
14
|
+
|
|
15
|
+
function WhatsAppClickToChatButton(_ref) {
|
|
16
|
+
let {
|
|
17
|
+
data
|
|
18
|
+
} = _ref;
|
|
19
|
+
const {
|
|
20
|
+
phoneNumber,
|
|
21
|
+
text,
|
|
22
|
+
message,
|
|
23
|
+
color,
|
|
24
|
+
round,
|
|
25
|
+
sx
|
|
26
|
+
} = data;
|
|
27
|
+
const theme = material.useTheme();
|
|
28
|
+
const formattedPhoneNumber = phoneNumber.replace(/\D/g, "");
|
|
29
|
+
const handleClick = () => {
|
|
30
|
+
let url = "https://wa.me/".concat(formattedPhoneNumber);
|
|
31
|
+
if (message) {
|
|
32
|
+
const formattedMessage = encodeURIComponent(message);
|
|
33
|
+
url = "https://wa.me/".concat(formattedPhoneNumber, "?text=").concat(formattedMessage);
|
|
34
|
+
}
|
|
35
|
+
window.open(url, "_blank");
|
|
36
|
+
};
|
|
37
|
+
return /*#__PURE__*/React.createElement(material.Button, {
|
|
38
|
+
variant: "contained",
|
|
39
|
+
onClick: handleClick,
|
|
40
|
+
startIcon: /*#__PURE__*/React.createElement(material.SvgIcon, {
|
|
41
|
+
sx: [round === true && {
|
|
42
|
+
m: 0,
|
|
43
|
+
p: 0
|
|
44
|
+
}]
|
|
45
|
+
}, /*#__PURE__*/React.createElement(WhatsAppIcon, {
|
|
46
|
+
fill: color || theme.palette.primary.contrastText
|
|
47
|
+
})),
|
|
48
|
+
sx: [{
|
|
49
|
+
...sx
|
|
50
|
+
}, round === true && {
|
|
51
|
+
display: "grid",
|
|
52
|
+
justifyContent: "center",
|
|
53
|
+
alignItems: "center",
|
|
54
|
+
borderRadius: "50%",
|
|
55
|
+
p: 1,
|
|
56
|
+
minWidth: "unset",
|
|
57
|
+
".MuiButton-startIcon": {
|
|
58
|
+
m: 0,
|
|
59
|
+
p: 0
|
|
60
|
+
}
|
|
61
|
+
}]
|
|
62
|
+
}, !round && (text || "Click to WhatsApp"));
|
|
63
|
+
}
|
|
64
|
+
function WhatsAppIcon(props) {
|
|
65
|
+
return /*#__PURE__*/React.createElement("svg", _rollupPluginBabelHelpers.extends({
|
|
66
|
+
viewBox: "0 0 30.667 30.667"
|
|
67
|
+
}, props), /*#__PURE__*/React.createElement("g", {
|
|
68
|
+
"stroke-width": "0"
|
|
69
|
+
}), /*#__PURE__*/React.createElement("g", {
|
|
70
|
+
"stroke-linecap": "round",
|
|
71
|
+
"stroke-linejoin": "round"
|
|
72
|
+
}), /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
|
|
73
|
+
d: "M30.667,14.939c0,8.25-6.74,14.938-15.056,14.938c-2.639,0-5.118-0.675-7.276-1.857L0,30.667l2.717-8.017 c-1.37-2.25-2.159-4.892-2.159-7.712C0.559,6.688,7.297,0,15.613,0C23.928,0.002,30.667,6.689,30.667,14.939z M15.61,2.382 c-6.979,0-12.656,5.634-12.656,12.56c0,2.748,0.896,5.292,2.411,7.362l-1.58,4.663l4.862-1.545c2,1.312,4.393,2.076,6.963,2.076 c6.979,0,12.658-5.633,12.658-12.559C28.27,8.016,22.59,2.382,15.61,2.382z M23.214,18.38c-0.094-0.151-0.34-0.243-0.708-0.427 c-0.367-0.184-2.184-1.069-2.521-1.189c-0.34-0.123-0.586-0.185-0.832,0.182c-0.243,0.367-0.951,1.191-1.168,1.437 c-0.215,0.245-0.43,0.276-0.799,0.095c-0.369-0.186-1.559-0.57-2.969-1.817c-1.097-0.972-1.838-2.169-2.052-2.536 c-0.217-0.366-0.022-0.564,0.161-0.746c0.165-0.165,0.369-0.428,0.554-0.643c0.185-0.213,0.246-0.364,0.369-0.609 c0.121-0.245,0.06-0.458-0.031-0.643c-0.092-0.184-0.829-1.984-1.138-2.717c-0.307-0.732-0.614-0.611-0.83-0.611 c-0.215,0-0.461-0.03-0.707-0.03S9.897,8.215,9.56,8.582s-1.291,1.252-1.291,3.054c0,1.804,1.321,3.543,1.506,3.787 c0.186,0.243,2.554,4.062,6.305,5.528c3.753,1.465,3.753,0.976,4.429,0.914c0.678-0.062,2.184-0.885,2.49-1.739 C23.307,19.268,23.307,18.533,23.214,18.38z"
|
|
74
|
+
})));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
exports.default = WhatsAppClickToChatButton;
|
package/dist/cjs/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var Footer = require('./components/Footer.js');
|
|
|
15
15
|
var ContactForm = require('./components/ContactForm.js');
|
|
16
16
|
var WebsitePlaceholder = require('./components/WebsitePlaceholder.js');
|
|
17
17
|
var BulletList = require('./components/BulletList.js');
|
|
18
|
+
var WhatsAppClickToChatButton = require('./components/WhatsAppClickToChatButton.js');
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
|
|
@@ -27,3 +28,4 @@ exports.Footer = Footer.default;
|
|
|
27
28
|
exports.ContactForm = ContactForm.default;
|
|
28
29
|
exports.WebsitePlaceholder = WebsitePlaceholder.default;
|
|
29
30
|
exports.BulletList = BulletList.default;
|
|
31
|
+
exports.WhatsAppClickToChatButton = WhatsAppClickToChatButton.default;
|
|
@@ -6,11 +6,16 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import React from 'react';
|
|
9
|
-
import '
|
|
10
|
-
import { Stack, Typography, TextField, Button } from '@mui/material';
|
|
9
|
+
import { Container, Paper, Stack, Typography, TextField, Button } from '@mui/material';
|
|
11
10
|
import isEmail from 'validator/lib/isEmail';
|
|
12
11
|
|
|
13
12
|
function ContactForm(_ref) {
|
|
13
|
+
let {
|
|
14
|
+
data
|
|
15
|
+
} = _ref;
|
|
16
|
+
const {
|
|
17
|
+
maxWidth = "lg"
|
|
18
|
+
} = data;
|
|
14
19
|
const [formValues, setFormValues] = React.useState({
|
|
15
20
|
name: "",
|
|
16
21
|
email: "",
|
|
@@ -19,14 +24,24 @@ function ContactForm(_ref) {
|
|
|
19
24
|
});
|
|
20
25
|
const [formErrors, setFormErrors] = React.useState({});
|
|
21
26
|
const handleBlur = e => {
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
const {
|
|
28
|
+
id
|
|
29
|
+
} = e.target;
|
|
24
30
|
const errors = validate(formValues);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
if (errors[id]) {
|
|
32
|
+
setFormErrors(prevErrors => ({
|
|
33
|
+
...prevErrors,
|
|
34
|
+
[id]: errors[id]
|
|
35
|
+
}));
|
|
36
|
+
} else {
|
|
37
|
+
setFormErrors(prevErrors => {
|
|
38
|
+
const updatedErrors = {
|
|
39
|
+
...prevErrors
|
|
40
|
+
};
|
|
41
|
+
delete updatedErrors[id];
|
|
42
|
+
return updatedErrors;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
30
45
|
};
|
|
31
46
|
const handleChange = e => {
|
|
32
47
|
const {
|
|
@@ -37,10 +52,14 @@ function ContactForm(_ref) {
|
|
|
37
52
|
...formValues,
|
|
38
53
|
[id]: value
|
|
39
54
|
});
|
|
40
|
-
console.log("formValues", formValues);
|
|
41
55
|
};
|
|
42
56
|
const handleClear = () => {
|
|
43
|
-
setFormValues({
|
|
57
|
+
setFormValues({
|
|
58
|
+
name: "",
|
|
59
|
+
email: "",
|
|
60
|
+
subject: "",
|
|
61
|
+
message: ""
|
|
62
|
+
});
|
|
44
63
|
};
|
|
45
64
|
const handleSendCallback = () => {
|
|
46
65
|
console.log("Send callback");
|
|
@@ -65,7 +84,16 @@ function ContactForm(_ref) {
|
|
|
65
84
|
console.log("errors from validate", errors);
|
|
66
85
|
return errors;
|
|
67
86
|
};
|
|
68
|
-
return /*#__PURE__*/React.createElement(
|
|
87
|
+
return /*#__PURE__*/React.createElement(Container, {
|
|
88
|
+
maxWidth: maxWidth || "lg",
|
|
89
|
+
sx: {
|
|
90
|
+
my: 1
|
|
91
|
+
}
|
|
92
|
+
}, /*#__PURE__*/React.createElement(Paper, {
|
|
93
|
+
sx: {
|
|
94
|
+
p: 2
|
|
95
|
+
}
|
|
96
|
+
}, /*#__PURE__*/React.createElement(Stack, {
|
|
69
97
|
spacing: 2
|
|
70
98
|
}, /*#__PURE__*/React.createElement(Typography, {
|
|
71
99
|
variant: "h6",
|
|
@@ -78,8 +106,8 @@ function ContactForm(_ref) {
|
|
|
78
106
|
label: "Name",
|
|
79
107
|
value: formValues.name,
|
|
80
108
|
variant: "outlined",
|
|
81
|
-
onBlur:
|
|
82
|
-
onChange:
|
|
109
|
+
onBlur: handleBlur,
|
|
110
|
+
onChange: handleChange,
|
|
83
111
|
error: formErrors.name != undefined ? true : false,
|
|
84
112
|
helperText: formErrors.name
|
|
85
113
|
}), /*#__PURE__*/React.createElement(TextField, {
|
|
@@ -118,13 +146,12 @@ function ContactForm(_ref) {
|
|
|
118
146
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
119
147
|
variant: "outlined",
|
|
120
148
|
color: "primary",
|
|
121
|
-
onClick:
|
|
149
|
+
onClick: handleClear
|
|
122
150
|
}, "Clear"), /*#__PURE__*/React.createElement(Button, {
|
|
123
151
|
variant: "contained",
|
|
124
152
|
color: "primary",
|
|
125
153
|
onClick: handleSendCallback
|
|
126
|
-
}, "Send")));
|
|
154
|
+
}, "Send")))));
|
|
127
155
|
}
|
|
128
|
-
ContactForm.propTypes = {};
|
|
129
156
|
|
|
130
157
|
export { ContactForm as default };
|
|
@@ -12,6 +12,7 @@ import { HeroSection } from './HeroSection.js';
|
|
|
12
12
|
import { FeatureSection } from './FeaturesSection.js';
|
|
13
13
|
import { IconSection } from './IconSection.js';
|
|
14
14
|
import { Box } from '@mui/material';
|
|
15
|
+
import ContactForm from './ContactForm.js';
|
|
15
16
|
|
|
16
17
|
function blockRenderer(block) {
|
|
17
18
|
switch (block.__component) {
|
|
@@ -25,6 +26,11 @@ function blockRenderer(block) {
|
|
|
25
26
|
key: block.id,
|
|
26
27
|
data: block
|
|
27
28
|
});
|
|
29
|
+
case "layout.contact-section":
|
|
30
|
+
return /*#__PURE__*/React.createElement(ContactForm, {
|
|
31
|
+
key: block.id,
|
|
32
|
+
data: block
|
|
33
|
+
});
|
|
28
34
|
case "layout.text-image-section":
|
|
29
35
|
return /*#__PURE__*/React.createElement(TextImageSection, {
|
|
30
36
|
key: block.id,
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UMWD-Components
|
|
3
|
+
* @copyright Jelle Paulus
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { extends as _extends } from '../_virtual/_rollupPluginBabelHelpers.js';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { useTheme, Button, SvgIcon } from '@mui/material';
|
|
10
|
+
|
|
11
|
+
function WhatsAppClickToChatButton(_ref) {
|
|
12
|
+
let {
|
|
13
|
+
data
|
|
14
|
+
} = _ref;
|
|
15
|
+
const {
|
|
16
|
+
phoneNumber,
|
|
17
|
+
text,
|
|
18
|
+
message,
|
|
19
|
+
color,
|
|
20
|
+
round,
|
|
21
|
+
sx
|
|
22
|
+
} = data;
|
|
23
|
+
const theme = useTheme();
|
|
24
|
+
const formattedPhoneNumber = phoneNumber.replace(/\D/g, "");
|
|
25
|
+
const handleClick = () => {
|
|
26
|
+
let url = "https://wa.me/".concat(formattedPhoneNumber);
|
|
27
|
+
if (message) {
|
|
28
|
+
const formattedMessage = encodeURIComponent(message);
|
|
29
|
+
url = "https://wa.me/".concat(formattedPhoneNumber, "?text=").concat(formattedMessage);
|
|
30
|
+
}
|
|
31
|
+
window.open(url, "_blank");
|
|
32
|
+
};
|
|
33
|
+
return /*#__PURE__*/React.createElement(Button, {
|
|
34
|
+
variant: "contained",
|
|
35
|
+
onClick: handleClick,
|
|
36
|
+
startIcon: /*#__PURE__*/React.createElement(SvgIcon, {
|
|
37
|
+
sx: [round === true && {
|
|
38
|
+
m: 0,
|
|
39
|
+
p: 0
|
|
40
|
+
}]
|
|
41
|
+
}, /*#__PURE__*/React.createElement(WhatsAppIcon, {
|
|
42
|
+
fill: color || theme.palette.primary.contrastText
|
|
43
|
+
})),
|
|
44
|
+
sx: [{
|
|
45
|
+
...sx
|
|
46
|
+
}, round === true && {
|
|
47
|
+
display: "grid",
|
|
48
|
+
justifyContent: "center",
|
|
49
|
+
alignItems: "center",
|
|
50
|
+
borderRadius: "50%",
|
|
51
|
+
p: 1,
|
|
52
|
+
minWidth: "unset",
|
|
53
|
+
".MuiButton-startIcon": {
|
|
54
|
+
m: 0,
|
|
55
|
+
p: 0
|
|
56
|
+
}
|
|
57
|
+
}]
|
|
58
|
+
}, !round && (text || "Click to WhatsApp"));
|
|
59
|
+
}
|
|
60
|
+
function WhatsAppIcon(props) {
|
|
61
|
+
return /*#__PURE__*/React.createElement("svg", _extends({
|
|
62
|
+
viewBox: "0 0 30.667 30.667"
|
|
63
|
+
}, props), /*#__PURE__*/React.createElement("g", {
|
|
64
|
+
"stroke-width": "0"
|
|
65
|
+
}), /*#__PURE__*/React.createElement("g", {
|
|
66
|
+
"stroke-linecap": "round",
|
|
67
|
+
"stroke-linejoin": "round"
|
|
68
|
+
}), /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("path", {
|
|
69
|
+
d: "M30.667,14.939c0,8.25-6.74,14.938-15.056,14.938c-2.639,0-5.118-0.675-7.276-1.857L0,30.667l2.717-8.017 c-1.37-2.25-2.159-4.892-2.159-7.712C0.559,6.688,7.297,0,15.613,0C23.928,0.002,30.667,6.689,30.667,14.939z M15.61,2.382 c-6.979,0-12.656,5.634-12.656,12.56c0,2.748,0.896,5.292,2.411,7.362l-1.58,4.663l4.862-1.545c2,1.312,4.393,2.076,6.963,2.076 c6.979,0,12.658-5.633,12.658-12.559C28.27,8.016,22.59,2.382,15.61,2.382z M23.214,18.38c-0.094-0.151-0.34-0.243-0.708-0.427 c-0.367-0.184-2.184-1.069-2.521-1.189c-0.34-0.123-0.586-0.185-0.832,0.182c-0.243,0.367-0.951,1.191-1.168,1.437 c-0.215,0.245-0.43,0.276-0.799,0.095c-0.369-0.186-1.559-0.57-2.969-1.817c-1.097-0.972-1.838-2.169-2.052-2.536 c-0.217-0.366-0.022-0.564,0.161-0.746c0.165-0.165,0.369-0.428,0.554-0.643c0.185-0.213,0.246-0.364,0.369-0.609 c0.121-0.245,0.06-0.458-0.031-0.643c-0.092-0.184-0.829-1.984-1.138-2.717c-0.307-0.732-0.614-0.611-0.83-0.611 c-0.215,0-0.461-0.03-0.707-0.03S9.897,8.215,9.56,8.582s-1.291,1.252-1.291,3.054c0,1.804,1.321,3.543,1.506,3.787 c0.186,0.243,2.554,4.062,6.305,5.528c3.753,1.465,3.753,0.976,4.429,0.914c0.678-0.062,2.184-0.885,2.49-1.739 C23.307,19.268,23.307,18.533,23.214,18.38z"
|
|
70
|
+
})));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { WhatsAppClickToChatButton as default };
|
package/dist/esm/index.js
CHANGED
|
@@ -13,3 +13,4 @@ export { default as Footer } from './components/Footer.js';
|
|
|
13
13
|
export { default as ContactForm } from './components/ContactForm.js';
|
|
14
14
|
export { default as WebsitePlaceholder } from './components/WebsitePlaceholder.js';
|
|
15
15
|
export { default as BulletList } from './components/BulletList.js';
|
|
16
|
+
export { default as WhatsAppClickToChatButton } from './components/WhatsAppClickToChatButton.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "umwd-components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.71",
|
|
4
4
|
"description": "UMWD Component library",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
"@fontsource/roboto": "^5.0.12",
|
|
89
89
|
"@mui/types": "^7.2.14",
|
|
90
90
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
91
|
+
"@types/validator": "^13.11.9",
|
|
91
92
|
"next-router-mock": "^0.9.12",
|
|
92
93
|
"react": "^18.2.0",
|
|
93
94
|
"react-dnd": "^16.0.1",
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import {
|
|
5
|
+
Container,
|
|
6
|
+
Paper,
|
|
7
|
+
TextField,
|
|
8
|
+
Typography,
|
|
9
|
+
Stack,
|
|
10
|
+
Button,
|
|
11
|
+
} from "@mui/material";
|
|
12
|
+
import isEmail from "validator/lib/isEmail";
|
|
13
|
+
import { Breakpoint } from "@mui/system";
|
|
14
|
+
|
|
15
|
+
interface ContactFormProps {
|
|
16
|
+
id: number;
|
|
17
|
+
__component: string;
|
|
18
|
+
title: string;
|
|
19
|
+
maxWidth: Breakpoint;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function ContactForm({ data }: { readonly data: ContactFormProps }) {
|
|
23
|
+
const { maxWidth = "lg" } = data;
|
|
24
|
+
|
|
25
|
+
type FormValues = {
|
|
26
|
+
name: string;
|
|
27
|
+
email: string;
|
|
28
|
+
subject: string;
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const [formValues, setFormValues] = React.useState<FormValues>({
|
|
33
|
+
name: "",
|
|
34
|
+
email: "",
|
|
35
|
+
subject: "",
|
|
36
|
+
message: "",
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
type FormErrors = {
|
|
40
|
+
name?: string;
|
|
41
|
+
email?: string;
|
|
42
|
+
subject?: string;
|
|
43
|
+
message?: string;
|
|
44
|
+
[key: string]: string | undefined; // Add index signature
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const [formErrors, setFormErrors] = React.useState<FormErrors>({});
|
|
48
|
+
|
|
49
|
+
const handleBlur = (e: React.FocusEvent<HTMLInputElement>): void => {
|
|
50
|
+
const { id } = e.target;
|
|
51
|
+
const errors = validate(formValues);
|
|
52
|
+
if (errors[id]) {
|
|
53
|
+
setFormErrors((prevErrors) => ({
|
|
54
|
+
...prevErrors,
|
|
55
|
+
[id]: errors[id],
|
|
56
|
+
}));
|
|
57
|
+
} else {
|
|
58
|
+
setFormErrors((prevErrors) => {
|
|
59
|
+
const updatedErrors = { ...prevErrors };
|
|
60
|
+
delete updatedErrors[id];
|
|
61
|
+
return updatedErrors;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
|
67
|
+
const { id, value } = e.target;
|
|
68
|
+
setFormValues({ ...formValues, [id]: value });
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const handleClear = () => {
|
|
72
|
+
setFormValues({
|
|
73
|
+
name: "",
|
|
74
|
+
email: "",
|
|
75
|
+
subject: "",
|
|
76
|
+
message: "",
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const handleSendCallback = () => {
|
|
81
|
+
console.log("Send callback");
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const validate = (values: FormValues) => {
|
|
85
|
+
console.log("values from validate", values);
|
|
86
|
+
|
|
87
|
+
let errors: Partial<FormErrors> = {};
|
|
88
|
+
|
|
89
|
+
if (values.name === "") {
|
|
90
|
+
errors.name = "Name is required";
|
|
91
|
+
}
|
|
92
|
+
if (values.email === "") {
|
|
93
|
+
errors.email = "Email is required";
|
|
94
|
+
} else if (!isEmail(values.email)) {
|
|
95
|
+
errors.email = "Invalid email";
|
|
96
|
+
}
|
|
97
|
+
if (values.subject === "") {
|
|
98
|
+
errors.subject = "Subject is required";
|
|
99
|
+
}
|
|
100
|
+
if (values.message === "") {
|
|
101
|
+
errors.message = "Message is required";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
console.log("errors from validate", errors);
|
|
105
|
+
|
|
106
|
+
return errors;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<Container maxWidth={maxWidth || "lg"} sx={{ my: 1 }}>
|
|
111
|
+
<Paper sx={{ p: 2 }}>
|
|
112
|
+
<Stack spacing={2}>
|
|
113
|
+
<Typography variant="h6" align="center">
|
|
114
|
+
Write us
|
|
115
|
+
</Typography>
|
|
116
|
+
<Typography variant="body1" align="center">
|
|
117
|
+
We're open for any suggestion or just to have a chat
|
|
118
|
+
</Typography>
|
|
119
|
+
<TextField
|
|
120
|
+
id="name"
|
|
121
|
+
label="Name"
|
|
122
|
+
value={formValues.name}
|
|
123
|
+
variant="outlined"
|
|
124
|
+
onBlur={handleBlur}
|
|
125
|
+
onChange={handleChange}
|
|
126
|
+
error={formErrors.name != undefined ? true : false}
|
|
127
|
+
helperText={formErrors.name}
|
|
128
|
+
/>
|
|
129
|
+
<TextField
|
|
130
|
+
id="email"
|
|
131
|
+
label="Email"
|
|
132
|
+
value={formValues.email}
|
|
133
|
+
variant="outlined"
|
|
134
|
+
onBlur={handleBlur}
|
|
135
|
+
onChange={handleChange}
|
|
136
|
+
error={formErrors.email != undefined ? true : false}
|
|
137
|
+
helperText={formErrors.email}
|
|
138
|
+
/>
|
|
139
|
+
<TextField
|
|
140
|
+
id="subject"
|
|
141
|
+
label="Subject"
|
|
142
|
+
value={formValues.subject}
|
|
143
|
+
variant="outlined"
|
|
144
|
+
onBlur={handleBlur}
|
|
145
|
+
onChange={handleChange}
|
|
146
|
+
error={formErrors.subject != undefined}
|
|
147
|
+
helperText={formErrors.subject}
|
|
148
|
+
/>
|
|
149
|
+
<TextField
|
|
150
|
+
id="message"
|
|
151
|
+
label="Message"
|
|
152
|
+
value={formValues.message}
|
|
153
|
+
variant="outlined"
|
|
154
|
+
multiline
|
|
155
|
+
minRows={5}
|
|
156
|
+
onBlur={handleBlur}
|
|
157
|
+
onChange={handleChange}
|
|
158
|
+
error={formErrors.message != undefined}
|
|
159
|
+
helperText={formErrors.message}
|
|
160
|
+
/>
|
|
161
|
+
<Stack direction={"row"} spacing={2} justifyContent={"end"}>
|
|
162
|
+
<Button variant="outlined" color="primary" onClick={handleClear}>
|
|
163
|
+
Clear
|
|
164
|
+
</Button>
|
|
165
|
+
<Button
|
|
166
|
+
variant="contained"
|
|
167
|
+
color="primary"
|
|
168
|
+
onClick={handleSendCallback}
|
|
169
|
+
>
|
|
170
|
+
Send
|
|
171
|
+
</Button>
|
|
172
|
+
</Stack>
|
|
173
|
+
</Stack>
|
|
174
|
+
</Paper>
|
|
175
|
+
</Container>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export default ContactForm;
|
package/src/components/Page.js
CHANGED
|
@@ -7,6 +7,7 @@ import { HeroSection } from "./HeroSection.tsx";
|
|
|
7
7
|
import { FeatureSection } from "./FeaturesSection.tsx";
|
|
8
8
|
import { IconSection } from "./IconSection.tsx";
|
|
9
9
|
import { Box } from "@mui/material";
|
|
10
|
+
import ContactForm from "./ContactForm.tsx";
|
|
10
11
|
|
|
11
12
|
function blockRenderer(block) {
|
|
12
13
|
switch (block.__component) {
|
|
@@ -14,10 +15,13 @@ function blockRenderer(block) {
|
|
|
14
15
|
return <HeroSection key={block.id} data={block} />;
|
|
15
16
|
case "layout.features-section":
|
|
16
17
|
return <FeatureSection key={block.id} data={block} />;
|
|
18
|
+
case "layout.contact-section":
|
|
19
|
+
return <ContactForm key={block.id} data={block} />;
|
|
17
20
|
case "layout.text-image-section":
|
|
18
21
|
return <TextImageSection key={block.id} data={block} />;
|
|
19
22
|
case "layout.icon-section":
|
|
20
23
|
return <IconSection key={block.id} data={block} />;
|
|
24
|
+
|
|
21
25
|
default:
|
|
22
26
|
return null;
|
|
23
27
|
}
|
|
@@ -24,7 +24,7 @@ interface TextImageSectionProps {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function TextImageSection({ data }: Readonly<TextImageSectionProps>) {
|
|
27
|
-
const { title, text, image, reverse = false, maxWidth } = data;
|
|
27
|
+
const { title, text, image, reverse = false, maxWidth = "lg" } = data;
|
|
28
28
|
|
|
29
29
|
/* TODO Text_content should deal with linebreaks,
|
|
30
30
|
reading up upon mui-markdown docs is advised */
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Button, SvgIcon, useTheme } from "@mui/material";
|
|
3
|
+
|
|
4
|
+
interface WhatsAppClickToChatButtonProps {
|
|
5
|
+
phoneNumber: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
message?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
round?: boolean;
|
|
10
|
+
sx?: React.CSSProperties;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function WhatsAppClickToChatButton({
|
|
14
|
+
data,
|
|
15
|
+
}: {
|
|
16
|
+
readonly data: WhatsAppClickToChatButtonProps;
|
|
17
|
+
}) {
|
|
18
|
+
const { phoneNumber, text, message, color, round, sx } = data;
|
|
19
|
+
|
|
20
|
+
const theme = useTheme();
|
|
21
|
+
|
|
22
|
+
const formattedPhoneNumber = phoneNumber.replace(/\D/g, "");
|
|
23
|
+
|
|
24
|
+
const handleClick = () => {
|
|
25
|
+
let url = `https://wa.me/${formattedPhoneNumber}`;
|
|
26
|
+
if (message) {
|
|
27
|
+
const formattedMessage = encodeURIComponent(message);
|
|
28
|
+
url = `https://wa.me/${formattedPhoneNumber}?text=${formattedMessage}`;
|
|
29
|
+
}
|
|
30
|
+
window.open(url, "_blank");
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Button
|
|
35
|
+
variant="contained"
|
|
36
|
+
onClick={handleClick}
|
|
37
|
+
startIcon={
|
|
38
|
+
<SvgIcon sx={[round === true && { m: 0, p: 0 }]}>
|
|
39
|
+
<WhatsAppIcon fill={color || theme.palette.primary.contrastText} />
|
|
40
|
+
</SvgIcon>
|
|
41
|
+
}
|
|
42
|
+
sx={[
|
|
43
|
+
{ ...sx },
|
|
44
|
+
round === true && {
|
|
45
|
+
display: "grid",
|
|
46
|
+
justifyContent: "center",
|
|
47
|
+
alignItems: "center",
|
|
48
|
+
borderRadius: "50%",
|
|
49
|
+
p: 1,
|
|
50
|
+
minWidth: "unset",
|
|
51
|
+
".MuiButton-startIcon": { m: 0, p: 0 },
|
|
52
|
+
},
|
|
53
|
+
]}
|
|
54
|
+
>
|
|
55
|
+
{!round && (text || "Click to WhatsApp")}
|
|
56
|
+
</Button>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default WhatsAppClickToChatButton;
|
|
61
|
+
|
|
62
|
+
function WhatsAppIcon(props: any) {
|
|
63
|
+
return (
|
|
64
|
+
<svg viewBox="0 0 30.667 30.667" {...props}>
|
|
65
|
+
<g stroke-width="0"></g>
|
|
66
|
+
<g stroke-linecap="round" stroke-linejoin="round"></g>
|
|
67
|
+
<g>
|
|
68
|
+
<path d="M30.667,14.939c0,8.25-6.74,14.938-15.056,14.938c-2.639,0-5.118-0.675-7.276-1.857L0,30.667l2.717-8.017 c-1.37-2.25-2.159-4.892-2.159-7.712C0.559,6.688,7.297,0,15.613,0C23.928,0.002,30.667,6.689,30.667,14.939z M15.61,2.382 c-6.979,0-12.656,5.634-12.656,12.56c0,2.748,0.896,5.292,2.411,7.362l-1.58,4.663l4.862-1.545c2,1.312,4.393,2.076,6.963,2.076 c6.979,0,12.658-5.633,12.658-12.559C28.27,8.016,22.59,2.382,15.61,2.382z M23.214,18.38c-0.094-0.151-0.34-0.243-0.708-0.427 c-0.367-0.184-2.184-1.069-2.521-1.189c-0.34-0.123-0.586-0.185-0.832,0.182c-0.243,0.367-0.951,1.191-1.168,1.437 c-0.215,0.245-0.43,0.276-0.799,0.095c-0.369-0.186-1.559-0.57-2.969-1.817c-1.097-0.972-1.838-2.169-2.052-2.536 c-0.217-0.366-0.022-0.564,0.161-0.746c0.165-0.165,0.369-0.428,0.554-0.643c0.185-0.213,0.246-0.364,0.369-0.609 c0.121-0.245,0.06-0.458-0.031-0.643c-0.092-0.184-0.829-1.984-1.138-2.717c-0.307-0.732-0.614-0.611-0.83-0.611 c-0.215,0-0.461-0.03-0.707-0.03S9.897,8.215,9.56,8.582s-1.291,1.252-1.291,3.054c0,1.804,1.321,3.543,1.506,3.787 c0.186,0.243,2.554,4.062,6.305,5.528c3.753,1.465,3.753,0.976,4.429,0.914c0.678-0.062,2.184-0.885,2.49-1.739 C23.307,19.268,23.307,18.533,23.214,18.38z"></path>
|
|
69
|
+
</g>
|
|
70
|
+
</svg>
|
|
71
|
+
);
|
|
72
|
+
}
|
package/src/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export { default as NavBar } from "./components/NavBar";
|
|
|
10
10
|
export { default as TextImageSection } from "./components/TextImageSection.tsx";
|
|
11
11
|
export { default as Page } from "./components/Page";
|
|
12
12
|
export { default as Footer } from "./components/Footer";
|
|
13
|
-
export { default as ContactForm } from "./components/ContactForm";
|
|
13
|
+
export { default as ContactForm } from "./components/ContactForm.tsx";
|
|
14
14
|
export { default as WebsitePlaceholder } from "./components/WebsitePlaceholder";
|
|
15
15
|
export { default as BulletList } from "./components/BulletList";
|
|
16
|
+
export { default as WhatsAppClickToChatButton } from "./components/WhatsAppClickToChatButton.tsx";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import WhatsAppClickToChatButton from "../components/WhatsAppClickToChatButton.tsx";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "UMWD/WhatsAppClickToChatButton",
|
|
6
|
+
component: WhatsAppClickToChatButton,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const Template = ({ ...args }) => {
|
|
10
|
+
return <WhatsAppClickToChatButton {...args} />;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const Round = Template.bind({});
|
|
14
|
+
|
|
15
|
+
Round.args = {
|
|
16
|
+
data: {
|
|
17
|
+
phoneNumber: "+1234567890",
|
|
18
|
+
message: "Hello, how can I help you?",
|
|
19
|
+
color: "#25D366",
|
|
20
|
+
round: true,
|
|
21
|
+
sx: {
|
|
22
|
+
position: "fixed",
|
|
23
|
+
bottom: "20px",
|
|
24
|
+
right: "20px",
|
|
25
|
+
zIndex: 1000,
|
|
26
|
+
width: "40px",
|
|
27
|
+
height: "40px",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const WithText = Template.bind({});
|
|
33
|
+
|
|
34
|
+
WithText.args = {
|
|
35
|
+
data: {
|
|
36
|
+
phoneNumber: "+1234567890",
|
|
37
|
+
message: "Hello, how can I help you?",
|
|
38
|
+
color: "red",
|
|
39
|
+
round: false,
|
|
40
|
+
sx: {
|
|
41
|
+
position: "fixed",
|
|
42
|
+
bottom: "20px",
|
|
43
|
+
right: "20px",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const SX = Template.bind({});
|
|
49
|
+
|
|
50
|
+
SX.args = {
|
|
51
|
+
data: {
|
|
52
|
+
phoneNumber: "+1234567890",
|
|
53
|
+
message: "Hello, how can I help you?",
|
|
54
|
+
color: "red",
|
|
55
|
+
round: true,
|
|
56
|
+
sx: {
|
|
57
|
+
position: "fixed",
|
|
58
|
+
bottom: "20px",
|
|
59
|
+
right: "20px",
|
|
60
|
+
zIndex: 1000,
|
|
61
|
+
width: "70px",
|
|
62
|
+
height: "70px",
|
|
63
|
+
".MuiSvgIcon-root": {
|
|
64
|
+
width: "40px",
|
|
65
|
+
height: "40px",
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React from "react";
|
|
4
|
-
import PropTypes from "prop-types";
|
|
5
|
-
import { TextField, Typography, Stack, Button } from "@mui/material";
|
|
6
|
-
import isEmail from "validator/lib/isEmail";
|
|
7
|
-
|
|
8
|
-
function ContactForm({ ...args }) {
|
|
9
|
-
const [formValues, setFormValues] = React.useState({
|
|
10
|
-
name: "",
|
|
11
|
-
email: "",
|
|
12
|
-
subject: "",
|
|
13
|
-
message: "",
|
|
14
|
-
});
|
|
15
|
-
const [formErrors, setFormErrors] = React.useState({});
|
|
16
|
-
|
|
17
|
-
const handleBlur = (e) => {
|
|
18
|
-
console.log(e.target.id);
|
|
19
|
-
console.log(e.target.value);
|
|
20
|
-
const errors = validate(formValues);
|
|
21
|
-
console.log(errors);
|
|
22
|
-
setFormErrors({ ...formErrors, [e.target.id]: errors[e.target.id] });
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const handleChange = (e) => {
|
|
26
|
-
const { id, value } = e.target;
|
|
27
|
-
setFormValues({ ...formValues, [id]: value });
|
|
28
|
-
console.log("formValues", formValues);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const handleClear = () => {
|
|
32
|
-
setFormValues({});
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const handleSendCallback = () => {
|
|
36
|
-
console.log("Send callback");
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const validate = (values) => {
|
|
40
|
-
console.log("values from validate", values);
|
|
41
|
-
let errors = {};
|
|
42
|
-
|
|
43
|
-
if (values.name === "") {
|
|
44
|
-
errors.name = "Name is required";
|
|
45
|
-
}
|
|
46
|
-
if (values.email === "") {
|
|
47
|
-
errors.email = "Email is required";
|
|
48
|
-
} else if (!isEmail(values.email)) {
|
|
49
|
-
errors.email = "Invalid email";
|
|
50
|
-
}
|
|
51
|
-
if (values.subject === "") {
|
|
52
|
-
errors.subject = "Subject is required";
|
|
53
|
-
}
|
|
54
|
-
if (values.message === "") {
|
|
55
|
-
errors.message = "Message is required";
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
console.log("errors from validate", errors);
|
|
59
|
-
|
|
60
|
-
return errors;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<Stack spacing={2}>
|
|
65
|
-
<Typography variant="h6" align="center">
|
|
66
|
-
Write us
|
|
67
|
-
</Typography>
|
|
68
|
-
<Typography variant="body1" align="center">
|
|
69
|
-
We're open for any suggestion or just to have a chat
|
|
70
|
-
</Typography>
|
|
71
|
-
<TextField
|
|
72
|
-
id="name"
|
|
73
|
-
label="Name"
|
|
74
|
-
value={formValues.name}
|
|
75
|
-
variant="outlined"
|
|
76
|
-
onBlur={(e) => handleBlur(e)}
|
|
77
|
-
onChange={(e) => handleChange(e)}
|
|
78
|
-
error={formErrors.name != undefined ? true : false}
|
|
79
|
-
helperText={formErrors.name}
|
|
80
|
-
/>
|
|
81
|
-
<TextField
|
|
82
|
-
id="email"
|
|
83
|
-
label="Email"
|
|
84
|
-
value={formValues.email}
|
|
85
|
-
variant="outlined"
|
|
86
|
-
onBlur={handleBlur}
|
|
87
|
-
onChange={handleChange}
|
|
88
|
-
error={formErrors.email != undefined ? true : false}
|
|
89
|
-
helperText={formErrors.email}
|
|
90
|
-
/>
|
|
91
|
-
<TextField
|
|
92
|
-
id="subject"
|
|
93
|
-
label="Subject"
|
|
94
|
-
value={formValues.subject}
|
|
95
|
-
variant="outlined"
|
|
96
|
-
onBlur={handleBlur}
|
|
97
|
-
onChange={handleChange}
|
|
98
|
-
error={formErrors.subject != undefined}
|
|
99
|
-
helperText={formErrors.subject}
|
|
100
|
-
/>
|
|
101
|
-
<TextField
|
|
102
|
-
id="message"
|
|
103
|
-
label="Message"
|
|
104
|
-
value={formValues.message}
|
|
105
|
-
variant="outlined"
|
|
106
|
-
multiline
|
|
107
|
-
minRows={5}
|
|
108
|
-
onBlur={handleBlur}
|
|
109
|
-
onChange={handleChange}
|
|
110
|
-
error={formErrors.message != undefined}
|
|
111
|
-
helperText={formErrors.message}
|
|
112
|
-
/>
|
|
113
|
-
<Stack direction={"row"} spacing={2} justifyContent={"end"}>
|
|
114
|
-
<Button variant="outlined" color="primary" onClick={() => handleClear}>
|
|
115
|
-
Clear
|
|
116
|
-
</Button>
|
|
117
|
-
<Button
|
|
118
|
-
variant="contained"
|
|
119
|
-
color="primary"
|
|
120
|
-
onClick={handleSendCallback}
|
|
121
|
-
>
|
|
122
|
-
Send
|
|
123
|
-
</Button>
|
|
124
|
-
</Stack>
|
|
125
|
-
</Stack>
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
ContactForm.propTypes = {};
|
|
130
|
-
|
|
131
|
-
export default ContactForm;
|