@openstack_dev/gatsby-theme-marketing-oif-core 1.0.24 → 1.0.25
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/gatsby-node.js +33 -0
- package/package.json +1 -1
- package/src/cms/config/collections/configurationsCollection/footer/index.js +85 -41
- package/src/cms/config/collections/configurationsCollection/footer/typeDefs.js +12 -4
- package/src/components/Footer/index.js +19 -4
- package/src/components/Footer/index.module.scss +10 -7
- package/src/components/Footer/template.js +126 -25
- package/src/components/Link.js +10 -5
- package/src/content/footer/bluesky_logo.svg +4 -0
- package/src/content/footer/index.json +70 -12
- package/src/content/footer/mastodon.svg +12 -0
- package/src/content/footer/qrcode-for-gh-5cc38c749efd-1280.jpg +0 -0
- package/src/content/footer/x-icon.svg +13 -0
- package/src/content/site-settings/index.json +1 -1
- package/src/images/404-bg.jpg +0 -0
- package/src/images/cat.png +0 -0
- package/src/pages/404.js +71 -0
- package/src/styles/404.module.scss +132 -0
- package/src/themes/404theme.js +26 -0
- package/static/fonts/gothamnarrow-ultra/GothamNarrow-Ultra.eot +0 -0
- package/static/fonts/gothamnarrow-ultra/GothamNarrow-Ultra.otf +0 -0
- package/static/fonts/gothamnarrow-ultra/GothamNarrow-Ultra.svg +3273 -0
- package/static/fonts/gothamnarrow-ultra/GothamNarrow-Ultra.ttf +0 -0
- package/static/fonts/gothamnarrow-ultra/GothamNarrow-Ultra.woff +0 -0
package/gatsby-node.js
CHANGED
|
@@ -15,6 +15,7 @@ const {
|
|
|
15
15
|
MAINTENANCE_FILE_PATH,
|
|
16
16
|
FONTS_SCSS_FILE_PATH,
|
|
17
17
|
SPONSORED_PROJECTS_FILE_PATH,
|
|
18
|
+
FOOTER_FILE_PATH,
|
|
18
19
|
} = require("./src/utils/filePath");
|
|
19
20
|
const { generateFontFile } = require("./src/utils/cssUtils");
|
|
20
21
|
|
|
@@ -87,6 +88,38 @@ exports.onPreBootstrap = async () => {
|
|
|
87
88
|
if (sponsoredProjects) {
|
|
88
89
|
writeToJson(SPONSORED_PROJECTS_FILE_PATH, sponsoredProjects);
|
|
89
90
|
}
|
|
91
|
+
|
|
92
|
+
// new footer structure migration
|
|
93
|
+
// read the JSON file
|
|
94
|
+
const rawData = fs.readFileSync(FOOTER_FILE_PATH, "utf8");
|
|
95
|
+
let footerJSON;
|
|
96
|
+
try {
|
|
97
|
+
footerJSON = JSON.parse(rawData);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.log("Error parsing JSON from footer file:", error);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// return new structure for social networks
|
|
103
|
+
if (footerJSON.social && Array.isArray(footerJSON.social.networks)) {
|
|
104
|
+
footerJSON.social.networks = footerJSON.social.networks.map((item) => ({
|
|
105
|
+
display: item.display,
|
|
106
|
+
title: item.title || item.icon,
|
|
107
|
+
clickBehaviour: {
|
|
108
|
+
link: item.clickBehaviour?.link || item.link,
|
|
109
|
+
attributes: item.clickBehaviour?.attributes || [],
|
|
110
|
+
},
|
|
111
|
+
rendering: {
|
|
112
|
+
icon: item.rendering?.icon || item.icon,
|
|
113
|
+
},
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
// save updated file.
|
|
117
|
+
try {
|
|
118
|
+
fs.writeFileSync(FOOTER_FILE_PATH, JSON.stringify(footerJSON));
|
|
119
|
+
console.log(`File successfully updated at ${FOOTER_FILE_PATH}`);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.log("Error writing updated config file:", error);
|
|
122
|
+
}
|
|
90
123
|
};
|
|
91
124
|
|
|
92
125
|
exports.createSchemaCustomization = ({ actions }) => {
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
+
import { FOOTER_FILE_PATH } from "@utils/filePath";
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
booleanField,
|
|
3
5
|
stringField,
|
|
4
6
|
objectField,
|
|
5
|
-
listField
|
|
7
|
+
listField,
|
|
8
|
+
fileField,
|
|
6
9
|
} from "../../../fields";
|
|
7
10
|
|
|
8
|
-
import {
|
|
9
|
-
FOOTER_FILE_PATH
|
|
10
|
-
} from "@utils/filePath";
|
|
11
|
-
|
|
12
11
|
/*
|
|
13
12
|
- file: "src/content/footer.json"
|
|
14
13
|
label: "Footer"
|
|
@@ -19,7 +18,7 @@ import {
|
|
|
19
18
|
{label: "Display", name: "display", widget: boolean, required: false},
|
|
20
19
|
{label: "Items", name: "items", widget: list, fields: [
|
|
21
20
|
{label: "Title", name: "title", widget: string},
|
|
22
|
-
{label: "Link", name: "link", widget: string},
|
|
21
|
+
{label: "Link", name: "link", widget: string},
|
|
23
22
|
]}
|
|
24
23
|
]}
|
|
25
24
|
- {label: "Logo", name: "logo", widget: object, fields: [
|
|
@@ -51,12 +50,12 @@ const footer = {
|
|
|
51
50
|
fields: [
|
|
52
51
|
stringField({
|
|
53
52
|
label: "Title",
|
|
54
|
-
name: "title"
|
|
53
|
+
name: "title",
|
|
55
54
|
}),
|
|
56
55
|
booleanField({
|
|
57
56
|
label: "Display",
|
|
58
57
|
name: "display",
|
|
59
|
-
required: false
|
|
58
|
+
required: false,
|
|
60
59
|
}),
|
|
61
60
|
listField({
|
|
62
61
|
label: "Items",
|
|
@@ -64,15 +63,15 @@ const footer = {
|
|
|
64
63
|
fields: [
|
|
65
64
|
stringField({
|
|
66
65
|
label: "Title",
|
|
67
|
-
name: "title"
|
|
66
|
+
name: "title",
|
|
68
67
|
}),
|
|
69
68
|
stringField({
|
|
70
69
|
label: "Link",
|
|
71
|
-
name: "link"
|
|
72
|
-
})
|
|
73
|
-
]
|
|
74
|
-
})
|
|
75
|
-
]
|
|
70
|
+
name: "link",
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
|
+
}),
|
|
74
|
+
],
|
|
76
75
|
}),
|
|
77
76
|
objectField({
|
|
78
77
|
label: "Logo",
|
|
@@ -81,9 +80,9 @@ const footer = {
|
|
|
81
80
|
booleanField({
|
|
82
81
|
label: "Display",
|
|
83
82
|
name: "display",
|
|
84
|
-
required: false
|
|
85
|
-
})
|
|
86
|
-
]
|
|
83
|
+
required: false,
|
|
84
|
+
}),
|
|
85
|
+
],
|
|
87
86
|
}),
|
|
88
87
|
objectField({
|
|
89
88
|
label: "Social",
|
|
@@ -91,33 +90,78 @@ const footer = {
|
|
|
91
90
|
fields: [
|
|
92
91
|
stringField({
|
|
93
92
|
label: "Title",
|
|
94
|
-
name: "title"
|
|
93
|
+
name: "title",
|
|
95
94
|
}),
|
|
96
95
|
booleanField({
|
|
97
96
|
label: "Display",
|
|
98
97
|
name: "display",
|
|
99
|
-
required: false
|
|
98
|
+
required: false,
|
|
100
99
|
}),
|
|
101
100
|
listField({
|
|
102
101
|
label: "Networks",
|
|
103
102
|
name: "networks",
|
|
104
103
|
fields: [
|
|
105
104
|
stringField({
|
|
106
|
-
label: "
|
|
107
|
-
name: "
|
|
105
|
+
label: "Title",
|
|
106
|
+
name: "title",
|
|
108
107
|
}),
|
|
109
|
-
|
|
110
|
-
label: "
|
|
111
|
-
name: "
|
|
108
|
+
objectField({
|
|
109
|
+
label: "Rendering",
|
|
110
|
+
name: "rendering",
|
|
111
|
+
fields: [
|
|
112
|
+
stringField({
|
|
113
|
+
label: "Icon",
|
|
114
|
+
name: "icon",
|
|
115
|
+
required: false,
|
|
116
|
+
}),
|
|
117
|
+
fileField({
|
|
118
|
+
label: "file",
|
|
119
|
+
name: "file",
|
|
120
|
+
required: false,
|
|
121
|
+
}),
|
|
122
|
+
],
|
|
123
|
+
}),
|
|
124
|
+
objectField({
|
|
125
|
+
label: "Click Behaviour",
|
|
126
|
+
name: "clickBehaviour",
|
|
127
|
+
fields: [
|
|
128
|
+
stringField({
|
|
129
|
+
label: "Link",
|
|
130
|
+
name: "link",
|
|
131
|
+
required: false,
|
|
132
|
+
}),
|
|
133
|
+
listField({
|
|
134
|
+
label: "Custom attributes",
|
|
135
|
+
name: "attributes",
|
|
136
|
+
required: false,
|
|
137
|
+
fields: [
|
|
138
|
+
stringField({
|
|
139
|
+
label: "Attribute",
|
|
140
|
+
name: "attribute",
|
|
141
|
+
required: true,
|
|
142
|
+
}),
|
|
143
|
+
stringField({
|
|
144
|
+
label: "Value",
|
|
145
|
+
name: "value",
|
|
146
|
+
required: true,
|
|
147
|
+
}),
|
|
148
|
+
],
|
|
149
|
+
}),
|
|
150
|
+
fileField({
|
|
151
|
+
label: "Open modal with File",
|
|
152
|
+
name: "openModal",
|
|
153
|
+
required: false,
|
|
154
|
+
}),
|
|
155
|
+
],
|
|
112
156
|
}),
|
|
113
157
|
booleanField({
|
|
114
158
|
label: "Display",
|
|
115
159
|
name: "display",
|
|
116
|
-
required: false
|
|
117
|
-
})
|
|
118
|
-
]
|
|
119
|
-
})
|
|
120
|
-
]
|
|
160
|
+
required: false,
|
|
161
|
+
}),
|
|
162
|
+
],
|
|
163
|
+
}),
|
|
164
|
+
],
|
|
121
165
|
}),
|
|
122
166
|
listField({
|
|
123
167
|
label: "Legal",
|
|
@@ -125,13 +169,13 @@ const footer = {
|
|
|
125
169
|
fields: [
|
|
126
170
|
stringField({
|
|
127
171
|
label: "Title",
|
|
128
|
-
name: "title"
|
|
172
|
+
name: "title",
|
|
129
173
|
}),
|
|
130
174
|
stringField({
|
|
131
175
|
label: "Link",
|
|
132
|
-
name: "link"
|
|
133
|
-
})
|
|
134
|
-
]
|
|
176
|
+
name: "link",
|
|
177
|
+
}),
|
|
178
|
+
],
|
|
135
179
|
}),
|
|
136
180
|
objectField({
|
|
137
181
|
label: "Credit",
|
|
@@ -139,20 +183,20 @@ const footer = {
|
|
|
139
183
|
fields: [
|
|
140
184
|
stringField({
|
|
141
185
|
label: "Title",
|
|
142
|
-
name: "title"
|
|
186
|
+
name: "title",
|
|
143
187
|
}),
|
|
144
188
|
stringField({
|
|
145
189
|
label: "Content",
|
|
146
|
-
name: "content"
|
|
190
|
+
name: "content",
|
|
147
191
|
}),
|
|
148
192
|
booleanField({
|
|
149
193
|
label: "Display",
|
|
150
194
|
name: "display",
|
|
151
|
-
required: false
|
|
152
|
-
})
|
|
153
|
-
]
|
|
154
|
-
})
|
|
155
|
-
]
|
|
195
|
+
required: false,
|
|
196
|
+
}),
|
|
197
|
+
],
|
|
198
|
+
}),
|
|
199
|
+
],
|
|
156
200
|
};
|
|
157
201
|
|
|
158
|
-
export default footer;
|
|
202
|
+
export default footer;
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
|
|
2
1
|
module.exports = `
|
|
2
|
+
type ClickBehaviour {
|
|
3
|
+
link: String
|
|
4
|
+
attribute: String
|
|
5
|
+
openModal: File @fileByRelativePath
|
|
6
|
+
}
|
|
7
|
+
type Rendering {
|
|
8
|
+
icon: String
|
|
9
|
+
file: File @fileByRelativePath
|
|
10
|
+
}
|
|
3
11
|
type Link {
|
|
4
12
|
title: String
|
|
5
13
|
link: String
|
|
6
14
|
}
|
|
7
15
|
type Networks {
|
|
8
|
-
icon: String
|
|
9
|
-
link: String
|
|
10
16
|
display: Boolean
|
|
17
|
+
rendering: Rendering
|
|
18
|
+
clickBehaviour: ClickBehaviour
|
|
11
19
|
}
|
|
12
20
|
type Social {
|
|
13
21
|
title: String
|
|
@@ -34,4 +42,4 @@ module.exports = `
|
|
|
34
42
|
logo: Logo
|
|
35
43
|
columns: [Columns]
|
|
36
44
|
}
|
|
37
|
-
`;
|
|
45
|
+
`;
|
|
@@ -10,8 +10,23 @@ const footerQuery = graphql`
|
|
|
10
10
|
title
|
|
11
11
|
networks {
|
|
12
12
|
display
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
title
|
|
14
|
+
rendering {
|
|
15
|
+
icon
|
|
16
|
+
file {
|
|
17
|
+
publicURL
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
clickBehaviour {
|
|
21
|
+
link
|
|
22
|
+
attributes {
|
|
23
|
+
attribute
|
|
24
|
+
value
|
|
25
|
+
}
|
|
26
|
+
openModal {
|
|
27
|
+
publicURL
|
|
28
|
+
}
|
|
29
|
+
}
|
|
15
30
|
}
|
|
16
31
|
}
|
|
17
32
|
credit {
|
|
@@ -31,10 +46,10 @@ const footerQuery = graphql`
|
|
|
31
46
|
}
|
|
32
47
|
`;
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
function Footer() {
|
|
35
50
|
const { footerJson: footerContent } = useStaticQuery(footerQuery);
|
|
36
51
|
|
|
37
52
|
return <FooterTemplate data={footerContent} />;
|
|
38
|
-
}
|
|
53
|
+
}
|
|
39
54
|
|
|
40
55
|
export default Footer;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.link {
|
|
18
|
-
color: #
|
|
18
|
+
color: #aaaaaa;
|
|
19
19
|
text-decoration: none;
|
|
20
20
|
line-height: 1.5;
|
|
21
21
|
|
|
@@ -45,15 +45,18 @@
|
|
|
45
45
|
min-width: 48px;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
.iconImage {
|
|
49
|
+
height: 36px;
|
|
50
|
+
}
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
.credit {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
margin-top: 20px;
|
|
55
|
+
line-height: 1.5;
|
|
56
|
+
color: #aaaaaa;
|
|
57
|
+
a {
|
|
58
|
+
color: #aaaaaa;
|
|
59
|
+
}
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
}
|
|
@@ -1,27 +1,51 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Container, Modal, Grid, Icon, Box,
|
|
4
|
+
} from "@mui/material";
|
|
3
5
|
import Link from "../Link";
|
|
4
|
-
import
|
|
6
|
+
import "@fortawesome/fontawesome-free/css/all.css";
|
|
5
7
|
|
|
6
8
|
import styles from "./index.module.scss";
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
+
function FooterTemplate({ data }) {
|
|
11
|
+
const TOTAL_COLUMNS = 12;
|
|
12
|
+
const columns = data?.columns?.filter((col) => col.display);
|
|
10
13
|
const socialColumnSpan = 4;
|
|
11
|
-
const colsSpan = columns?.length > 0
|
|
14
|
+
const colsSpan = columns?.length > 0
|
|
15
|
+
? Math.floor((TOTAL_COLUMNS - socialColumnSpan) / columns.length)
|
|
16
|
+
: 0;
|
|
17
|
+
|
|
18
|
+
const [openModalIndex, setOpenModalIndex] = React.useState(null);
|
|
19
|
+
|
|
20
|
+
const handleOpenModal = (index) => {
|
|
21
|
+
setOpenModalIndex(index);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const handleCloseModal = () => {
|
|
25
|
+
setOpenModalIndex(null);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const isModalOpen = (index) => openModalIndex === index;
|
|
29
|
+
|
|
30
|
+
const parseAttributes = (attributes) => {
|
|
31
|
+
const extraAttributes = {};
|
|
32
|
+
attributes.forEach((attr) => {
|
|
33
|
+
extraAttributes[attr.attribute] = attr.value;
|
|
34
|
+
});
|
|
35
|
+
return extraAttributes;
|
|
36
|
+
};
|
|
37
|
+
|
|
12
38
|
return (
|
|
13
39
|
<footer className={styles.footer}>
|
|
14
40
|
<Container maxWidth="lg" className={styles.footerColummns}>
|
|
15
41
|
<Grid container>
|
|
16
|
-
{columns.map((col
|
|
17
|
-
<Grid item xs={12} md={colsSpan} key={
|
|
18
|
-
<h3>
|
|
19
|
-
{col?.title}
|
|
20
|
-
</h3>
|
|
42
|
+
{columns.map((col) => (
|
|
43
|
+
<Grid item xs={12} md={colsSpan} key={col?.title}>
|
|
44
|
+
<h3>{col?.title}</h3>
|
|
21
45
|
<ul>
|
|
22
|
-
{col.items.map((item
|
|
23
|
-
<li key={`item-${
|
|
24
|
-
<Link to={item?.link} className={styles.link}
|
|
46
|
+
{col.items.map((item) => (
|
|
47
|
+
<li key={`item-${item.title}`}>
|
|
48
|
+
<Link to={item?.link} className={styles.link}>
|
|
25
49
|
{item?.title}
|
|
26
50
|
</Link>
|
|
27
51
|
</li>
|
|
@@ -31,25 +55,102 @@ const FooterTemplate = ({ data }) => {
|
|
|
31
55
|
))}
|
|
32
56
|
{data.social?.display && (
|
|
33
57
|
<Grid item xs={12} md={socialColumnSpan}>
|
|
34
|
-
<h3>
|
|
35
|
-
{data.social?.title}
|
|
36
|
-
</h3>
|
|
58
|
+
<h3>{data.social?.title}</h3>
|
|
37
59
|
<div className={styles.socialContainer}>
|
|
38
|
-
{data.social?.networks
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
{data.social?.networks
|
|
61
|
+
.filter((net) => net.display)
|
|
62
|
+
.map((net, index) => {
|
|
63
|
+
const renderedIcon = net.rendering?.file?.publicURL ? (
|
|
64
|
+
<Box
|
|
65
|
+
component="img"
|
|
66
|
+
src={net.rendering.file.publicURL}
|
|
67
|
+
alt={net.rendering.icon}
|
|
68
|
+
className={styles.iconImage}
|
|
69
|
+
sx={{ p: "2px", mr: "10px" }}
|
|
70
|
+
/>
|
|
71
|
+
) : (
|
|
72
|
+
<Icon className={`fab fa-${net.rendering?.icon}`} />
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (net.clickBehaviour?.openModal) {
|
|
76
|
+
return (
|
|
77
|
+
<Box key={net.title}>
|
|
78
|
+
<Box
|
|
79
|
+
component="a"
|
|
80
|
+
className={styles.link}
|
|
81
|
+
onClick={() => handleOpenModal(index)}
|
|
82
|
+
sx={{ cursor: "pointer" }}
|
|
83
|
+
title={net.title}
|
|
84
|
+
>
|
|
85
|
+
{renderedIcon}
|
|
86
|
+
</Box>
|
|
87
|
+
<Modal
|
|
88
|
+
open={isModalOpen(index)}
|
|
89
|
+
onClose={handleCloseModal}
|
|
90
|
+
aria-labelledby={`modal-${index}-title`}
|
|
91
|
+
aria-describedby={`modal-${index}-description`}
|
|
92
|
+
sx={{
|
|
93
|
+
display: "flex",
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<Box
|
|
97
|
+
component="img"
|
|
98
|
+
src={net.clickBehaviour.openModal.publicURL}
|
|
99
|
+
alt="Modal Content"
|
|
100
|
+
className={styles.modalImage}
|
|
101
|
+
sx={{
|
|
102
|
+
width: 150,
|
|
103
|
+
margin: "auto",
|
|
104
|
+
justifyContent: "center",
|
|
105
|
+
alignItems: "center",
|
|
106
|
+
borderRadius: "6px",
|
|
107
|
+
}}
|
|
108
|
+
/>
|
|
109
|
+
</Modal>
|
|
110
|
+
</Box>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (net.clickBehaviour?.link) {
|
|
115
|
+
const extraAttributes = net.clickBehaviour.attributes
|
|
116
|
+
&& net.clickBehaviour.attributes.length > 0
|
|
117
|
+
? parseAttributes(net.clickBehaviour.attributes)
|
|
118
|
+
: {};
|
|
119
|
+
return (
|
|
120
|
+
<Link
|
|
121
|
+
to={net.clickBehaviour.link}
|
|
122
|
+
className={styles.link}
|
|
123
|
+
title={net.title}
|
|
124
|
+
key={net.title}
|
|
125
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
126
|
+
{...extraAttributes}
|
|
127
|
+
>
|
|
128
|
+
{renderedIcon}
|
|
129
|
+
</Link>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<Box
|
|
135
|
+
key={net.title}
|
|
136
|
+
className={styles.link}
|
|
137
|
+
title={net.title}
|
|
138
|
+
>
|
|
139
|
+
{renderedIcon}
|
|
140
|
+
</Box>
|
|
141
|
+
);
|
|
142
|
+
})}
|
|
45
143
|
</div>
|
|
46
|
-
|
|
144
|
+
<div
|
|
145
|
+
className={styles.credit}
|
|
146
|
+
dangerouslySetInnerHTML={{ __html: data.credit.content }}
|
|
147
|
+
/>
|
|
47
148
|
</Grid>
|
|
48
149
|
)}
|
|
49
150
|
</Grid>
|
|
50
151
|
</Container>
|
|
51
152
|
</footer>
|
|
52
153
|
);
|
|
53
|
-
}
|
|
154
|
+
}
|
|
54
155
|
|
|
55
156
|
export default FooterTemplate;
|
package/src/components/Link.js
CHANGED
|
@@ -3,11 +3,13 @@ import { Link as GatsbyLink } from "gatsby";
|
|
|
3
3
|
// Since DOM elements <a> cannot receive activeClassName
|
|
4
4
|
// and partiallyActive, destructure the prop here and
|
|
5
5
|
// pass it only to GatsbyLink
|
|
6
|
-
|
|
6
|
+
function Link({
|
|
7
|
+
children, to, activeClassName, partiallyActive, ...other
|
|
8
|
+
}) {
|
|
7
9
|
// Tailor the following test to your environment.
|
|
8
10
|
// This example assumes that any internal link (intended for Gatsby)
|
|
9
11
|
// will start with exactly one slash, and that anything else is external.
|
|
10
|
-
const internal = /^\/(?!\/)/.test(to)
|
|
12
|
+
const internal = /^\/(?!\/)/.test(to);
|
|
11
13
|
// Use Gatsby Link for internal links, and <a> for others
|
|
12
14
|
const email = /\S+@\S+\.\S+/.test(to);
|
|
13
15
|
|
|
@@ -17,6 +19,7 @@ const Link = ({ children, to, activeClassName, partiallyActive, ...other }) => {
|
|
|
17
19
|
to={to}
|
|
18
20
|
activeClassName={activeClassName}
|
|
19
21
|
partiallyActive={partiallyActive}
|
|
22
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
20
23
|
{...other}
|
|
21
24
|
>
|
|
22
25
|
{children}
|
|
@@ -26,16 +29,18 @@ const Link = ({ children, to, activeClassName, partiallyActive, ...other }) => {
|
|
|
26
29
|
if (email) {
|
|
27
30
|
const href = /^mailto:/.test(to) ? to : `mailto:${to}`;
|
|
28
31
|
return (
|
|
32
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
29
33
|
<a href={href} {...other}>
|
|
30
34
|
{children}
|
|
31
35
|
</a>
|
|
32
36
|
);
|
|
33
37
|
}
|
|
34
38
|
return (
|
|
35
|
-
|
|
39
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
40
|
+
<a href={to} target="_blank" rel="noreferrer" {...other}>
|
|
36
41
|
{children}
|
|
37
42
|
</a>
|
|
38
43
|
);
|
|
39
|
-
}
|
|
44
|
+
}
|
|
40
45
|
|
|
41
|
-
export default Link;
|
|
46
|
+
export default Link;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="600" height="530" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z" fill="#eaeaea"/>
|
|
4
|
+
</svg>
|