@stackshift-ui/contact 6.0.3 → 6.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +16 -15
- package/src/contact.test.tsx +13 -0
- package/src/contact.tsx +40 -0
- package/src/contact_a.tsx +253 -0
- package/src/contact_b.tsx +149 -0
- package/src/helper/index.ts +12 -0
- package/src/index.ts +6 -0
- package/src/types.ts +412 -0
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackshift-ui/contact",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "6.0.
|
|
4
|
+
"version": "6.0.4",
|
|
5
5
|
"private": false,
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"module": "./dist/index.mjs",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
|
-
"dist/**"
|
|
11
|
+
"dist/**",
|
|
12
|
+
"src"
|
|
12
13
|
],
|
|
13
14
|
"author": "WebriQ <info@webriq.com>",
|
|
14
15
|
"devDependencies": {
|
|
@@ -34,20 +35,20 @@
|
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"@portabletext/react": "^3.1.0",
|
|
36
37
|
"classnames": "^2.5.1",
|
|
37
|
-
"@stackshift-ui/button": "6.0.
|
|
38
|
-
"@stackshift-ui/card": "6.0.
|
|
39
|
-
"@stackshift-ui/
|
|
40
|
-
"@stackshift-ui/
|
|
41
|
-
"@stackshift-ui/form
|
|
42
|
-
"@stackshift-ui/
|
|
43
|
-
"@stackshift-ui/
|
|
44
|
-
"@stackshift-ui/link": "6.0.2",
|
|
45
|
-
"@stackshift-ui/social-icons": "6.0.2",
|
|
46
|
-
"@stackshift-ui/section": "6.0.2",
|
|
47
|
-
"@stackshift-ui/form": "6.0.2",
|
|
48
|
-
"@stackshift-ui/text": "6.0.2",
|
|
38
|
+
"@stackshift-ui/button": "6.0.3",
|
|
39
|
+
"@stackshift-ui/card": "6.0.3",
|
|
40
|
+
"@stackshift-ui/container": "6.0.3",
|
|
41
|
+
"@stackshift-ui/flex": "6.0.3",
|
|
42
|
+
"@stackshift-ui/form": "6.0.3",
|
|
43
|
+
"@stackshift-ui/image": "6.0.3",
|
|
44
|
+
"@stackshift-ui/link": "6.0.3",
|
|
49
45
|
"@stackshift-ui/scripts": "6.0.2",
|
|
50
|
-
"@stackshift-ui/
|
|
46
|
+
"@stackshift-ui/heading": "6.0.3",
|
|
47
|
+
"@stackshift-ui/section": "6.0.3",
|
|
48
|
+
"@stackshift-ui/system": "6.0.3",
|
|
49
|
+
"@stackshift-ui/social-icons": "6.0.3",
|
|
50
|
+
"@stackshift-ui/text": "6.0.3",
|
|
51
|
+
"@stackshift-ui/form-field": "6.0.4"
|
|
51
52
|
},
|
|
52
53
|
"peerDependencies": {
|
|
53
54
|
"@stackshift-ui/system": ">=0.0.0",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { cleanup, render, screen } from "@testing-library/react";
|
|
2
|
+
import { afterEach, describe, test } from "vitest";
|
|
3
|
+
import { Contact } from "./contact";
|
|
4
|
+
|
|
5
|
+
describe.concurrent("contact", () => {
|
|
6
|
+
afterEach(cleanup);
|
|
7
|
+
|
|
8
|
+
test.skip("Dummy test - test if renders without errors", ({ expect }) => {
|
|
9
|
+
const clx = "my-class";
|
|
10
|
+
render(<Contact />);
|
|
11
|
+
expect(screen.getByTestId("{ kebabCase name }}").classList).toContain(clx);
|
|
12
|
+
});
|
|
13
|
+
});
|
package/src/contact.tsx
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { lazy } from "react";
|
|
2
|
+
import { SectionsProps, SocialLink, Form } from "./types";
|
|
3
|
+
|
|
4
|
+
const Variants = {
|
|
5
|
+
variant_a: lazy(() => import("./contact_a")),
|
|
6
|
+
variant_b: lazy(() => import("./contact_b")),
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export interface ContactProps {
|
|
10
|
+
title?: string;
|
|
11
|
+
contactDescription?: string;
|
|
12
|
+
officeInformation?: string;
|
|
13
|
+
contactEmail?: string;
|
|
14
|
+
contactNumber?: string;
|
|
15
|
+
socialLinks?: SocialLink[];
|
|
16
|
+
form?: Form;
|
|
17
|
+
block?: any;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const displayName = "Contact";
|
|
21
|
+
|
|
22
|
+
export const Contact: React.FC<SectionsProps> = ({ data }) => {
|
|
23
|
+
const variant = data?.variant;
|
|
24
|
+
const Variant = variant && Variants[variant as keyof typeof Variants];
|
|
25
|
+
|
|
26
|
+
const props = {
|
|
27
|
+
title: data?.variants?.title ?? undefined,
|
|
28
|
+
contactDescription: data?.variants?.contactDescription ?? undefined,
|
|
29
|
+
officeInformation: data?.variants?.officeInformation ?? undefined,
|
|
30
|
+
contactEmail: data?.variants?.contactEmail ?? undefined,
|
|
31
|
+
contactNumber: data?.variants?.contactNumber ?? undefined,
|
|
32
|
+
socialLinks: data?.variants?.socialLinks ?? undefined,
|
|
33
|
+
form: data?.variants?.form ?? undefined,
|
|
34
|
+
block: data?.variants?.block ?? undefined,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return Variant ? <Variant {...props} /> : null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
Contact.displayName = displayName;
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { PortableText, PortableTextComponents } from "@portabletext/react";
|
|
2
|
+
import { Button } from "@stackshift-ui/button";
|
|
3
|
+
import { Container } from "@stackshift-ui/container";
|
|
4
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
5
|
+
import { Form } from "@stackshift-ui/form";
|
|
6
|
+
import { FormField } from "@stackshift-ui/form-field";
|
|
7
|
+
import { Heading } from "@stackshift-ui/heading";
|
|
8
|
+
import { Link } from "@stackshift-ui/link";
|
|
9
|
+
import { Section } from "@stackshift-ui/section";
|
|
10
|
+
import { SocialIcons } from "@stackshift-ui/social-icons";
|
|
11
|
+
import { Text } from "@stackshift-ui/text";
|
|
12
|
+
import React from "react";
|
|
13
|
+
|
|
14
|
+
import { ContactProps } from ".";
|
|
15
|
+
import { thankYouPageLink } from "./helper";
|
|
16
|
+
import { SocialLink, Form as iForm, Socials as iSocials } from "./types";
|
|
17
|
+
|
|
18
|
+
export default function Contact_A({
|
|
19
|
+
contactDescription,
|
|
20
|
+
officeInformation,
|
|
21
|
+
contactEmail,
|
|
22
|
+
contactNumber,
|
|
23
|
+
socialLinks,
|
|
24
|
+
form,
|
|
25
|
+
block,
|
|
26
|
+
title,
|
|
27
|
+
}: ContactProps) {
|
|
28
|
+
return (
|
|
29
|
+
<Section className="py-20 bg-background">
|
|
30
|
+
<Container maxWidth={1280}>
|
|
31
|
+
<Flex direction="col" gap={8} justify="between" className="lg:flex-row">
|
|
32
|
+
<Flex direction="col" gap={8} className="px-10 w-full basis-1/2">
|
|
33
|
+
<ContactTitleAndDescription
|
|
34
|
+
form={form}
|
|
35
|
+
title={title}
|
|
36
|
+
contactDescription={contactDescription}
|
|
37
|
+
/>
|
|
38
|
+
<OfficeInformation
|
|
39
|
+
officeInformation={officeInformation}
|
|
40
|
+
contactEmail={contactEmail}
|
|
41
|
+
contactNumber={contactNumber}
|
|
42
|
+
/>
|
|
43
|
+
<SocialLinksCard socialLinks={socialLinks} />
|
|
44
|
+
</Flex>
|
|
45
|
+
<FormFields form={form} block={block} blockCustomization={blockCustomization} />
|
|
46
|
+
</Flex>
|
|
47
|
+
</Container>
|
|
48
|
+
</Section>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function ContactTitleAndDescription({
|
|
53
|
+
form,
|
|
54
|
+
title,
|
|
55
|
+
contactDescription,
|
|
56
|
+
}: {
|
|
57
|
+
form?: iForm;
|
|
58
|
+
title?: string;
|
|
59
|
+
contactDescription?: string;
|
|
60
|
+
}) {
|
|
61
|
+
return (
|
|
62
|
+
<div>
|
|
63
|
+
{(form?.name || title) && <Heading>{form?.name || title}</Heading>}
|
|
64
|
+
{contactDescription && (
|
|
65
|
+
<Text muted className="mt-5 leading-loose text-gray-700">
|
|
66
|
+
{contactDescription}
|
|
67
|
+
</Text>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function OfficeInformation({
|
|
74
|
+
officeInformation,
|
|
75
|
+
contactEmail,
|
|
76
|
+
contactNumber,
|
|
77
|
+
}: {
|
|
78
|
+
officeInformation?: string;
|
|
79
|
+
contactEmail?: string;
|
|
80
|
+
contactNumber?: string;
|
|
81
|
+
}) {
|
|
82
|
+
if (!officeInformation) return null;
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<Flex gap={8} justify="between" className="flex-col w-full md:flex-row">
|
|
86
|
+
<div>
|
|
87
|
+
<Heading type="h2">{"Office"}</Heading>
|
|
88
|
+
{officeInformation && (
|
|
89
|
+
<Text className="mt-3" muted>
|
|
90
|
+
{officeInformation}
|
|
91
|
+
</Text>
|
|
92
|
+
)}
|
|
93
|
+
</div>
|
|
94
|
+
<div>
|
|
95
|
+
<Heading type="h2">{"Contacts"}</Heading>
|
|
96
|
+
<Text className="my-3" muted>
|
|
97
|
+
{contactEmail && <Link href={`mailto:${contactEmail}`}>{contactEmail}</Link>}
|
|
98
|
+
</Text>
|
|
99
|
+
<Text muted>
|
|
100
|
+
{contactNumber && <Link href={`tel:${contactNumber}`}>{contactNumber}</Link>}
|
|
101
|
+
</Text>
|
|
102
|
+
</div>
|
|
103
|
+
</Flex>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function SocialLinksCard({ socialLinks }: { socialLinks?: SocialLink[] }) {
|
|
108
|
+
if (!socialLinks) return null;
|
|
109
|
+
return (
|
|
110
|
+
<div className="w-full md:w-1/3 lg:w-full">
|
|
111
|
+
<Heading type="h2" fontSize="2xl" className="mb-2">
|
|
112
|
+
Socials
|
|
113
|
+
</Heading>
|
|
114
|
+
<Flex gap={4}>
|
|
115
|
+
<SocialLinks socialLinks={socialLinks} />
|
|
116
|
+
</Flex>
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function SocialLinks({ socialLinks }: { socialLinks?: SocialLink[] }) {
|
|
122
|
+
if (!socialLinks) return null;
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<React.Fragment>
|
|
126
|
+
{socialLinks?.map(social => (
|
|
127
|
+
<Link
|
|
128
|
+
aria-label={social?.socialMedia || social?.socialMediaPlatform || ""}
|
|
129
|
+
className="inline-block mr-4 rounded hover:bg-gray-100"
|
|
130
|
+
target="_blank"
|
|
131
|
+
rel="noopener noreferrer"
|
|
132
|
+
href={social?.socialMediaLink ?? "/page-not-found"}
|
|
133
|
+
key={social?._key}>
|
|
134
|
+
{social?.socialMediaLink && <SocialIcons social={social.socialMedia as iSocials} />}
|
|
135
|
+
</Link>
|
|
136
|
+
))}
|
|
137
|
+
</React.Fragment>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function FormFields({
|
|
142
|
+
form,
|
|
143
|
+
block,
|
|
144
|
+
blockCustomization,
|
|
145
|
+
}: {
|
|
146
|
+
form?: iForm;
|
|
147
|
+
block: any;
|
|
148
|
+
blockCustomization: PortableTextComponents;
|
|
149
|
+
}) {
|
|
150
|
+
if (!form) return null;
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div className="w-full px-5 sm:px-10 lg:w-1/2 lg:px-0 lg:pl-10 lg:pt-10">
|
|
154
|
+
{form?.fields && (
|
|
155
|
+
<Form
|
|
156
|
+
id={form?.id ?? undefined}
|
|
157
|
+
name="Contact-VariantA-Form"
|
|
158
|
+
className="lg:mx-auto lg:max-w-md text-xs space-y-3 font-semibold"
|
|
159
|
+
thankyouPage={thankYouPageLink(form?.thankYouPage)}>
|
|
160
|
+
{form?.fields?.map((formFields, index) => (
|
|
161
|
+
<div key={index}>
|
|
162
|
+
{formFields?.type === "inputCheckbox" ? (
|
|
163
|
+
<FormField
|
|
164
|
+
noLabel
|
|
165
|
+
name={formFields?.name ?? ""}
|
|
166
|
+
placeholder={formFields?.placeholder}
|
|
167
|
+
required={formFields?.isRequired}
|
|
168
|
+
{...formFields}
|
|
169
|
+
/>
|
|
170
|
+
) : (
|
|
171
|
+
<FormField
|
|
172
|
+
noLabel
|
|
173
|
+
variant="primary"
|
|
174
|
+
name={formFields?.name ?? ""}
|
|
175
|
+
placeholder={formFields?.name}
|
|
176
|
+
required={formFields?.isRequired}
|
|
177
|
+
{...formFields}
|
|
178
|
+
/>
|
|
179
|
+
)}
|
|
180
|
+
</div>
|
|
181
|
+
))}
|
|
182
|
+
<div className="items-center sm:flex sm:justify-between">
|
|
183
|
+
{block && (
|
|
184
|
+
<div className="inline-flex mt-2">
|
|
185
|
+
<input
|
|
186
|
+
aria-label="Agree to terms"
|
|
187
|
+
className="mt-1 mr-2"
|
|
188
|
+
type="checkbox"
|
|
189
|
+
id="terms"
|
|
190
|
+
name="terms"
|
|
191
|
+
defaultValue={1}
|
|
192
|
+
required
|
|
193
|
+
/>
|
|
194
|
+
<span className="text-sm text-gray-500 font-semibold">
|
|
195
|
+
<PortableText
|
|
196
|
+
value={block}
|
|
197
|
+
components={blockCustomization}
|
|
198
|
+
onMissingComponent={false} // Disabling warnings / handling unknown types
|
|
199
|
+
/>
|
|
200
|
+
</span>
|
|
201
|
+
</div>
|
|
202
|
+
)}
|
|
203
|
+
<div>
|
|
204
|
+
<div className="webriq-recaptcha" />
|
|
205
|
+
</div>
|
|
206
|
+
{form?.buttonLabel && (
|
|
207
|
+
<Button
|
|
208
|
+
as="button"
|
|
209
|
+
ariaLabel={form?.buttonLabel ?? "Contact form submit button"}
|
|
210
|
+
className="inline-block px-6 py-2 mt-5 font-bold leading-loose text-white transition duration-200 rounded-global bg-primary hover:bg-primary-foreground sm:mt-0"
|
|
211
|
+
type="submit">
|
|
212
|
+
{form?.buttonLabel}
|
|
213
|
+
</Button>
|
|
214
|
+
)}
|
|
215
|
+
</div>
|
|
216
|
+
</Form>
|
|
217
|
+
)}
|
|
218
|
+
</div>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// block styling as props to `components` of the PortableText component
|
|
223
|
+
const blockCustomization: PortableTextComponents = {
|
|
224
|
+
marks: {
|
|
225
|
+
internalLink: ({ children, value }) => (
|
|
226
|
+
<Link
|
|
227
|
+
aria-label={value.href ?? "internal link"}
|
|
228
|
+
style={{ color: "red" }}
|
|
229
|
+
href={value.slug.current}>
|
|
230
|
+
{children}
|
|
231
|
+
</Link>
|
|
232
|
+
),
|
|
233
|
+
link: ({ children, value }) =>
|
|
234
|
+
value.blank ? (
|
|
235
|
+
<Link
|
|
236
|
+
aria-label={value.href ?? "external link"}
|
|
237
|
+
href={value.href}
|
|
238
|
+
target="_blank"
|
|
239
|
+
rel="noopener noreferrer">
|
|
240
|
+
{children}
|
|
241
|
+
</Link>
|
|
242
|
+
) : (
|
|
243
|
+
<Link
|
|
244
|
+
aria-label={value.href ?? "external link"}
|
|
245
|
+
style={{ color: "blue" }}
|
|
246
|
+
href={value.href}>
|
|
247
|
+
{children}
|
|
248
|
+
</Link>
|
|
249
|
+
),
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export { Contact_A };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Card } from "@stackshift-ui/card";
|
|
2
|
+
import { Container } from "@stackshift-ui/container";
|
|
3
|
+
import { Flex } from "@stackshift-ui/flex";
|
|
4
|
+
import { Heading } from "@stackshift-ui/heading";
|
|
5
|
+
import { Image } from "@stackshift-ui/image";
|
|
6
|
+
import { Link } from "@stackshift-ui/link";
|
|
7
|
+
import { Section } from "@stackshift-ui/section";
|
|
8
|
+
import { SocialIcons } from "@stackshift-ui/social-icons";
|
|
9
|
+
import { Text } from "@stackshift-ui/text";
|
|
10
|
+
import React from "react";
|
|
11
|
+
import { ContactProps } from ".";
|
|
12
|
+
import { Socials } from "./types";
|
|
13
|
+
|
|
14
|
+
export default function Contact_B({
|
|
15
|
+
title,
|
|
16
|
+
contactDescription,
|
|
17
|
+
officeInformation,
|
|
18
|
+
contactNumber,
|
|
19
|
+
contactEmail,
|
|
20
|
+
socialLinks,
|
|
21
|
+
}: ContactProps) {
|
|
22
|
+
return (
|
|
23
|
+
<Section className="py-20 bg-background">
|
|
24
|
+
<Container maxWidth={1280}>
|
|
25
|
+
<ContactHeader title={title} description={contactDescription} />
|
|
26
|
+
<Container maxWidth={960}>
|
|
27
|
+
<ContactDetails
|
|
28
|
+
officeInformation={officeInformation}
|
|
29
|
+
contactNumber={contactNumber}
|
|
30
|
+
contactEmail={contactEmail}
|
|
31
|
+
socialLinks={socialLinks}
|
|
32
|
+
/>
|
|
33
|
+
</Container>
|
|
34
|
+
</Container>
|
|
35
|
+
</Section>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function ContactHeader({ title, description }: { title?: string; description?: string }) {
|
|
40
|
+
return (
|
|
41
|
+
<div className="mb-16 text-center">
|
|
42
|
+
{title ? (
|
|
43
|
+
<Heading type="h1" fontSize="3xl">
|
|
44
|
+
{title}
|
|
45
|
+
</Heading>
|
|
46
|
+
) : null}
|
|
47
|
+
{description ? <Text muted>{description}</Text> : null}
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function ContactDetails({
|
|
53
|
+
officeInformation,
|
|
54
|
+
contactEmail,
|
|
55
|
+
contactNumber,
|
|
56
|
+
socialLinks,
|
|
57
|
+
}: {
|
|
58
|
+
officeInformation?: string;
|
|
59
|
+
contactEmail?: string;
|
|
60
|
+
contactNumber?: string;
|
|
61
|
+
socialLinks?: any;
|
|
62
|
+
}) {
|
|
63
|
+
return (
|
|
64
|
+
<Flex className="flex-col lg:flex-row" gap={4} justify="between" align="stretch">
|
|
65
|
+
{officeInformation ? <OfficeInformationCard officeInformation={officeInformation} /> : null}
|
|
66
|
+
|
|
67
|
+
{contactEmail || contactNumber ? (
|
|
68
|
+
<ContactsCard contactEmail={contactEmail} contactNumber={contactNumber} />
|
|
69
|
+
) : null}
|
|
70
|
+
|
|
71
|
+
{socialLinks ? <SocialLinksCard socialLinks={socialLinks} /> : null}
|
|
72
|
+
</Flex>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function OfficeInformationCard({ officeInformation }: { officeInformation: string }) {
|
|
77
|
+
return (
|
|
78
|
+
<Card className="w-full p-12 text-center bg-white md:p-16 lg:p-20">
|
|
79
|
+
<Heading type="h2" fontSize="2xl" className="mb-16">
|
|
80
|
+
Office
|
|
81
|
+
</Heading>
|
|
82
|
+
<Text muted>{officeInformation}</Text>
|
|
83
|
+
</Card>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function ContactsCard({
|
|
88
|
+
contactEmail,
|
|
89
|
+
contactNumber,
|
|
90
|
+
}: {
|
|
91
|
+
contactEmail?: string;
|
|
92
|
+
contactNumber?: string;
|
|
93
|
+
}) {
|
|
94
|
+
return (
|
|
95
|
+
<Card className="w-full p-12 bg-white md:p-16 lg:p-20 text-center">
|
|
96
|
+
<Heading type="h2" fontSize="2xl" className="mb-16 ">
|
|
97
|
+
Contacts
|
|
98
|
+
</Heading>
|
|
99
|
+
<Text className="mb-2" muted>
|
|
100
|
+
{contactEmail ? <Link href={`mailto:${contactEmail}`}>{contactEmail}</Link> : null}
|
|
101
|
+
</Text>
|
|
102
|
+
<Text muted>
|
|
103
|
+
{contactNumber ? <Link href={`tel:${contactNumber}`}>{contactNumber}</Link> : null}
|
|
104
|
+
</Text>
|
|
105
|
+
</Card>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function SocialLinksCard({ socialLinks }: any) {
|
|
110
|
+
return (
|
|
111
|
+
<Card className="w-full p-12 text-center bg-white md:p-16 lg:p-20">
|
|
112
|
+
<Heading className="mb-16" fontSize="2xl" type="h2">
|
|
113
|
+
Socials
|
|
114
|
+
</Heading>
|
|
115
|
+
<Flex justify="center">
|
|
116
|
+
<SocialLinks socialLinks={socialLinks} />
|
|
117
|
+
</Flex>
|
|
118
|
+
</Card>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function SocialLinks({ socialLinks }: any) {
|
|
123
|
+
return (
|
|
124
|
+
<React.Fragment>
|
|
125
|
+
{socialLinks?.map((social: any) => (
|
|
126
|
+
<Link
|
|
127
|
+
aria-label={social?.socialMedia || social?.socialMediaPlatform}
|
|
128
|
+
className="inline-block mr-4"
|
|
129
|
+
target="_blank"
|
|
130
|
+
rel="noopener noreferrer"
|
|
131
|
+
href={social?.socialMediaLink}
|
|
132
|
+
key={social?._key}>
|
|
133
|
+
{social?.socialMediaIcon?.image ? (
|
|
134
|
+
<Image
|
|
135
|
+
src={social?.socialMediaIcon?.image}
|
|
136
|
+
width={24}
|
|
137
|
+
height={24}
|
|
138
|
+
alt={social?.socialMediaIcon?.alt ?? "contact-socialMedia-icon"}
|
|
139
|
+
/>
|
|
140
|
+
) : (
|
|
141
|
+
<SocialIcons social={social.socialMedia as Socials} />
|
|
142
|
+
)}
|
|
143
|
+
</Link>
|
|
144
|
+
))}
|
|
145
|
+
</React.Fragment>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export { Contact_B };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// WebriQ form redirect thank you page on successful submission
|
|
2
|
+
export const thankYouPageLink = (link: any) => {
|
|
3
|
+
if (!link) {
|
|
4
|
+
return "/thank-you";
|
|
5
|
+
} else {
|
|
6
|
+
if (link?.linkType === "linkInternal") {
|
|
7
|
+
return `/${link?.internalLink}`;
|
|
8
|
+
} else {
|
|
9
|
+
return link?.externalLink;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
};
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
export type StyleVariants<T extends string> = Record<T, string>;
|
|
2
|
+
|
|
3
|
+
export type Socials = "facebook" | "instagram" | "youtube" | "linkedin" | "twitter";
|
|
4
|
+
export interface MainImage {
|
|
5
|
+
image: string;
|
|
6
|
+
alt?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface LabeledRoute extends ConditionalLink {
|
|
10
|
+
ariaLabel?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
linkTarget?: string;
|
|
13
|
+
linkType?: string;
|
|
14
|
+
_type?: string;
|
|
15
|
+
linkInternal?: any;
|
|
16
|
+
}
|
|
17
|
+
export interface ConditionalLink {
|
|
18
|
+
type?: string;
|
|
19
|
+
internalLink?: string | null;
|
|
20
|
+
externalLink?: string | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface StatItems {
|
|
24
|
+
label?: string;
|
|
25
|
+
mainImage?: MainImage;
|
|
26
|
+
value?: string;
|
|
27
|
+
_key?: string;
|
|
28
|
+
_type?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface Logo extends ConditionalLink {
|
|
32
|
+
alt?: string;
|
|
33
|
+
linkTarget?: string;
|
|
34
|
+
image?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface Images {
|
|
38
|
+
image?: string;
|
|
39
|
+
_key?: string;
|
|
40
|
+
_type?: string;
|
|
41
|
+
alt?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ContactDetails {
|
|
45
|
+
addressInfo?: string;
|
|
46
|
+
contactInfo?: string;
|
|
47
|
+
emailInfo?: string;
|
|
48
|
+
_key?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface SocialLink {
|
|
52
|
+
socialMedia?: string | null;
|
|
53
|
+
socialMediaLink?: string | null;
|
|
54
|
+
_key?: string | null;
|
|
55
|
+
_type?: string | null;
|
|
56
|
+
socialMediaIcon?: {
|
|
57
|
+
alt?: string;
|
|
58
|
+
image?: string;
|
|
59
|
+
} | null;
|
|
60
|
+
socialMediaPlatform?: string | null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface LabeledRouteWithKey extends LabeledRoute {
|
|
64
|
+
_key?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface ArrayOfImageTitleAndText {
|
|
68
|
+
mainImage?: {
|
|
69
|
+
alt?: string;
|
|
70
|
+
image?: string;
|
|
71
|
+
};
|
|
72
|
+
plainText?: string;
|
|
73
|
+
title?: string;
|
|
74
|
+
_key?: string;
|
|
75
|
+
_type?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface FeaturedItem {
|
|
79
|
+
description?: string;
|
|
80
|
+
mainImage?: MainImage;
|
|
81
|
+
title?: string;
|
|
82
|
+
subtitle?: string;
|
|
83
|
+
_key?: string;
|
|
84
|
+
_type?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface ArrayOfTitleAndText {
|
|
88
|
+
_key?: string;
|
|
89
|
+
plainText?: string;
|
|
90
|
+
title?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface BlogPost extends SanityBody {
|
|
94
|
+
authors?: Author[] | null;
|
|
95
|
+
body?: any;
|
|
96
|
+
categories?: Category[] | null;
|
|
97
|
+
excerpt?: string | null;
|
|
98
|
+
link?: string | null;
|
|
99
|
+
mainImage?: string | null;
|
|
100
|
+
publishedAt?: string;
|
|
101
|
+
seo?: Seo | null;
|
|
102
|
+
slug?: SanitySlug | null;
|
|
103
|
+
title?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface Seo {
|
|
107
|
+
_type?: string;
|
|
108
|
+
seoTitle?: string;
|
|
109
|
+
seoDescription?: string;
|
|
110
|
+
seoImage?: string;
|
|
111
|
+
seoKeywords?: string;
|
|
112
|
+
seoSynonyms?: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface SanitySlug {
|
|
116
|
+
current?: string;
|
|
117
|
+
_type?: "slug";
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface SanityBody {
|
|
121
|
+
_createdAt?: string;
|
|
122
|
+
_id?: string;
|
|
123
|
+
_rev?: string;
|
|
124
|
+
_type?: string;
|
|
125
|
+
_updatedAt?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface Author extends SanityBody {
|
|
129
|
+
link?: string | null;
|
|
130
|
+
bio?: string | null;
|
|
131
|
+
name?: string | null;
|
|
132
|
+
slug?: SanitySlug | null;
|
|
133
|
+
image?: string | null;
|
|
134
|
+
profile?: {
|
|
135
|
+
alt: string;
|
|
136
|
+
image: string;
|
|
137
|
+
} | null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface Category extends SanityBody {
|
|
141
|
+
title?: string;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface Form {
|
|
145
|
+
id?: string | null;
|
|
146
|
+
buttonLabel?: string | null;
|
|
147
|
+
name?: string | null;
|
|
148
|
+
subtitle?: string | null;
|
|
149
|
+
fields?: FormFields[] | null;
|
|
150
|
+
thankYouPage?: ThankYouPage | null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface FormFields {
|
|
154
|
+
name?: string;
|
|
155
|
+
placeholder?: string;
|
|
156
|
+
pricingType?: string;
|
|
157
|
+
type?: FormTypes;
|
|
158
|
+
_key?: string;
|
|
159
|
+
_type?: string;
|
|
160
|
+
isRequired?: boolean;
|
|
161
|
+
label?: string;
|
|
162
|
+
items?: string[];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export type FormTypes =
|
|
166
|
+
| "inputText"
|
|
167
|
+
| "inputEmail"
|
|
168
|
+
| "inputPassword"
|
|
169
|
+
| "inputNumber"
|
|
170
|
+
| "textarea"
|
|
171
|
+
| "inputFile"
|
|
172
|
+
| "inputRadio"
|
|
173
|
+
| "inputCheckbox"
|
|
174
|
+
| "inputSelect";
|
|
175
|
+
|
|
176
|
+
export interface ThankYouPage {
|
|
177
|
+
externalLink?: string | null;
|
|
178
|
+
internalLink?: string | null;
|
|
179
|
+
linkInternal?: any;
|
|
180
|
+
linkTarget?: string;
|
|
181
|
+
linkType?: string;
|
|
182
|
+
type?: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
//Used on different sections
|
|
186
|
+
export interface SectionsProps {
|
|
187
|
+
template?: Template;
|
|
188
|
+
data?: Sections;
|
|
189
|
+
variant?: string | null | undefined;
|
|
190
|
+
schema?: Variants;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export interface Sections extends SanityBody {
|
|
194
|
+
label?: string;
|
|
195
|
+
variant?: string;
|
|
196
|
+
variants?: Variants;
|
|
197
|
+
_key?: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//*EDIT THIS SECTION WHEN CREATING/UPDATING SCHEMAS ON STUDIO */
|
|
201
|
+
export interface Variants {
|
|
202
|
+
template?: Template;
|
|
203
|
+
multipleMenus?: any;
|
|
204
|
+
arrayOfTitleAndText?: ArrayOfTitleAndText[] | null;
|
|
205
|
+
logo?: Logo | null;
|
|
206
|
+
primaryButton?: LabeledRoute | null;
|
|
207
|
+
secondaryButton?: LabeledRoute | null;
|
|
208
|
+
routes?: LabeledRouteWithKey[] | null;
|
|
209
|
+
menu?: LabeledRouteWithKey[] | null;
|
|
210
|
+
plans?: Plans[] | null;
|
|
211
|
+
formLinks?: LabeledRouteWithKey[] | null;
|
|
212
|
+
portfolios?: Portfolios[] | null;
|
|
213
|
+
portfoliosWithCategories?: PortfoliosWithCategories[] | null;
|
|
214
|
+
length?: number;
|
|
215
|
+
signInLink?: LabeledRoute | null;
|
|
216
|
+
signinLink?: LabeledRoute | null;
|
|
217
|
+
tags?: string[] | null;
|
|
218
|
+
posts?: BlogPost[] | null;
|
|
219
|
+
blogsPerPage?: number | null;
|
|
220
|
+
form?: Form | null;
|
|
221
|
+
collections?: Collection | null;
|
|
222
|
+
products?: CollectionProduct | null;
|
|
223
|
+
allProducts?: Collection[];
|
|
224
|
+
subtitle?: string | null;
|
|
225
|
+
caption?: string | null;
|
|
226
|
+
title?: string | null;
|
|
227
|
+
plainText?: string | null;
|
|
228
|
+
contactDescription?: string | null;
|
|
229
|
+
officeInformation?: string | null;
|
|
230
|
+
contactEmail?: string | null;
|
|
231
|
+
contactNumber?: string | null;
|
|
232
|
+
socialLinks?: SocialLink[] | null;
|
|
233
|
+
block?: any;
|
|
234
|
+
heading?: string | null;
|
|
235
|
+
acceptButtonLabel?: string | null;
|
|
236
|
+
declineButtonLabel?: string | null;
|
|
237
|
+
faqsWithCategories?: FaqsWithCategory[] | null;
|
|
238
|
+
faqs?: AskedQuestion[] | null;
|
|
239
|
+
arrayOfImageTitleAndText?: ArrayOfImageTitleAndText[] | null;
|
|
240
|
+
description?: string | null;
|
|
241
|
+
featuredItems?: FeaturedItem[] | null;
|
|
242
|
+
images?: Images[] | null;
|
|
243
|
+
contactDetails?: ContactDetails[] | null;
|
|
244
|
+
copyright?: string | null;
|
|
245
|
+
mainImage?: MainImage | null;
|
|
246
|
+
youtubeLink?: string | null;
|
|
247
|
+
banner?: any;
|
|
248
|
+
stats?: StatItems[] | null;
|
|
249
|
+
teams?: Team[] | null;
|
|
250
|
+
testimonials?: Testimonial[] | null;
|
|
251
|
+
selectStripeAccount?: string;
|
|
252
|
+
annualBilling?: string;
|
|
253
|
+
monthlyBilling?: string;
|
|
254
|
+
productDetails?: ProductDetail[];
|
|
255
|
+
btnLabel?: string;
|
|
256
|
+
selectAccount?: string;
|
|
257
|
+
hashtags?: string[];
|
|
258
|
+
numberOfPosts?: number;
|
|
259
|
+
text?: string;
|
|
260
|
+
button?: LabeledRoute;
|
|
261
|
+
features?: string[];
|
|
262
|
+
config?: {
|
|
263
|
+
enableAnalytics: boolean;
|
|
264
|
+
cookiePolicy?: {
|
|
265
|
+
siteName: string;
|
|
266
|
+
cookiePolicyPage: Reference;
|
|
267
|
+
};
|
|
268
|
+
consentModalPosition?: string;
|
|
269
|
+
};
|
|
270
|
+
contactLink?: LabeledRoute;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export interface Template {
|
|
274
|
+
bg?: string;
|
|
275
|
+
color?: string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export type Plans = {
|
|
279
|
+
_key?: string | null;
|
|
280
|
+
_type?: "planItems" | null;
|
|
281
|
+
checkoutButtonName?: string | null;
|
|
282
|
+
description?: string | null;
|
|
283
|
+
monthlyPrice?: string | null;
|
|
284
|
+
planType?: string | null;
|
|
285
|
+
yearlyPrice?: string | null;
|
|
286
|
+
planIncludes?: string[] | null;
|
|
287
|
+
primaryButton?: LabeledRoute | null;
|
|
288
|
+
} & Record<string, string>;
|
|
289
|
+
|
|
290
|
+
export interface Portfolios {
|
|
291
|
+
dateAdded?: string | null;
|
|
292
|
+
mainImage?: {
|
|
293
|
+
image?: string | null;
|
|
294
|
+
alt?: string | null;
|
|
295
|
+
} | null;
|
|
296
|
+
primaryButton?: LabeledRoute | null;
|
|
297
|
+
title?: string | null;
|
|
298
|
+
_key?: string | null;
|
|
299
|
+
_type?: string | null;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export interface PortfoliosWithCategories {
|
|
303
|
+
category?: string | null;
|
|
304
|
+
content?: Content[] | null;
|
|
305
|
+
primaryButton?: LabeledRoute | null;
|
|
306
|
+
_key?: string | null;
|
|
307
|
+
_type?: string | null;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export interface Content extends Portfolios {
|
|
311
|
+
description?: string | null;
|
|
312
|
+
subtitle?: string | null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export interface Collection extends SanityBody {
|
|
316
|
+
collectionInfoVariant?: {
|
|
317
|
+
variant?: string;
|
|
318
|
+
} | null;
|
|
319
|
+
name?: string | null;
|
|
320
|
+
products?: CollectionProduct[] | null;
|
|
321
|
+
sections?: any; //todo
|
|
322
|
+
seo?: Seo | null;
|
|
323
|
+
slug?: SanitySlug | null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface CollectionProduct extends SanityBody {
|
|
327
|
+
compareToPrice?: number | null;
|
|
328
|
+
description?: string | null;
|
|
329
|
+
ecwidProductId?: number | null;
|
|
330
|
+
name?: string | null;
|
|
331
|
+
price?: number | null;
|
|
332
|
+
productInfo?: ProductInfo | null;
|
|
333
|
+
productInfoVariant?: {
|
|
334
|
+
variant?: string;
|
|
335
|
+
} | null;
|
|
336
|
+
sections?: any; //todo
|
|
337
|
+
seo?: Seo | null;
|
|
338
|
+
slug?: SanitySlug | null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
//TODO, RECHECK PRODUCT INFO DATA FROM SANITY
|
|
342
|
+
interface ProductInfo {
|
|
343
|
+
btnLabel?: string | null;
|
|
344
|
+
images?: ProductInfoImage[] | null;
|
|
345
|
+
productDetails?: ProductDetail[] | null;
|
|
346
|
+
socialLinks?: SocialLink[] | null;
|
|
347
|
+
subtitle?: string | null;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
//TODO, RECHECK PRODUCT INFO DATA FROM SANITY
|
|
351
|
+
export interface ProductDetail {
|
|
352
|
+
blockContent?: any;
|
|
353
|
+
contentType?: string;
|
|
354
|
+
tabName?: string;
|
|
355
|
+
_key?: string;
|
|
356
|
+
[key: string]: any;
|
|
357
|
+
}
|
|
358
|
+
interface ProductInfoImage {
|
|
359
|
+
alt?: string | null;
|
|
360
|
+
_key: string;
|
|
361
|
+
_type: string;
|
|
362
|
+
image?: string | null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export interface FaqsWithCategory {
|
|
366
|
+
askedQuestions?: AskedQuestion[] | null;
|
|
367
|
+
category?: string | null;
|
|
368
|
+
_key?: string;
|
|
369
|
+
_type?: string;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export interface AskedQuestion {
|
|
373
|
+
answer?: string | null;
|
|
374
|
+
question?: string | null;
|
|
375
|
+
hidden?: boolean;
|
|
376
|
+
_key?: string;
|
|
377
|
+
_type?: string;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export interface Team {
|
|
381
|
+
jobTitle?: string;
|
|
382
|
+
mainImage?: MainImage;
|
|
383
|
+
name?: string;
|
|
384
|
+
plainText?: string;
|
|
385
|
+
_key?: string;
|
|
386
|
+
_type?: string;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export interface Testimonial {
|
|
390
|
+
jobTitle?: string;
|
|
391
|
+
mainImage?: MainImage;
|
|
392
|
+
name?: string;
|
|
393
|
+
rating?: string;
|
|
394
|
+
testimony?: string;
|
|
395
|
+
_key?: string;
|
|
396
|
+
_type?: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export declare interface Reference {
|
|
400
|
+
_type: string;
|
|
401
|
+
_ref: string;
|
|
402
|
+
_key?: string;
|
|
403
|
+
_weak?: boolean;
|
|
404
|
+
_strengthenOnPublish?: {
|
|
405
|
+
type: string;
|
|
406
|
+
weak?: boolean;
|
|
407
|
+
template?: {
|
|
408
|
+
id: string;
|
|
409
|
+
params: Record<string, string | number | boolean>;
|
|
410
|
+
};
|
|
411
|
+
};
|
|
412
|
+
}
|