@openeventkit/event-site 2.0.111 → 2.0.112

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 (36) hide show
  1. package/gatsby-browser.js +1 -1
  2. package/{gatsby-config.js → gatsby-config.mjs} +56 -20
  3. package/gatsby-node.js +145 -92
  4. package/gatsby-ssr.js +2 -14
  5. package/package.json +29 -27
  6. package/src/cms/cms-utils.js +15 -8
  7. package/src/cms/cms.js +1 -1
  8. package/src/cms/config/collections/configurationsCollection/siteSettings/index.js +25 -5
  9. package/src/cms/config/collections/configurationsCollection/siteSettings/typeDefs.js +6 -0
  10. package/src/cms/config/collections/contentPagesCollection/typeDefs.js +8 -1
  11. package/src/cms/config/collections/defaultPagesCollection/marketingPage/index.js +5 -5
  12. package/src/cms/config/collections/defaultPagesCollection/marketingPage/typeDefs.js +4 -4
  13. package/src/cms/preview-templates/ContentPagePreview.js +41 -13
  14. package/src/cms/widgets/IdentityProviderParamControl.js +1 -1
  15. package/src/components/DisqusComponent.js +1 -1
  16. package/src/components/LiteScheduleComponent.js +9 -11
  17. package/src/components/ResponsiveImage.js +30 -0
  18. package/src/components/summit-my-orders-tickets/components/TicketPopup/TicketPopupEditDetailsForm/TicketPopupEditDetailsForm.js +4 -4
  19. package/src/content/site-settings/index.json +6 -1
  20. package/src/pages/index.js +6 -6
  21. package/src/pages/maintenance.js +18 -0
  22. package/src/styles/marketing.module.scss +6 -4
  23. package/src/styles/style.scss +0 -26
  24. package/src/templates/content-page/index.js +74 -0
  25. package/src/templates/content-page/shortcodes.js +17 -0
  26. package/src/templates/content-page/template.js +21 -0
  27. package/src/templates/marketing-page-template.js +66 -38
  28. package/src/utils/buildPolyfills.js +18 -0
  29. package/src/utils/filePath.js +18 -14
  30. package/src/utils/useSiteSettings.js +4 -0
  31. package/src/components/Content.js +0 -42
  32. package/src/content/maintenance.json +0 -5
  33. package/src/pages/maintenance.md +0 -3
  34. package/src/templates/content-page.js +0 -92
  35. package/src/templates/maintenance-page.js +0 -40
  36. package/static/admin/admin.css +0 -3
@@ -1,8 +1,8 @@
1
- import * as React from "react";
1
+ import React, { useEffect, useRef, useState } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { navigate } from "gatsby";
4
4
  import { GatsbyImage, getImage } from "gatsby-plugin-image";
5
- import Markdown from "markdown-to-jsx";
5
+ import Mdx from "@mdx-js/runtime";
6
6
 
7
7
  import Layout from "../components/Layout";
8
8
  import AttendanceTrackerComponent from "../components/AttendanceTrackerComponent";
@@ -11,6 +11,7 @@ import LiteScheduleComponent from "../components/LiteScheduleComponent";
11
11
  import DisqusComponent from "../components/DisqusComponent";
12
12
  import Countdown from "../components/Countdown";
13
13
  import Link from "../components/Link";
14
+ import ResponsiveImage from "../components/ResponsiveImage";
14
15
 
15
16
  import Masonry from "react-masonry-css";
16
17
  import Slider from "react-slick";
@@ -29,6 +30,11 @@ const sliderSettings = {
29
30
  slidesToScroll: 1
30
31
  };
31
32
 
33
+ const shortcodes = {
34
+ a: Link,
35
+ img: ResponsiveImage
36
+ };
37
+
32
38
  const MarketingPageTemplate = ({
33
39
  location,
34
40
  data,
@@ -37,6 +43,22 @@ const MarketingPageTemplate = ({
37
43
  summitPhase,
38
44
  isLoggedUser,
39
45
  }) => {
46
+ const rightColumnRef = useRef(null);
47
+ const [rightColumnHeight, setRightColumnHeight] = useState();
48
+
49
+ const onResize = () => {
50
+ if (rightColumnRef?.current) {
51
+ setRightColumnHeight(rightColumnRef.current.firstChild.clientHeight);
52
+ }
53
+ };
54
+
55
+ useEffect(() => {
56
+ onResize();
57
+ window.addEventListener("resize", onResize);
58
+ return () => {
59
+ window.removeEventListener("resize", onResize);
60
+ };
61
+ }, [data, rightColumnRef]);
40
62
 
41
63
  const {
42
64
  marketingPageJson: {
@@ -51,8 +73,8 @@ const MarketingPageTemplate = ({
51
73
  if (widgets?.schedule && isLoggedUser && summitPhase !== PHASES.BEFORE) {
52
74
  scheduleProps = {
53
75
  ...scheduleProps,
54
- onEventClick: (ev) => navigate(`/a/event/${ev.id}`),
55
- }
76
+ onEventClick: (ev) => navigate(`/a/event/${ev.id}`)
77
+ };
56
78
  }
57
79
 
58
80
  const shouldRenderMasonry = masonry?.display;
@@ -66,43 +88,49 @@ const MarketingPageTemplate = ({
66
88
  />
67
89
  {summit && countdown?.display && <Countdown summit={summit} text={countdown?.text} />}
68
90
  <div className="columns">
69
- <div className={`column mt-3 px-6 py-6 ${shouldRenderMasonry ? "is-half" : ""} ${styles.leftColumn ? styles.leftColumn : ""}`} style={{ position: 'relative' }}>
70
- {widgets?.text?.display && widgets?.text?.content &&
71
- <Markdown>
72
- {widgets.text.content}
73
- </Markdown>
91
+ <div
92
+ className={`column mt-3 px-6 py-6 ${shouldRenderMasonry ? "is-half" : ""} ${styles.leftColumn || ""}`}
93
+ style={{ maxHeight: shouldRenderMasonry && rightColumnHeight ? rightColumnHeight : "none" }}
94
+ >
95
+ {widgets?.content?.display && widgets?.content?.body &&
96
+ <Mdx components={shortcodes}>
97
+ {widgets.content.body}
98
+ </Mdx>
74
99
  }
75
100
  {widgets?.schedule?.display &&
76
- <>
77
- <h2><b>{widgets.schedule.title}</b></h2>
78
- <LiteScheduleComponent
79
- {...scheduleProps}
80
- lastDataSync={lastDataSync}
81
- id={`marketing_lite_schedule_${lastDataSync}`}
82
- page="marketing-site"
83
- showAllEvents={true}
84
- showSearch={false}
85
- showNav={true}
86
- />
87
- </>
101
+ <>
102
+ <h2><b>{widgets.schedule.title}</b></h2>
103
+ <LiteScheduleComponent
104
+ {...scheduleProps}
105
+ lastDataSync={lastDataSync}
106
+ id={`marketing_lite_schedule_${lastDataSync}`}
107
+ page="marketing-site"
108
+ showAllEvents={true}
109
+ showSearch={false}
110
+ showNav={true}
111
+ />
112
+ </>
88
113
  }
89
114
  {widgets?.disqus?.display &&
90
- <>
91
- <h2><b>{widgets.disqus.title}</b></h2>
92
- <DisqusComponent page="marketing-site"/>
93
- </>
115
+ <>
116
+ <h2><b>{widgets.disqus.title}</b></h2>
117
+ <DisqusComponent page="marketing-site"/>
118
+ </>
94
119
  }
95
120
  {widgets?.image?.display &&
96
- widgets?.image?.image.src &&
97
- <>
98
- <h2><b>{widgets.image.title}</b></h2>
99
- <br />
100
- <GatsbyImage image={getImage(widgets.image.image.src)} alt={widgets.image.image.alt ?? ""} />
101
- </>
121
+ widgets?.image?.image.src &&
122
+ <>
123
+ <h2><b>{widgets.image.title}</b></h2>
124
+ <br />
125
+ <GatsbyImage image={getImage(widgets.image.image.src)} alt={widgets.image.image.alt ?? ""} />
126
+ </>
102
127
  }
103
128
  </div>
104
129
  {shouldRenderMasonry &&
105
- <div className={`column is-half px-0 pb-0 ${styles.rightColumn ? styles.rightColumn : ""}`}>
130
+ <div
131
+ ref={rightColumnRef}
132
+ className={`column px-0 pb-0 is-half ${styles.rightColumn || ""}`}
133
+ >
106
134
  <Masonry
107
135
  breakpointCols={2}
108
136
  className="my-masonry-grid"
@@ -111,7 +139,7 @@ const MarketingPageTemplate = ({
111
139
  if (item.images && item.images.length === 1) {
112
140
  const image = getImage(item.images[0].src);
113
141
  return (
114
- <div className={'single'} key={index}>
142
+ <div className={"single"} key={index}>
115
143
  {item.images[0].link ?
116
144
  <Link to={item.images[0].link}>
117
145
  <GatsbyImage image={image} alt={item.images[0].alt ?? ""} />
@@ -120,7 +148,7 @@ const MarketingPageTemplate = ({
120
148
  <GatsbyImage image={image} alt={item.images[0].alt ?? ""} />
121
149
  }
122
150
  </div>
123
- )
151
+ );
124
152
  } else if (item.images && item.images.length > 1) {
125
153
  return (
126
154
  <Slider {...sliderSettings} key={index}>
@@ -136,14 +164,14 @@ const MarketingPageTemplate = ({
136
164
  <GatsbyImage image={img} alt={image.alt ?? ""} />
137
165
  }
138
166
  </div>
139
- )
167
+ );
140
168
  })}
141
169
  </Slider>
142
- )
170
+ );
143
171
  } else {
144
172
  return (
145
173
  <div className="single" key={index} />
146
- )
174
+ );
147
175
  }
148
176
  })}
149
177
  </Masonry>
@@ -151,7 +179,7 @@ const MarketingPageTemplate = ({
151
179
  }
152
180
  </div>
153
181
  </Layout>
154
- )
182
+ );
155
183
  };
156
184
 
157
185
  MarketingPageTemplate.propTypes = {
@@ -0,0 +1,18 @@
1
+ import { JSDOM } from "jsdom";
2
+ import { XMLHttpRequest } from "xmlhttprequest";
3
+
4
+ const noop = () => {};
5
+
6
+ const matchMedia = () => ({
7
+ matches: false,
8
+ addListener: noop,
9
+ removeListener: noop
10
+ });
11
+
12
+ const { window } = new JSDOM("...");
13
+
14
+ global.window = window;
15
+ global.window.matchMedia = matchMedia;
16
+ global.document = window.document;
17
+ global.navigator = window.navigator;
18
+ global.XMLHttpRequest = XMLHttpRequest;
@@ -1,7 +1,9 @@
1
1
  const DATA_DIR_PATH = "src/data";
2
2
  const STATIC_CONTENT_DIR_PATH = "src/content";
3
3
  const DEFAULTS_DIR_PATH = "src/defaults";
4
- const CONTENT_PAGES_DIR_PATH = "src/pages/content-pages";
4
+ const PAGES_DIR_PATH = "src/pages";
5
+ const CONTENT_PAGES_PATH_NAME = `content-pages`;
6
+ const CONTENT_PAGES_DIR_PATH = `${PAGES_DIR_PATH}/${CONTENT_PAGES_PATH_NAME}`;
5
7
  const STYLES_DIR_PATH = "src/styles";
6
8
  const DEFAULT_COLORS_FILE_PATH = `${DEFAULTS_DIR_PATH}/colors.json`;
7
9
  const COLORS_FILE_PATH = `${DATA_DIR_PATH}/colors.json`;
@@ -33,7 +35,7 @@ const VOTEABLE_PRESENTATIONS_FILE_NAME = "voteable-presentations.json";
33
35
  const VOTEABLE_PRESENTATIONS_FILE_PATH = `${DATA_DIR_PATH}/${VOTEABLE_PRESENTATIONS_FILE_NAME}`;
34
36
  const POSTERS_PAGES_FILE_PATH = `${STATIC_CONTENT_DIR_PATH}/posters-pages.json`;
35
37
  const MARKETING_SETTINGS_FILE_PATH = `${DATA_DIR_PATH}/marketing-settings.json`;
36
- const MAINTENANCE_FILE_PATH = `${STATIC_CONTENT_DIR_PATH}/maintenance.json`;
38
+ const MAINTENANCE_PATH_NAME = `maintenance`;
37
39
  const EXPO_HALL_PAGE_FILE_PATH = `${STATIC_CONTENT_DIR_PATH}/expo-hall-page/index.json`;
38
40
  const INVITATIONS_REJECT_PAGE_FILE_PATH = `${STATIC_CONTENT_DIR_PATH}/invitations-reject-page/index.json`;
39
41
  const SPONSORS_FILE_NAME = "sponsors.json";
@@ -44,25 +46,27 @@ const APPLE_PAY_DOMAIN_FILE_PATH = `/static/.well-known/`
44
46
  const APPLE_PAY_DOMAIN_FILE_NAME = `apple-developer-merchantid-domain-association`;
45
47
 
46
48
  exports.REQUIRED_DIR_PATHS = [
47
- DATA_DIR_PATH,
48
- STATIC_CONTENT_DIR_PATH,
49
- CONTENT_PAGES_DIR_PATH,
50
- STYLES_DIR_PATH,
51
- SITE_SETTINGS_DIR_PATH,
52
- MARKETING_PAGE_DIR_PATH,
53
- LOBBY_PAGE_DIR_PATH,
54
- INVITATIONS_REJECT_PAGE_FILE_PATH,
55
- NAVBAR_DIR_PATH,
56
- FOOTER_DIR_PATH
49
+ DATA_DIR_PATH,
50
+ STATIC_CONTENT_DIR_PATH,
51
+ CONTENT_PAGES_DIR_PATH,
52
+ STYLES_DIR_PATH,
53
+ SITE_SETTINGS_DIR_PATH,
54
+ MARKETING_PAGE_DIR_PATH,
55
+ LOBBY_PAGE_DIR_PATH,
56
+ INVITATIONS_REJECT_PAGE_FILE_PATH,
57
+ NAVBAR_DIR_PATH,
58
+ FOOTER_DIR_PATH
57
59
  ];
58
60
  exports.STATIC_CONTENT_DIR_PATH = STATIC_CONTENT_DIR_PATH;
61
+ exports.PAGES_DIR_PATH = PAGES_DIR_PATH;
62
+ exports.CONTENT_PAGES_PATH_NAME = CONTENT_PAGES_PATH_NAME;
63
+ exports.CONTENT_PAGES_DIR_PATH = CONTENT_PAGES_DIR_PATH;
59
64
  exports.DEFAULT_COLORS_FILE_PATH = DEFAULT_COLORS_FILE_PATH;
60
65
  exports.COLORS_FILE_PATH = COLORS_FILE_PATH;
61
66
  exports.COLORS_SASS_FILE_PATH = COLORS_SASS_FILE_PATH;
62
67
  exports.FONTS_SCSS_FILE_PATH = FONTS_SCSS_FILE_PATH;
63
68
  exports.SITE_SETTINGS_DIR_PATH = SITE_SETTINGS_DIR_PATH;
64
69
  exports.SITE_SETTINGS_FILE_PATH = SITE_SETTINGS_FILE_PATH;
65
- exports.CONTENT_PAGES_DIR_PATH = CONTENT_PAGES_DIR_PATH;
66
70
  exports.MARKETING_PAGE_FILE_PATH = MARKETING_PAGE_FILE_PATH;
67
71
  exports.LOBBY_PAGE_FILE_PATH = LOBBY_PAGE_FILE_PATH;
68
72
  exports.ADS_FILE_PATH = ADS_FILE_PATH;
@@ -83,7 +87,7 @@ exports.VOTEABLE_PRESENTATIONS_FILE_NAME = VOTEABLE_PRESENTATIONS_FILE_NAME;
83
87
  exports.VOTEABLE_PRESENTATIONS_FILE_PATH = VOTEABLE_PRESENTATIONS_FILE_PATH;
84
88
  exports.POSTERS_PAGES_FILE_PATH = POSTERS_PAGES_FILE_PATH;
85
89
  exports.MARKETING_SETTINGS_FILE_PATH = MARKETING_SETTINGS_FILE_PATH;
86
- exports.MAINTENANCE_FILE_PATH = MAINTENANCE_FILE_PATH;
90
+ exports.MAINTENANCE_PATH_NAME = MAINTENANCE_PATH_NAME;
87
91
  exports.EXPO_HALL_PAGE_FILE_PATH = EXPO_HALL_PAGE_FILE_PATH;
88
92
  exports.INVITATIONS_REJECT_PAGE_FILE_PATH = INVITATIONS_REJECT_PAGE_FILE_PATH;
89
93
  exports.SPONSORS_FILE_PATH = SPONSORS_FILE_PATH;
@@ -47,6 +47,10 @@ const siteSettingsQuery = graphql`
47
47
  }
48
48
  providerLogoSize
49
49
  }
50
+ maintenanceMode {
51
+ title
52
+ subtitle
53
+ }
50
54
  }
51
55
  }
52
56
  `;
@@ -1,42 +0,0 @@
1
- import React, { useState, useEffect } from 'react'
2
- import PropTypes from 'prop-types'
3
- import sanitizeHtml from 'sanitize-html';
4
-
5
- export const HTMLContent = ({ content, className }) => {
6
- const [cleanHTML, setCleanHTML] = useState(content);
7
-
8
- useEffect(() => {
9
- const clean = sanitizeHtml(content, {
10
- // adds custom settings to default settings (https://www.npmjs.com/package/sanitize-html#default-options)
11
- allowedTags: sanitizeHtml.defaults.allowedTags.concat(['iframe', 'img']),
12
- allowedAttributes: {
13
- ...sanitizeHtml.defaults.allowedAttributes,
14
- 'iframe': ['src', 'width', 'height', 'frameborder', 'allow', 'allowfullscreen'],
15
- 'a': ['target'],
16
- '*': ['href', 'class']
17
- },
18
- exclusiveFilter: (frame) => {
19
- // removing a and p tags with no text or media childrens
20
- return (frame.tag === 'a' || frame.tag === 'p') && !frame.text.trim() && !frame.mediaChildren;
21
- }
22
- });
23
- setCleanHTML(clean);
24
- }, [content])
25
-
26
- return (
27
- <div className={className} dangerouslySetInnerHTML={{ __html: cleanHTML }} />
28
- )
29
- }
30
-
31
- const Content = ({ content, className }) => (
32
- <div className={className}>{content}</div>
33
- )
34
-
35
- Content.propTypes = {
36
- content: PropTypes.node,
37
- className: PropTypes.string,
38
- }
39
-
40
- HTMLContent.propTypes = Content.propTypes
41
-
42
- export default Content
@@ -1,5 +0,0 @@
1
- {
2
- "enabled": false,
3
- "title": "Site under maintenance",
4
- "subtitle": "Please reload page shortly"
5
- }
@@ -1,3 +0,0 @@
1
- ---
2
- templateKey: maintenance-page
3
- ---
@@ -1,92 +0,0 @@
1
- import * as React from "react";
2
- import PropTypes from "prop-types";
3
- import { connect } from "react-redux";
4
- import { graphql } from "gatsby";
5
- import { Redirect } from "@gatsbyjs/reach-router";
6
- import Seo from "../components/Seo";
7
- import Layout from "../components/Layout";
8
- import Content, { HTMLContent } from "../components/Content";
9
- import { titleFromPathname } from "../utils/urlFormating";
10
-
11
-
12
- import { USER_REQUIREMENTS } from "../cms/config/collections/contentPagesCollection"
13
-
14
- export const ContentPageTemplate = ({
15
- title,
16
- content,
17
- contentComponent
18
- }) => {
19
- const PageContent = contentComponent || Content
20
-
21
- return (
22
- <div className="content">
23
- <h1>{title}</h1>
24
- <PageContent content={content} />
25
- </div>
26
- )
27
- }
28
-
29
- ContentPageTemplate.propTypes = {
30
- title: PropTypes.string,
31
- content: PropTypes.string,
32
- contentComponent: PropTypes.func,
33
- }
34
-
35
- const ContentPage = ({ data, isLoggedUser, hasTicket, isAuthorized }) => {
36
- const { frontmatter: {title, userRequirement}, html } = data.markdownRemark
37
- // if isAuthorized byoass the AUTHZ check
38
- if (!isAuthorized && (
39
- (userRequirement === USER_REQUIREMENTS.loggedIn && !isLoggedUser) || (userRequirement === USER_REQUIREMENTS.hasTicket && !hasTicket)
40
- )) {
41
- return <Redirect to='/' noThrow />
42
- }
43
-
44
- return (
45
- <Layout>
46
- <ContentPageTemplate
47
- contentComponent={HTMLContent}
48
- title={title}
49
- content={html}
50
- />
51
- </Layout>
52
- )
53
- }
54
-
55
- ContentPage.propTypes = {
56
- data: PropTypes.shape({
57
- markdownRemark: PropTypes.shape({
58
- frontmatter: PropTypes.object,
59
- }),
60
- }),
61
- isLoggedUser: PropTypes.bool,
62
- hasTicket: PropTypes.bool
63
- };
64
-
65
- const mapStateToProps = ({ loggedUserState, userState }) => ({
66
- isLoggedUser: loggedUserState.isLoggedUser,
67
- hasTicket: userState.hasTicket,
68
- isAuthorized: userState.isAuthorized
69
- });
70
-
71
- export default connect(mapStateToProps, null)(ContentPage);
72
-
73
- export const contentPageQuery = graphql`
74
- query ($id: String!) {
75
- markdownRemark(id: { eq: $id }) {
76
- html
77
- frontmatter {
78
- title
79
- userRequirement
80
- }
81
- }
82
- }
83
- `;
84
-
85
- export const Head = ({
86
- location
87
- }) => (
88
- <Seo
89
- title={titleFromPathname(location.pathname)}
90
- location={location}
91
- />
92
- );
@@ -1,40 +0,0 @@
1
- import * as React from "react";
2
- import PropTypes from "prop-types";
3
- import maintenanceMode from "content/maintenance.json";
4
-
5
- import HeroComponent from "../components/HeroComponent";
6
-
7
- import "../styles/bulma.scss";
8
-
9
- const MaintenancePageTemplate = ({
10
- title,
11
- subtitle
12
- }) => {
13
- return (
14
- <HeroComponent
15
- title={title}
16
- subtitle={subtitle}
17
- />
18
- );
19
- }
20
-
21
- MaintenancePageTemplate.propTypes = {
22
- title: PropTypes.string,
23
- subtitle: PropTypes.string,
24
- }
25
-
26
- const MaintenancePage = () => {
27
- const {
28
- title,
29
- subtitle
30
- } = maintenanceMode;
31
-
32
- return (
33
- <MaintenancePageTemplate
34
- title={title}
35
- subtitle={subtitle}
36
- />
37
- )
38
- };
39
-
40
- export default MaintenancePage;
@@ -1,3 +0,0 @@
1
- [data-slate-editor] {
2
- -webkit-user-modify: read-write !important;
3
- }