umwd-components 0.1.68 → 0.1.70
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 +19 -7
- package/dist/cjs/components/HeroSection.js +12 -3
- package/dist/cjs/components/Page.js +14 -2
- package/dist/cjs/components/StrapiImage.js +1 -1
- package/dist/cjs/components/TextImageSection.js +1 -1
- package/dist/esm/components/ContactForm.js +20 -8
- package/dist/esm/components/HeroSection.js +12 -3
- package/dist/esm/components/Page.js +14 -2
- package/dist/esm/components/StrapiImage.js +1 -1
- package/dist/esm/components/TextImageSection.js +1 -1
- package/package.json +1 -1
- package/src/components/ContactForm.tsx +149 -0
- package/src/components/HeroSection.tsx +18 -3
- package/src/components/Page.js +7 -2
- package/src/components/StrapiImage.tsx +1 -1
- package/src/components/TextImageSection.tsx +1 -1
- package/src/index.js +1 -1
- package/src/stories/Page.stories.js +170 -2
- package/src/components/ContactForm.js +0 -131
|
@@ -10,11 +10,18 @@
|
|
|
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
|
+
id,
|
|
22
|
+
title,
|
|
23
|
+
maxWidth = "lg"
|
|
24
|
+
} = data;
|
|
18
25
|
const [formValues, setFormValues] = React.useState({
|
|
19
26
|
name: "",
|
|
20
27
|
email: "",
|
|
@@ -23,10 +30,7 @@ function ContactForm(_ref) {
|
|
|
23
30
|
});
|
|
24
31
|
const [formErrors, setFormErrors] = React.useState({});
|
|
25
32
|
const handleBlur = e => {
|
|
26
|
-
console.log(e.target.id);
|
|
27
|
-
console.log(e.target.value);
|
|
28
33
|
const errors = validate(formValues);
|
|
29
|
-
console.log(errors);
|
|
30
34
|
setFormErrors({
|
|
31
35
|
...formErrors,
|
|
32
36
|
[e.target.id]: errors[e.target.id]
|
|
@@ -69,7 +73,16 @@ function ContactForm(_ref) {
|
|
|
69
73
|
console.log("errors from validate", errors);
|
|
70
74
|
return errors;
|
|
71
75
|
};
|
|
72
|
-
return /*#__PURE__*/React.createElement(material.
|
|
76
|
+
return /*#__PURE__*/React.createElement(material.Container, {
|
|
77
|
+
maxWidth: maxWidth,
|
|
78
|
+
sx: {
|
|
79
|
+
my: 1
|
|
80
|
+
}
|
|
81
|
+
}, /*#__PURE__*/React.createElement(material.Paper, {
|
|
82
|
+
sx: {
|
|
83
|
+
p: 2
|
|
84
|
+
}
|
|
85
|
+
}, /*#__PURE__*/React.createElement(material.Stack, {
|
|
73
86
|
spacing: 2
|
|
74
87
|
}, /*#__PURE__*/React.createElement(material.Typography, {
|
|
75
88
|
variant: "h6",
|
|
@@ -127,8 +140,7 @@ function ContactForm(_ref) {
|
|
|
127
140
|
variant: "contained",
|
|
128
141
|
color: "primary",
|
|
129
142
|
onClick: handleSendCallback
|
|
130
|
-
}, "Send")));
|
|
143
|
+
}, "Send")))));
|
|
131
144
|
}
|
|
132
|
-
ContactForm.propTypes = {};
|
|
133
145
|
|
|
134
146
|
exports.default = ContactForm;
|
|
@@ -18,7 +18,8 @@ function HeroSection(_ref) {
|
|
|
18
18
|
const {
|
|
19
19
|
heading,
|
|
20
20
|
subHeading,
|
|
21
|
-
|
|
21
|
+
bgImage,
|
|
22
|
+
logoImage,
|
|
22
23
|
link
|
|
23
24
|
} = data;
|
|
24
25
|
return /*#__PURE__*/React.createElement("header", {
|
|
@@ -47,16 +48,24 @@ function HeroSection(_ref) {
|
|
|
47
48
|
height: "100%"
|
|
48
49
|
},
|
|
49
50
|
height: 1080,
|
|
50
|
-
src:
|
|
51
|
+
src: bgImage.url,
|
|
51
52
|
width: 1920
|
|
52
53
|
}), /*#__PURE__*/React.createElement(material.Stack, {
|
|
53
54
|
spacing: 2,
|
|
55
|
+
alignItems: "center",
|
|
56
|
+
justifyContent: "center",
|
|
54
57
|
sx: {
|
|
55
58
|
width: "max-content",
|
|
56
59
|
maxWidth: "600px",
|
|
57
60
|
zIndex: 1
|
|
58
61
|
}
|
|
59
|
-
}, /*#__PURE__*/React.createElement(
|
|
62
|
+
}, logoImage && /*#__PURE__*/React.createElement(StrapiImage.StrapiImage, {
|
|
63
|
+
alt: logoImage.alternativeText,
|
|
64
|
+
height: logoImage.height || 100,
|
|
65
|
+
style: logoImage.style || {},
|
|
66
|
+
src: logoImage.url,
|
|
67
|
+
width: logoImage.width || 100
|
|
68
|
+
}), /*#__PURE__*/React.createElement(material.Typography, {
|
|
60
69
|
variant: "h1",
|
|
61
70
|
align: "center"
|
|
62
71
|
}, heading), /*#__PURE__*/React.createElement(material.Typography, {
|
|
@@ -15,6 +15,8 @@ var TextImageSection = require('./TextImageSection.js');
|
|
|
15
15
|
var HeroSection = require('./HeroSection.js');
|
|
16
16
|
var FeaturesSection = require('./FeaturesSection.js');
|
|
17
17
|
var IconSection = require('./IconSection.js');
|
|
18
|
+
var material = require('@mui/material');
|
|
19
|
+
var ContactForm = require('./ContactForm.js');
|
|
18
20
|
|
|
19
21
|
function blockRenderer(block) {
|
|
20
22
|
switch (block.__component) {
|
|
@@ -28,6 +30,11 @@ function blockRenderer(block) {
|
|
|
28
30
|
key: block.id,
|
|
29
31
|
data: block
|
|
30
32
|
});
|
|
33
|
+
case "layout.contact-section":
|
|
34
|
+
return /*#__PURE__*/React.createElement(ContactForm.default, {
|
|
35
|
+
key: block.id,
|
|
36
|
+
data: block
|
|
37
|
+
});
|
|
31
38
|
case "layout.text-image-section":
|
|
32
39
|
return /*#__PURE__*/React.createElement(TextImageSection.default, {
|
|
33
40
|
key: block.id,
|
|
@@ -44,12 +51,17 @@ function blockRenderer(block) {
|
|
|
44
51
|
}
|
|
45
52
|
function Page(_ref) {
|
|
46
53
|
let {
|
|
47
|
-
blocks
|
|
54
|
+
blocks,
|
|
55
|
+
sx
|
|
48
56
|
} = _ref;
|
|
49
57
|
if (!blocks) {
|
|
50
58
|
return /*#__PURE__*/React.createElement("p", null, "No sections found");
|
|
51
59
|
}
|
|
52
|
-
return /*#__PURE__*/React.createElement(
|
|
60
|
+
return /*#__PURE__*/React.createElement(material.Box, {
|
|
61
|
+
sx: {
|
|
62
|
+
...sx
|
|
63
|
+
}
|
|
64
|
+
}, blocks.map(blockRenderer));
|
|
53
65
|
}
|
|
54
66
|
Page.propTypes = {
|
|
55
67
|
blocks: PropTypes.arrayOf(PropTypes.object)
|
|
@@ -6,11 +6,18 @@
|
|
|
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
|
+
id,
|
|
18
|
+
title,
|
|
19
|
+
maxWidth = "lg"
|
|
20
|
+
} = data;
|
|
14
21
|
const [formValues, setFormValues] = React.useState({
|
|
15
22
|
name: "",
|
|
16
23
|
email: "",
|
|
@@ -19,10 +26,7 @@ function ContactForm(_ref) {
|
|
|
19
26
|
});
|
|
20
27
|
const [formErrors, setFormErrors] = React.useState({});
|
|
21
28
|
const handleBlur = e => {
|
|
22
|
-
console.log(e.target.id);
|
|
23
|
-
console.log(e.target.value);
|
|
24
29
|
const errors = validate(formValues);
|
|
25
|
-
console.log(errors);
|
|
26
30
|
setFormErrors({
|
|
27
31
|
...formErrors,
|
|
28
32
|
[e.target.id]: errors[e.target.id]
|
|
@@ -65,7 +69,16 @@ function ContactForm(_ref) {
|
|
|
65
69
|
console.log("errors from validate", errors);
|
|
66
70
|
return errors;
|
|
67
71
|
};
|
|
68
|
-
return /*#__PURE__*/React.createElement(
|
|
72
|
+
return /*#__PURE__*/React.createElement(Container, {
|
|
73
|
+
maxWidth: maxWidth,
|
|
74
|
+
sx: {
|
|
75
|
+
my: 1
|
|
76
|
+
}
|
|
77
|
+
}, /*#__PURE__*/React.createElement(Paper, {
|
|
78
|
+
sx: {
|
|
79
|
+
p: 2
|
|
80
|
+
}
|
|
81
|
+
}, /*#__PURE__*/React.createElement(Stack, {
|
|
69
82
|
spacing: 2
|
|
70
83
|
}, /*#__PURE__*/React.createElement(Typography, {
|
|
71
84
|
variant: "h6",
|
|
@@ -123,8 +136,7 @@ function ContactForm(_ref) {
|
|
|
123
136
|
variant: "contained",
|
|
124
137
|
color: "primary",
|
|
125
138
|
onClick: handleSendCallback
|
|
126
|
-
}, "Send")));
|
|
139
|
+
}, "Send")))));
|
|
127
140
|
}
|
|
128
|
-
ContactForm.propTypes = {};
|
|
129
141
|
|
|
130
142
|
export { ContactForm as default };
|
|
@@ -16,7 +16,8 @@ function HeroSection(_ref) {
|
|
|
16
16
|
const {
|
|
17
17
|
heading,
|
|
18
18
|
subHeading,
|
|
19
|
-
|
|
19
|
+
bgImage,
|
|
20
|
+
logoImage,
|
|
20
21
|
link
|
|
21
22
|
} = data;
|
|
22
23
|
return /*#__PURE__*/React.createElement("header", {
|
|
@@ -45,16 +46,24 @@ function HeroSection(_ref) {
|
|
|
45
46
|
height: "100%"
|
|
46
47
|
},
|
|
47
48
|
height: 1080,
|
|
48
|
-
src:
|
|
49
|
+
src: bgImage.url,
|
|
49
50
|
width: 1920
|
|
50
51
|
}), /*#__PURE__*/React.createElement(Stack, {
|
|
51
52
|
spacing: 2,
|
|
53
|
+
alignItems: "center",
|
|
54
|
+
justifyContent: "center",
|
|
52
55
|
sx: {
|
|
53
56
|
width: "max-content",
|
|
54
57
|
maxWidth: "600px",
|
|
55
58
|
zIndex: 1
|
|
56
59
|
}
|
|
57
|
-
}, /*#__PURE__*/React.createElement(
|
|
60
|
+
}, logoImage && /*#__PURE__*/React.createElement(StrapiImage, {
|
|
61
|
+
alt: logoImage.alternativeText,
|
|
62
|
+
height: logoImage.height || 100,
|
|
63
|
+
style: logoImage.style || {},
|
|
64
|
+
src: logoImage.url,
|
|
65
|
+
width: logoImage.width || 100
|
|
66
|
+
}), /*#__PURE__*/React.createElement(Typography, {
|
|
58
67
|
variant: "h1",
|
|
59
68
|
align: "center"
|
|
60
69
|
}, heading), /*#__PURE__*/React.createElement(Typography, {
|
|
@@ -11,6 +11,8 @@ import TextImageSection from './TextImageSection.js';
|
|
|
11
11
|
import { HeroSection } from './HeroSection.js';
|
|
12
12
|
import { FeatureSection } from './FeaturesSection.js';
|
|
13
13
|
import { IconSection } from './IconSection.js';
|
|
14
|
+
import { Box } from '@mui/material';
|
|
15
|
+
import ContactForm from './ContactForm.js';
|
|
14
16
|
|
|
15
17
|
function blockRenderer(block) {
|
|
16
18
|
switch (block.__component) {
|
|
@@ -24,6 +26,11 @@ function blockRenderer(block) {
|
|
|
24
26
|
key: block.id,
|
|
25
27
|
data: block
|
|
26
28
|
});
|
|
29
|
+
case "layout.contact-section":
|
|
30
|
+
return /*#__PURE__*/React.createElement(ContactForm, {
|
|
31
|
+
key: block.id,
|
|
32
|
+
data: block
|
|
33
|
+
});
|
|
27
34
|
case "layout.text-image-section":
|
|
28
35
|
return /*#__PURE__*/React.createElement(TextImageSection, {
|
|
29
36
|
key: block.id,
|
|
@@ -40,12 +47,17 @@ function blockRenderer(block) {
|
|
|
40
47
|
}
|
|
41
48
|
function Page(_ref) {
|
|
42
49
|
let {
|
|
43
|
-
blocks
|
|
50
|
+
blocks,
|
|
51
|
+
sx
|
|
44
52
|
} = _ref;
|
|
45
53
|
if (!blocks) {
|
|
46
54
|
return /*#__PURE__*/React.createElement("p", null, "No sections found");
|
|
47
55
|
}
|
|
48
|
-
return /*#__PURE__*/React.createElement(
|
|
56
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
57
|
+
sx: {
|
|
58
|
+
...sx
|
|
59
|
+
}
|
|
60
|
+
}, blocks.map(blockRenderer));
|
|
49
61
|
}
|
|
50
62
|
Page.propTypes = {
|
|
51
63
|
blocks: PropTypes.arrayOf(PropTypes.object)
|
package/package.json
CHANGED
|
@@ -0,0 +1,149 @@
|
|
|
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
|
+
|
|
14
|
+
interface ContactFormProps {
|
|
15
|
+
id: number;
|
|
16
|
+
title: string;
|
|
17
|
+
maxWidth: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function ContactForm({ data }: { readonly data: ContactFormProps }) {
|
|
21
|
+
const { id, title, maxWidth = "lg" } = data;
|
|
22
|
+
|
|
23
|
+
const [formValues, setFormValues] = React.useState({
|
|
24
|
+
name: "",
|
|
25
|
+
email: "",
|
|
26
|
+
subject: "",
|
|
27
|
+
message: "",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const [formErrors, setFormErrors] = React.useState({});
|
|
31
|
+
|
|
32
|
+
const handleBlur = (e: Event) => {
|
|
33
|
+
const errors = validate(formValues);
|
|
34
|
+
setFormErrors({ ...formErrors, [e.target.id]: errors[e.target.id] });
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const handleChange = (e: Event) => {
|
|
38
|
+
const { id, value } = e.target;
|
|
39
|
+
setFormValues({ ...formValues, [id]: value });
|
|
40
|
+
console.log("formValues", formValues);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const handleClear = () => {
|
|
44
|
+
setFormValues({});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleSendCallback = () => {
|
|
48
|
+
console.log("Send callback");
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const validate = (values) => {
|
|
52
|
+
console.log("values from validate", values);
|
|
53
|
+
let errors = {};
|
|
54
|
+
|
|
55
|
+
if (values.name === "") {
|
|
56
|
+
errors.name = "Name is required";
|
|
57
|
+
}
|
|
58
|
+
if (values.email === "") {
|
|
59
|
+
errors.email = "Email is required";
|
|
60
|
+
} else if (!isEmail(values.email)) {
|
|
61
|
+
errors.email = "Invalid email";
|
|
62
|
+
}
|
|
63
|
+
if (values.subject === "") {
|
|
64
|
+
errors.subject = "Subject is required";
|
|
65
|
+
}
|
|
66
|
+
if (values.message === "") {
|
|
67
|
+
errors.message = "Message is required";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log("errors from validate", errors);
|
|
71
|
+
|
|
72
|
+
return errors;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Container maxWidth={maxWidth} sx={{ my: 1 }}>
|
|
77
|
+
<Paper sx={{ p: 2 }}>
|
|
78
|
+
<Stack spacing={2}>
|
|
79
|
+
<Typography variant="h6" align="center">
|
|
80
|
+
Write us
|
|
81
|
+
</Typography>
|
|
82
|
+
<Typography variant="body1" align="center">
|
|
83
|
+
We're open for any suggestion or just to have a chat
|
|
84
|
+
</Typography>
|
|
85
|
+
<TextField
|
|
86
|
+
id="name"
|
|
87
|
+
label="Name"
|
|
88
|
+
value={formValues.name}
|
|
89
|
+
variant="outlined"
|
|
90
|
+
onBlur={(e) => handleBlur(e)}
|
|
91
|
+
onChange={(e) => handleChange(e)}
|
|
92
|
+
error={formErrors.name != undefined ? true : false}
|
|
93
|
+
helperText={formErrors.name}
|
|
94
|
+
/>
|
|
95
|
+
<TextField
|
|
96
|
+
id="email"
|
|
97
|
+
label="Email"
|
|
98
|
+
value={formValues.email}
|
|
99
|
+
variant="outlined"
|
|
100
|
+
onBlur={handleBlur}
|
|
101
|
+
onChange={handleChange}
|
|
102
|
+
error={formErrors.email != undefined ? true : false}
|
|
103
|
+
helperText={formErrors.email}
|
|
104
|
+
/>
|
|
105
|
+
<TextField
|
|
106
|
+
id="subject"
|
|
107
|
+
label="Subject"
|
|
108
|
+
value={formValues.subject}
|
|
109
|
+
variant="outlined"
|
|
110
|
+
onBlur={handleBlur}
|
|
111
|
+
onChange={handleChange}
|
|
112
|
+
error={formErrors.subject != undefined}
|
|
113
|
+
helperText={formErrors.subject}
|
|
114
|
+
/>
|
|
115
|
+
<TextField
|
|
116
|
+
id="message"
|
|
117
|
+
label="Message"
|
|
118
|
+
value={formValues.message}
|
|
119
|
+
variant="outlined"
|
|
120
|
+
multiline
|
|
121
|
+
minRows={5}
|
|
122
|
+
onBlur={handleBlur}
|
|
123
|
+
onChange={handleChange}
|
|
124
|
+
error={formErrors.message != undefined}
|
|
125
|
+
helperText={formErrors.message}
|
|
126
|
+
/>
|
|
127
|
+
<Stack direction={"row"} spacing={2} justifyContent={"end"}>
|
|
128
|
+
<Button
|
|
129
|
+
variant="outlined"
|
|
130
|
+
color="primary"
|
|
131
|
+
onClick={() => handleClear}
|
|
132
|
+
>
|
|
133
|
+
Clear
|
|
134
|
+
</Button>
|
|
135
|
+
<Button
|
|
136
|
+
variant="contained"
|
|
137
|
+
color="primary"
|
|
138
|
+
onClick={handleSendCallback}
|
|
139
|
+
>
|
|
140
|
+
Send
|
|
141
|
+
</Button>
|
|
142
|
+
</Stack>
|
|
143
|
+
</Stack>
|
|
144
|
+
</Paper>
|
|
145
|
+
</Container>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export default ContactForm;
|
|
@@ -7,6 +7,9 @@ interface ImageProps {
|
|
|
7
7
|
id: number;
|
|
8
8
|
url: string;
|
|
9
9
|
alternativeText: string;
|
|
10
|
+
style: React.CSSProperties;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
interface LinkProps {
|
|
@@ -21,13 +24,14 @@ interface HeroSectionProps {
|
|
|
21
24
|
__component: string;
|
|
22
25
|
heading: string;
|
|
23
26
|
subHeading: string;
|
|
24
|
-
|
|
27
|
+
bgImage: ImageProps;
|
|
28
|
+
logoImage: ImageProps;
|
|
25
29
|
link: LinkProps;
|
|
26
30
|
};
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
export function HeroSection({ data }: Readonly<HeroSectionProps>) {
|
|
30
|
-
const { heading, subHeading,
|
|
34
|
+
const { heading, subHeading, bgImage, logoImage, link } = data;
|
|
31
35
|
|
|
32
36
|
return (
|
|
33
37
|
<header style={{ position: "relative", padding: 0, margin: 0 }}>
|
|
@@ -52,13 +56,24 @@ export function HeroSection({ data }: Readonly<HeroSectionProps>) {
|
|
|
52
56
|
height: "100%",
|
|
53
57
|
}}
|
|
54
58
|
height={1080}
|
|
55
|
-
src={
|
|
59
|
+
src={bgImage.url}
|
|
56
60
|
width={1920}
|
|
57
61
|
/>
|
|
58
62
|
<Stack
|
|
59
63
|
spacing={2}
|
|
64
|
+
alignItems="center"
|
|
65
|
+
justifyContent="center"
|
|
60
66
|
sx={{ width: "max-content", maxWidth: "600px", zIndex: 1 }}
|
|
61
67
|
>
|
|
68
|
+
{logoImage && (
|
|
69
|
+
<StrapiImage
|
|
70
|
+
alt={logoImage.alternativeText}
|
|
71
|
+
height={logoImage.height || 100}
|
|
72
|
+
style={logoImage.style || {}}
|
|
73
|
+
src={logoImage.url}
|
|
74
|
+
width={logoImage.width || 100}
|
|
75
|
+
/>
|
|
76
|
+
)}
|
|
62
77
|
<Typography variant="h1" align="center">
|
|
63
78
|
{heading}
|
|
64
79
|
</Typography>
|
package/src/components/Page.js
CHANGED
|
@@ -6,6 +6,8 @@ import TextImageSection from "./TextImageSection.tsx";
|
|
|
6
6
|
import { HeroSection } from "./HeroSection.tsx";
|
|
7
7
|
import { FeatureSection } from "./FeaturesSection.tsx";
|
|
8
8
|
import { IconSection } from "./IconSection.tsx";
|
|
9
|
+
import { Box } from "@mui/material";
|
|
10
|
+
import ContactForm from "./ContactForm.tsx";
|
|
9
11
|
|
|
10
12
|
function blockRenderer(block) {
|
|
11
13
|
switch (block.__component) {
|
|
@@ -13,21 +15,24 @@ function blockRenderer(block) {
|
|
|
13
15
|
return <HeroSection key={block.id} data={block} />;
|
|
14
16
|
case "layout.features-section":
|
|
15
17
|
return <FeatureSection key={block.id} data={block} />;
|
|
18
|
+
case "layout.contact-section":
|
|
19
|
+
return <ContactForm key={block.id} data={block} />;
|
|
16
20
|
case "layout.text-image-section":
|
|
17
21
|
return <TextImageSection key={block.id} data={block} />;
|
|
18
22
|
case "layout.icon-section":
|
|
19
23
|
return <IconSection key={block.id} data={block} />;
|
|
24
|
+
|
|
20
25
|
default:
|
|
21
26
|
return null;
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
|
|
25
|
-
function Page({ blocks }) {
|
|
30
|
+
function Page({ blocks, sx }) {
|
|
26
31
|
if (!blocks) {
|
|
27
32
|
return <p>No sections found</p>;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
return
|
|
35
|
+
return <Box sx={{ ...sx }}>{blocks.map(blockRenderer)}</Box>;
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
Page.propTypes = {
|
|
@@ -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 */
|
package/src/index.js
CHANGED
|
@@ -10,6 +10,6 @@ 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";
|
|
@@ -7,8 +7,8 @@ export default {
|
|
|
7
7
|
// argTypes: { numberOfChildren: { type: "number" } },
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
const Template = ({ title, description, blocks, ...args }) => (
|
|
11
|
-
<Page title={title} description={description} blocks={blocks} />
|
|
10
|
+
const Template = ({ title, description, blocks, sx, ...args }) => (
|
|
11
|
+
<Page title={title} description={description} blocks={blocks} sx={sx} />
|
|
12
12
|
);
|
|
13
13
|
|
|
14
14
|
export const HelloWorld = Template.bind({});
|
|
@@ -21,11 +21,174 @@ HelloWorld.args = {
|
|
|
21
21
|
__component: "layout.hero-section",
|
|
22
22
|
heading: "UMWD",
|
|
23
23
|
subHeading: "A place for all your resources",
|
|
24
|
+
bgImage: {
|
|
25
|
+
id: 3,
|
|
26
|
+
url: "https://via.placeholder.com/100",
|
|
27
|
+
alternativeText: "UMWD",
|
|
28
|
+
},
|
|
29
|
+
logoImage: {
|
|
30
|
+
id: 3,
|
|
31
|
+
url: "/uploads/logo_decorated_ad284d33ef.png",
|
|
32
|
+
alternativeText: "UMWD",
|
|
33
|
+
width: 250,
|
|
34
|
+
height: 250,
|
|
35
|
+
},
|
|
36
|
+
link: {
|
|
37
|
+
id: 3,
|
|
38
|
+
url: "/resources",
|
|
39
|
+
text: "Resources",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 2,
|
|
44
|
+
__component: "layout.features-section",
|
|
45
|
+
title: "AMH",
|
|
46
|
+
description: "A place for all your resources",
|
|
47
|
+
feature: [
|
|
48
|
+
{
|
|
49
|
+
id: 1,
|
|
50
|
+
heading: "AIR AMBULANCE",
|
|
51
|
+
subHeading:
|
|
52
|
+
"All our aircraft providers are operational around the clock to ensure the patient gets home the fastest way. Our air ambulances are specifically modified to the highest medical standard. To ensure that patients who are in need of repatriation or evacuation can be transported as efficiently as possible. While upholding the highest international standards for medical treatment during the flight. Our aircrafts can carry up to two stretchers if needed and carry an oxygen capacity of ??? liters. Depending on the patient’s needs, travel distance and urgency of transport, the best type of air ambulance will be advised and provided.",
|
|
53
|
+
icon: "CLOUD_ICON",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 2,
|
|
57
|
+
heading: "BED TO BED",
|
|
58
|
+
subHeading:
|
|
59
|
+
"We offer bed to bed service. Where we will pick up the patient at the hospital of origin and also bring the patient to the receiving hospital with our medical team. This guarantees the best quality handover to the medical team that will take over the care of the patient at home.",
|
|
60
|
+
icon: "CHECK_ICON",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 3,
|
|
64
|
+
heading: "COMMERCIAL AIRLINE MEDICAL ESCORT",
|
|
65
|
+
subHeading:
|
|
66
|
+
"Medical transfer by commercial airline is a safe and more cost effective way to travel, if transport by air ambulance is not needed. We can provide medical escorts for necessary treatment and support, to keep the patient safe and comfortable during the flight. Depending on the patient’s diagnosis and condition and also flight options. Transport can be done in first class, business class or with a stretcher in economy class. Our team will help you pick the best way of transport.",
|
|
67
|
+
icon: "CLOCK_ICON",
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 1,
|
|
73
|
+
__component: "layout.text-image-section",
|
|
74
|
+
title: "Hello Mars",
|
|
24
75
|
image: {
|
|
76
|
+
url: "/uploads/man_in_circle_icon_6c77b6d3e4.png",
|
|
77
|
+
alt: "Hello Mars",
|
|
78
|
+
},
|
|
79
|
+
text: "**Hello Mars,** \n a distant red planet that has captured the imagination of humanity for centuries. As we gaze upon your mysterious surface from Earth, we can't help but wonder about the secrets you hold. Hello to the vast landscapes of rust-colored terrain, the towering volcanoes, and the enigmatic canyons that weave across your surface. *Hello Mars,* a planet that has been the focus of numerous space missions, each one aiming to unveil the mysteries of your past and present. From the iconic rovers tirelessly traversing your rocky landscapes to the orbiters capturing breathtaking images from above, we extend our greetings to the scientific endeavors that seek to understand your geology, climate, and potential for life. <br /> <br /> *Hello Mars,* a beacon of human exploration and curiosity. The dreams of setting foot on your soil have fueled the aspirations of generations, and with each technological leap, the possibility of humans visiting you becomes more tangible. The prospect of a human settlement on Mars brings excitement, challenges, and the promise of a new chapter in our interplanetary journey. <br /> <br /> *Hello Mars,* a testament to the indomitable human spirit that constantly seeks to push the boundaries of what is possible. As we continue to study, explore, and dream about the mysteries you hold, we are reminded of the vastness of the cosmos and the endless opportunities for discovery that lie beyond our home planet.",
|
|
80
|
+
reverse: true,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 1,
|
|
84
|
+
__component: "layout.icon-section",
|
|
85
|
+
icon: [
|
|
86
|
+
{
|
|
87
|
+
id: 1,
|
|
88
|
+
title: "INTENSIVE CARE UNIT",
|
|
89
|
+
text: "Intensive care unit with stretcher and vacuum mattress (adjustable backrest) | oxygen supply, compressed air and vacuum pump | 110/230V + 12/24V power supplies",
|
|
90
|
+
icon: "CLOCK_ICON",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 2,
|
|
94
|
+
title: "OXYGEN CAPACITY",
|
|
95
|
+
text: "4.000 l (per intensive care unit) plus up to 10.800 l in carbon high pressure cylinders",
|
|
96
|
+
icon: "CHECK_ICON",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 3,
|
|
100
|
+
title: "RESPIRATION SYSTEM",
|
|
101
|
+
text: "Hamilton T1 | or Hamilton H900 humidifier for: adults, pediatrics, neonates",
|
|
102
|
+
icon: "CLOUD_ICON",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 4,
|
|
106
|
+
title: "MONITORING",
|
|
107
|
+
text: "Zoll X Series | T1 (invasive and non-invasive blood pressure measurement, pulse oxymetry, capnometry, temperature measurement, ECG monitoring)",
|
|
108
|
+
icon: "CLOCK_ICON",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 5,
|
|
112
|
+
title: "DEFIBRILLATOR",
|
|
113
|
+
text: "Zoll X Series (with external cardiac pacemaker)",
|
|
114
|
+
icon: "CHECK_ICON",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: 6,
|
|
118
|
+
title: "AED",
|
|
119
|
+
text: "Heartsine 350 P",
|
|
120
|
+
icon: "CLOUD_ICON",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: 7,
|
|
124
|
+
title: "SYRINGE PUMPS",
|
|
125
|
+
text: "Fresenius Agilia Injectomat",
|
|
126
|
+
icon: "CLOCK_ICON",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 8,
|
|
130
|
+
title: "INFUSION PUMPS",
|
|
131
|
+
text: "Fresenus Agilia Volumat",
|
|
132
|
+
icon: "CHECK_ICON",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 9,
|
|
136
|
+
title: "PORTABLE SUCTION UNITS",
|
|
137
|
+
text: "Laerdal LCSU 4",
|
|
138
|
+
icon: "CLOUD_ICON",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: 10,
|
|
142
|
+
title: "EMERGENCY ALS BAGS",
|
|
143
|
+
text: "Extensive equipment for emergency and intensive care (e.g. videolaryngoscop, chest tube, urinary catheter, arterial catheter, surgical instruments, coniotomy, central venous line, care products)",
|
|
144
|
+
icon: "CLOCK_ICON",
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: 11,
|
|
148
|
+
title: "MEDICATION",
|
|
149
|
+
text: "Standard medication for emergency and intensiv care medicine | narcotics | antidotes",
|
|
150
|
+
icon: "CHECK_ICON",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: 12,
|
|
154
|
+
title: "PEDIATRIC EQUIPMENT",
|
|
155
|
+
text: "Babypod transport incubator I & II with Kanmed BabyWarmer | Incubator Dräger | intensive care backpack pediatric | additional emergency and intensive care medicine",
|
|
156
|
+
icon: "CLOUD_ICON",
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const AMH = Template.bind({});
|
|
164
|
+
|
|
165
|
+
AMH.args = {
|
|
166
|
+
sx: {
|
|
167
|
+
header: {
|
|
168
|
+
h1: {
|
|
169
|
+
color: "red",
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
title: "Hello Cruel World",
|
|
174
|
+
blocks: [
|
|
175
|
+
{
|
|
176
|
+
id: 3,
|
|
177
|
+
__component: "layout.hero-section",
|
|
178
|
+
heading: "UMWD",
|
|
179
|
+
subHeading: "A place for all your resources",
|
|
180
|
+
bgImage: {
|
|
25
181
|
id: 3,
|
|
26
182
|
url: "https://via.placeholder.com/100",
|
|
27
183
|
alternativeText: "UMWD",
|
|
28
184
|
},
|
|
185
|
+
logoImage: {
|
|
186
|
+
id: 3,
|
|
187
|
+
url: "/uploads/logo_decorated_ad284d33ef.png",
|
|
188
|
+
alternativeText: "UMWD",
|
|
189
|
+
width: 250,
|
|
190
|
+
height: 250,
|
|
191
|
+
},
|
|
29
192
|
link: {
|
|
30
193
|
id: 3,
|
|
31
194
|
url: "/resources",
|
|
@@ -150,5 +313,10 @@ HelloWorld.args = {
|
|
|
150
313
|
},
|
|
151
314
|
],
|
|
152
315
|
},
|
|
316
|
+
{
|
|
317
|
+
id: 1,
|
|
318
|
+
__component: "layout.contact-section",
|
|
319
|
+
title: "Contact us",
|
|
320
|
+
},
|
|
153
321
|
],
|
|
154
322
|
};
|
|
@@ -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;
|