gatsby-theme-q3 4.5.17 → 4.5.21

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.
Files changed (80) hide show
  1. package/.eslintrc.js +12 -12
  2. package/CHANGELOG.md +1216 -1200
  3. package/LICENSE +21 -21
  4. package/__fixtures__/en/titles.json +2 -2
  5. package/__fixtures__/fr/titles.json +2 -2
  6. package/gatsby-browser.js +38 -38
  7. package/gatsby-config.js +62 -62
  8. package/gatsby-node.js +77 -77
  9. package/gatsby-ssr.js +11 -11
  10. package/index.js +1 -1
  11. package/lib/components/AccountPublicGateway.js +2 -3
  12. package/lib/components/AdminLoader.js +2 -3
  13. package/lib/components/AdminPrivateGateway.js +3 -4
  14. package/lib/components/AdminPublicGateway.js +3 -4
  15. package/lib/components/AdminRouter.js +3 -4
  16. package/lib/components/BlogArchiveTemplate.js +2 -3
  17. package/lib/components/BlogTemplate.js +2 -3
  18. package/lib/components/FormBox.js +2 -3
  19. package/lib/components/FormBoxContent.js +2 -3
  20. package/lib/components/FormBoxNotice.js +2 -3
  21. package/lib/components/IsBrowserReady.js +2 -3
  22. package/lib/components/PageWrapper.js +2 -3
  23. package/lib/components/PublicTemplate.js +2 -3
  24. package/lib/components/Redirect.js +2 -3
  25. package/lib/components/RedirectToIndex.js +2 -3
  26. package/lib/components/RichText.js +2 -3
  27. package/lib/components/SearchEngine.js +4 -7
  28. package/lib/components/ShareButton.js +2 -3
  29. package/lib/components/Wrapper.js +2 -3
  30. package/lib/components/__tests__/useSiteMetaData.test.js +44 -44
  31. package/lib/components/__tests__/withAuthenticate.test.js +2 -2
  32. package/lib/components/__tests__/withSuccessOp.test.js +4 -4
  33. package/lib/components/index.js +2 -3
  34. package/lib/components/useSiteMetaData.js +1 -1
  35. package/lib/components/utils.js +2 -3
  36. package/lib/components/withAuthenticate.js +2 -2
  37. package/lib/components/withPublicTemplate.js +2 -3
  38. package/lib/components/withSuccessOp.js +3 -4
  39. package/lib/pages/404.js +2 -3
  40. package/lib/pages/login.js +2 -3
  41. package/lib/pages/password-change.js +2 -3
  42. package/lib/pages/password-reset.js +2 -3
  43. package/lib/pages/reverify.js +2 -3
  44. package/lib/pages/verify.js +2 -3
  45. package/package.json +5 -5
  46. package/src/components/AccountPublicGateway.jsx +18 -18
  47. package/src/components/AdminLoader.jsx +16 -16
  48. package/src/components/AdminPrivateGateway.jsx +37 -37
  49. package/src/components/AdminPublicGateway.jsx +34 -34
  50. package/src/components/AdminRouter.jsx +44 -44
  51. package/src/components/BlogArchiveTemplate.jsx +55 -55
  52. package/src/components/BlogTemplate.jsx +104 -104
  53. package/src/components/FormBox.jsx +22 -22
  54. package/src/components/FormBoxContent.jsx +26 -26
  55. package/src/components/FormBoxNotice.jsx +21 -21
  56. package/src/components/IsBrowserReady.jsx +13 -13
  57. package/src/components/PageWrapper.jsx +20 -20
  58. package/src/components/PublicTemplate.jsx +198 -198
  59. package/src/components/Redirect.jsx +13 -13
  60. package/src/components/RedirectToIndex.jsx +9 -9
  61. package/src/components/RichText.jsx +196 -196
  62. package/src/components/SearchEngine.jsx +124 -124
  63. package/src/components/ShareButton.jsx +80 -80
  64. package/src/components/Wrapper.jsx +14 -14
  65. package/src/components/__tests__/SearchEngine.test.jsx +58 -58
  66. package/src/components/__tests__/useSiteMetaData.test.js +44 -44
  67. package/src/components/__tests__/withAuthenticate.test.jsx +52 -52
  68. package/src/components/__tests__/withSuccessOp.test.jsx +57 -57
  69. package/src/components/index.js +16 -16
  70. package/src/components/useSiteMetaData.js +35 -35
  71. package/src/components/utils.js +23 -23
  72. package/src/components/withAuthenticate.jsx +20 -20
  73. package/src/components/withPublicTemplate.jsx +11 -11
  74. package/src/components/withSuccessOp.jsx +43 -43
  75. package/src/pages/404.jsx +31 -31
  76. package/src/pages/login.jsx +71 -71
  77. package/src/pages/password-change.jsx +72 -72
  78. package/src/pages/password-reset.jsx +47 -47
  79. package/src/pages/reverify.jsx +72 -72
  80. package/src/pages/verify.jsx +70 -70
@@ -1,196 +1,196 @@
1
- import React from 'react';
2
- import { get } from 'lodash';
3
- import PropTypes from 'prop-types';
4
- import { useStaticQuery, graphql, Link } from 'gatsby';
5
- import Card from '@material-ui/core/Card';
6
- import CardContent from '@material-ui/core/CardContent';
7
- import Box from '@material-ui/core/Box';
8
- import Typography from '@material-ui/core/Typography';
9
- import List from '@material-ui/core/List';
10
- import ListItem from '@material-ui/core/ListItem';
11
- import CardActionArea from '@material-ui/core/CardActionArea';
12
- import ListItemIcon from '@material-ui/core/ListItemIcon';
13
- import Divider from '@material-ui/core/Divider';
14
- import CheckCircleIcon from '@material-ui/icons/CheckCircle';
15
- import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
16
- import {
17
- MARKS,
18
- BLOCKS,
19
- INLINES,
20
- } from '@contentful/rich-text-types';
21
-
22
- const isImage = (v) => v === 'image';
23
-
24
- const getGroup = (v) =>
25
- typeof v === 'string' ? v.split('/')[0] : '';
26
-
27
- const imageRender = (node, locale) => {
28
- const { title, description, file } = get(
29
- node,
30
- 'data.target.fields',
31
- {},
32
- );
33
-
34
- if (!file || !(locale in file)) return null;
35
-
36
- const mimeType = file[locale].contentType;
37
- const mimeGroup = getGroup(mimeType);
38
-
39
- return isImage(mimeGroup) ? (
40
- <img
41
- title={title ? title[locale] : null}
42
- alt={description ? description[locale] : null}
43
- src={file[locale].url}
44
- />
45
- ) : null;
46
- };
47
-
48
- export const renderRichText = (
49
- json,
50
- locale = 'en-CA',
51
- sitemap = {},
52
- ) => {
53
- if (!json || !Object.keys(json).length) return null;
54
-
55
- const getFromSitemap = (node) =>
56
- get(
57
- sitemap,
58
- get(node, 'data.target.sys.contentful_id'),
59
- );
60
-
61
- return documentToReactComponents(json, {
62
- renderMark: {
63
- [MARKS.BOLD]: (text) => <strong>{text}</strong>,
64
- [MARKS.ITALIC]: (text) => <i>{text}</i>,
65
- [MARKS.UNDERLINE]: (text) => <u>{text}</u>,
66
- [MARKS.CODE]: (text) => <code>{text}</code>,
67
- },
68
- renderNode: {
69
- [BLOCKS.PARAGRAPH]: (node, children) => (
70
- <Typography component="p">{children}</Typography>
71
- ),
72
- [BLOCKS.HEADING_1]: (node, children) => (
73
- <Typography variant="h1" gutterBottom>
74
- {children}
75
- </Typography>
76
- ),
77
- [BLOCKS.HEADING_2]: (node, children) => (
78
- <Typography variant="h2" gutterBottom>
79
- {children}
80
- </Typography>
81
- ),
82
- [BLOCKS.HEADING_3]: (node, children) => (
83
- <Typography variant="h3" gutterBottom>
84
- {children}
85
- </Typography>
86
- ),
87
- [BLOCKS.HEADING_4]: (node, children) => (
88
- <Typography variant="h4" gutterBottom>
89
- {children}
90
- </Typography>
91
- ),
92
- [BLOCKS.HEADING_5]: (node, children) => (
93
- <Typography variant="h5" gutterBottom>
94
- {children}
95
- </Typography>
96
- ),
97
- [BLOCKS.HEADING_6]: (node, children) => (
98
- <Typography variant="h6" gutterBottom>
99
- {children}
100
- </Typography>
101
- ),
102
- [BLOCKS.OL_LIST]: (node, children) => (
103
- <List component="ol">{children}</List>
104
- ),
105
- [BLOCKS.UL_LIST]: (node, children) => (
106
- <List component="ul">{children}</List>
107
- ),
108
- [BLOCKS.LIST_ITEM]: (node, children) => (
109
- <ListItem>
110
- <ListItemIcon>
111
- <CheckCircleIcon />
112
- </ListItemIcon>
113
- {children}
114
- </ListItem>
115
- ),
116
- [BLOCKS.HR]: () => <Divider />,
117
- [BLOCKS.QUOTE]: (node, children) => (
118
- <blockquote>{children}</blockquote>
119
- ),
120
- [BLOCKS.EMBEDDED_ASSET]: (node) =>
121
- imageRender(node, locale),
122
- [BLOCKS.EMBEDDED_ENTRY]: () => null,
123
- [INLINES.EMBEDDED_ENTRY]: (node) => {
124
- const path = getFromSitemap(node);
125
-
126
- return path ? (
127
- <Box my={2}>
128
- <Card component="aside">
129
- <CardActionArea component={Link} to={path}>
130
- <CardContent>
131
- <Box p={2}>
132
- <Typography
133
- variant="body2"
134
- component="h3"
135
- gutterBottom
136
- >
137
- {get(
138
- node,
139
- `data.target.fields.title.${locale}`,
140
- )}
141
- </Typography>
142
- <Typography component="small">
143
- {get(
144
- node,
145
- `data.target.fields.description.${locale}`,
146
- )}
147
- </Typography>
148
- </Box>
149
- </CardContent>
150
- </CardActionArea>
151
- </Card>
152
- </Box>
153
- ) : null;
154
- },
155
- },
156
- });
157
- };
158
-
159
- const RichText = ({ json, locale }) => {
160
- const data = useStaticQuery(graphql`
161
- {
162
- allSitePage {
163
- nodes {
164
- path
165
- pageContext
166
- }
167
- }
168
- }
169
- `);
170
-
171
- return (
172
- <div>
173
- {renderRichText(
174
- json,
175
- locale,
176
- data.allSitePage.nodes.reduce((acc, next, i) => {
177
- acc[get(next, 'pageContext.contentful_id', i)] =
178
- next.path;
179
- return acc;
180
- }, {}),
181
- )}
182
- </div>
183
- );
184
- };
185
-
186
- RichText.propTypes = {
187
- // eslint-disable-next-line
188
- json: PropTypes.object,
189
- locale: PropTypes.string,
190
- };
191
-
192
- RichText.defaultProps = {
193
- locale: 'en-CA',
194
- };
195
-
196
- export default RichText;
1
+ import React from 'react';
2
+ import { get } from 'lodash';
3
+ import PropTypes from 'prop-types';
4
+ import { useStaticQuery, graphql, Link } from 'gatsby';
5
+ import Card from '@material-ui/core/Card';
6
+ import CardContent from '@material-ui/core/CardContent';
7
+ import Box from '@material-ui/core/Box';
8
+ import Typography from '@material-ui/core/Typography';
9
+ import List from '@material-ui/core/List';
10
+ import ListItem from '@material-ui/core/ListItem';
11
+ import CardActionArea from '@material-ui/core/CardActionArea';
12
+ import ListItemIcon from '@material-ui/core/ListItemIcon';
13
+ import Divider from '@material-ui/core/Divider';
14
+ import CheckCircleIcon from '@material-ui/icons/CheckCircle';
15
+ import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
16
+ import {
17
+ MARKS,
18
+ BLOCKS,
19
+ INLINES,
20
+ } from '@contentful/rich-text-types';
21
+
22
+ const isImage = (v) => v === 'image';
23
+
24
+ const getGroup = (v) =>
25
+ typeof v === 'string' ? v.split('/')[0] : '';
26
+
27
+ const imageRender = (node, locale) => {
28
+ const { title, description, file } = get(
29
+ node,
30
+ 'data.target.fields',
31
+ {},
32
+ );
33
+
34
+ if (!file || !(locale in file)) return null;
35
+
36
+ const mimeType = file[locale].contentType;
37
+ const mimeGroup = getGroup(mimeType);
38
+
39
+ return isImage(mimeGroup) ? (
40
+ <img
41
+ title={title ? title[locale] : null}
42
+ alt={description ? description[locale] : null}
43
+ src={file[locale].url}
44
+ />
45
+ ) : null;
46
+ };
47
+
48
+ export const renderRichText = (
49
+ json,
50
+ locale = 'en-CA',
51
+ sitemap = {},
52
+ ) => {
53
+ if (!json || !Object.keys(json).length) return null;
54
+
55
+ const getFromSitemap = (node) =>
56
+ get(
57
+ sitemap,
58
+ get(node, 'data.target.sys.contentful_id'),
59
+ );
60
+
61
+ return documentToReactComponents(json, {
62
+ renderMark: {
63
+ [MARKS.BOLD]: (text) => <strong>{text}</strong>,
64
+ [MARKS.ITALIC]: (text) => <i>{text}</i>,
65
+ [MARKS.UNDERLINE]: (text) => <u>{text}</u>,
66
+ [MARKS.CODE]: (text) => <code>{text}</code>,
67
+ },
68
+ renderNode: {
69
+ [BLOCKS.PARAGRAPH]: (node, children) => (
70
+ <Typography component="p">{children}</Typography>
71
+ ),
72
+ [BLOCKS.HEADING_1]: (node, children) => (
73
+ <Typography variant="h1" gutterBottom>
74
+ {children}
75
+ </Typography>
76
+ ),
77
+ [BLOCKS.HEADING_2]: (node, children) => (
78
+ <Typography variant="h2" gutterBottom>
79
+ {children}
80
+ </Typography>
81
+ ),
82
+ [BLOCKS.HEADING_3]: (node, children) => (
83
+ <Typography variant="h3" gutterBottom>
84
+ {children}
85
+ </Typography>
86
+ ),
87
+ [BLOCKS.HEADING_4]: (node, children) => (
88
+ <Typography variant="h4" gutterBottom>
89
+ {children}
90
+ </Typography>
91
+ ),
92
+ [BLOCKS.HEADING_5]: (node, children) => (
93
+ <Typography variant="h5" gutterBottom>
94
+ {children}
95
+ </Typography>
96
+ ),
97
+ [BLOCKS.HEADING_6]: (node, children) => (
98
+ <Typography variant="h6" gutterBottom>
99
+ {children}
100
+ </Typography>
101
+ ),
102
+ [BLOCKS.OL_LIST]: (node, children) => (
103
+ <List component="ol">{children}</List>
104
+ ),
105
+ [BLOCKS.UL_LIST]: (node, children) => (
106
+ <List component="ul">{children}</List>
107
+ ),
108
+ [BLOCKS.LIST_ITEM]: (node, children) => (
109
+ <ListItem>
110
+ <ListItemIcon>
111
+ <CheckCircleIcon />
112
+ </ListItemIcon>
113
+ {children}
114
+ </ListItem>
115
+ ),
116
+ [BLOCKS.HR]: () => <Divider />,
117
+ [BLOCKS.QUOTE]: (node, children) => (
118
+ <blockquote>{children}</blockquote>
119
+ ),
120
+ [BLOCKS.EMBEDDED_ASSET]: (node) =>
121
+ imageRender(node, locale),
122
+ [BLOCKS.EMBEDDED_ENTRY]: () => null,
123
+ [INLINES.EMBEDDED_ENTRY]: (node) => {
124
+ const path = getFromSitemap(node);
125
+
126
+ return path ? (
127
+ <Box my={2}>
128
+ <Card component="aside">
129
+ <CardActionArea component={Link} to={path}>
130
+ <CardContent>
131
+ <Box p={2}>
132
+ <Typography
133
+ variant="body2"
134
+ component="h3"
135
+ gutterBottom
136
+ >
137
+ {get(
138
+ node,
139
+ `data.target.fields.title.${locale}`,
140
+ )}
141
+ </Typography>
142
+ <Typography component="small">
143
+ {get(
144
+ node,
145
+ `data.target.fields.description.${locale}`,
146
+ )}
147
+ </Typography>
148
+ </Box>
149
+ </CardContent>
150
+ </CardActionArea>
151
+ </Card>
152
+ </Box>
153
+ ) : null;
154
+ },
155
+ },
156
+ });
157
+ };
158
+
159
+ const RichText = ({ json, locale }) => {
160
+ const data = useStaticQuery(graphql`
161
+ {
162
+ allSitePage {
163
+ nodes {
164
+ path
165
+ pageContext
166
+ }
167
+ }
168
+ }
169
+ `);
170
+
171
+ return (
172
+ <div>
173
+ {renderRichText(
174
+ json,
175
+ locale,
176
+ data.allSitePage.nodes.reduce((acc, next, i) => {
177
+ acc[get(next, 'pageContext.contentful_id', i)] =
178
+ next.path;
179
+ return acc;
180
+ }, {}),
181
+ )}
182
+ </div>
183
+ );
184
+ };
185
+
186
+ RichText.propTypes = {
187
+ // eslint-disable-next-line
188
+ json: PropTypes.object,
189
+ locale: PropTypes.string,
190
+ };
191
+
192
+ RichText.defaultProps = {
193
+ locale: 'en-CA',
194
+ };
195
+
196
+ export default RichText;
@@ -1,124 +1,124 @@
1
- import React from 'react';
2
- import { get, isFunction, isObject } from 'lodash';
3
- import PropTypes from 'prop-types';
4
- import { Helmet } from 'react-helmet';
5
- import { browser } from 'q3-ui-helpers';
6
- import useSiteMetaData from './useSiteMetaData';
7
-
8
- const withContent = (output) => (content) =>
9
- content && isFunction(output) ? output(content) : [];
10
-
11
- export const getStartUrl = () =>
12
- browser.isBrowserReady()
13
- ? get(window, 'location.host')
14
- : '';
15
-
16
- export const generateMetaDescriptionOptions = withContent(
17
- (content) => [
18
- {
19
- name: 'description',
20
- content,
21
- },
22
- {
23
- property: 'og:description',
24
- content,
25
- },
26
- {
27
- name: 'twitter:description',
28
- content,
29
- },
30
- ],
31
- );
32
-
33
- export const generateMetaTitleOptions = withContent(
34
- (content) => [
35
- {
36
- property: 'og:title',
37
- content,
38
- },
39
- {
40
- name: 'twitter:title',
41
- content,
42
- },
43
- ],
44
- );
45
-
46
- export const generateBrand = (xs) =>
47
- xs ? `%s | ${xs}` : undefined;
48
-
49
- export const generateIcons = (site = {}) =>
50
- site?.favicon
51
- ? [
52
- {
53
- src: site.favicon,
54
- sizes: '512x512',
55
- type: 'image/png',
56
- },
57
- ]
58
- : [];
59
-
60
- export const generateManifest = (site = {}) => ({
61
- background_color: site.color,
62
- description: site.description,
63
- display: 'fullscreen',
64
- icons: generateIcons(site),
65
- name: site.title,
66
- start_url: getStartUrl(),
67
- short_name: site.brand,
68
- theme_color: site.color,
69
- });
70
-
71
- const SEO = ({ description, lang, meta, title }) => {
72
- const site = useSiteMetaData();
73
- const metaDescription = description || site.description;
74
- const metaTitle = title || site.title;
75
- const manifestData = generateManifest(site);
76
-
77
- return (
78
- <Helmet
79
- htmlAttributes={{
80
- lang,
81
- }}
82
- title={metaTitle}
83
- titleTemplate={generateBrand(site.brand)}
84
- meta={[
85
- ...generateMetaTitleOptions(metaTitle),
86
- ...generateMetaDescriptionOptions(metaDescription),
87
- {
88
- property: 'og:type',
89
- content: 'website',
90
- },
91
- {
92
- name: 'twitter:card',
93
- content: 'summary',
94
- },
95
- ].concat(meta)}
96
- >
97
- {isObject(manifestData) ? (
98
- <link
99
- rel="manifest"
100
- href={`data:application/manifest+json,${encodeURIComponent(
101
- JSON.stringify(manifestData),
102
- )}`}
103
- />
104
- ) : null}
105
- <link rel="icon" href={site.favicon} />
106
- </Helmet>
107
- );
108
- };
109
-
110
- SEO.defaultProps = {
111
- lang: 'en',
112
- meta: [],
113
- description: '',
114
- title: '',
115
- };
116
-
117
- SEO.propTypes = {
118
- description: PropTypes.string,
119
- lang: PropTypes.string,
120
- meta: PropTypes.arrayOf(PropTypes.object),
121
- title: PropTypes.string,
122
- };
123
-
124
- export default SEO;
1
+ import React from 'react';
2
+ import { get, isFunction, isObject } from 'lodash';
3
+ import PropTypes from 'prop-types';
4
+ import { Helmet } from 'react-helmet';
5
+ import { browser } from 'q3-ui-helpers';
6
+ import useSiteMetaData from './useSiteMetaData';
7
+
8
+ const withContent = (output) => (content) =>
9
+ content && isFunction(output) ? output(content) : [];
10
+
11
+ export const getStartUrl = () =>
12
+ browser.isBrowserReady()
13
+ ? get(window, 'location.host')
14
+ : '';
15
+
16
+ export const generateMetaDescriptionOptions = withContent(
17
+ (content) => [
18
+ {
19
+ name: 'description',
20
+ content,
21
+ },
22
+ {
23
+ property: 'og:description',
24
+ content,
25
+ },
26
+ {
27
+ name: 'twitter:description',
28
+ content,
29
+ },
30
+ ],
31
+ );
32
+
33
+ export const generateMetaTitleOptions = withContent(
34
+ (content) => [
35
+ {
36
+ property: 'og:title',
37
+ content,
38
+ },
39
+ {
40
+ name: 'twitter:title',
41
+ content,
42
+ },
43
+ ],
44
+ );
45
+
46
+ export const generateBrand = (xs) =>
47
+ xs ? `%s | ${xs}` : undefined;
48
+
49
+ export const generateIcons = (site = {}) =>
50
+ site?.favicon
51
+ ? [
52
+ {
53
+ src: site.favicon,
54
+ sizes: '512x512',
55
+ type: 'image/png',
56
+ },
57
+ ]
58
+ : [];
59
+
60
+ export const generateManifest = (site = {}) => ({
61
+ background_color: site.color,
62
+ description: site.description,
63
+ display: 'fullscreen',
64
+ icons: generateIcons(site),
65
+ name: site.title,
66
+ start_url: getStartUrl(),
67
+ short_name: site.brand,
68
+ theme_color: site.color,
69
+ });
70
+
71
+ const SEO = ({ description, lang, meta, title }) => {
72
+ const site = useSiteMetaData();
73
+ const metaDescription = description || site.description;
74
+ const metaTitle = title || site.title;
75
+ const manifestData = generateManifest(site);
76
+
77
+ return (
78
+ <Helmet
79
+ htmlAttributes={{
80
+ lang,
81
+ }}
82
+ title={metaTitle}
83
+ titleTemplate={generateBrand(site.brand)}
84
+ meta={[
85
+ ...generateMetaTitleOptions(metaTitle),
86
+ ...generateMetaDescriptionOptions(metaDescription),
87
+ {
88
+ property: 'og:type',
89
+ content: 'website',
90
+ },
91
+ {
92
+ name: 'twitter:card',
93
+ content: 'summary',
94
+ },
95
+ ].concat(meta)}
96
+ >
97
+ {isObject(manifestData) ? (
98
+ <link
99
+ rel="manifest"
100
+ href={`data:application/manifest+json,${encodeURIComponent(
101
+ JSON.stringify(manifestData),
102
+ )}`}
103
+ />
104
+ ) : null}
105
+ <link rel="icon" href={site.favicon} />
106
+ </Helmet>
107
+ );
108
+ };
109
+
110
+ SEO.defaultProps = {
111
+ lang: 'en',
112
+ meta: [],
113
+ description: '',
114
+ title: '',
115
+ };
116
+
117
+ SEO.propTypes = {
118
+ description: PropTypes.string,
119
+ lang: PropTypes.string,
120
+ meta: PropTypes.arrayOf(PropTypes.object),
121
+ title: PropTypes.string,
122
+ };
123
+
124
+ export default SEO;