@openeventkit/event-site 2.1.50 → 2.1.52

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 (33) hide show
  1. package/fn-wide.png +0 -0
  2. package/gatsby-node.js +21 -4
  3. package/package.json +5 -4
  4. package/src/actions/event-actions.js +0 -2
  5. package/src/actions/extra-questions-actions.js +0 -5
  6. package/src/actions/presentation-actions.js +0 -5
  7. package/src/actions/summit-actions.js +0 -5
  8. package/src/actions/user-actions.js +11 -17
  9. package/src/cms/config/collections/configurationsCollection/siteSettings/index.js +21 -0
  10. package/src/cms/config/collections/configurationsCollection/siteSettings/typeDefs.js +5 -0
  11. package/src/cms/config/collections/contentPagesCollection/index.js +11 -1
  12. package/src/cms/config/collections/contentPagesCollection/typeDefs.js +1 -0
  13. package/src/cms/config/collections/defaultPagesCollection/marketingPage/index.js +2 -6
  14. package/src/cms/config/collections/defaultPagesCollection/marketingPage/typeDefs.js +0 -1
  15. package/src/cms/preview-templates/ContentPagePreview.js +12 -1
  16. package/src/components/AuthComponent.js +2 -1
  17. package/src/components/MarketingHero/MainColumn.js +23 -11
  18. package/src/components/RegisterButton.js +59 -0
  19. package/src/components/RegistrationFormShortcode.js +82 -0
  20. package/src/components/RegistrationModalComponent.js +124 -0
  21. package/src/content/marketing-page/index.json +1 -2
  22. package/src/content/site-settings/index.json +1 -1
  23. package/src/content/sponsors.json +1 -1
  24. package/src/pages/index.js +0 -1
  25. package/src/styles/colors.scss +7 -7
  26. package/src/styles/register-page.module.scss +23 -0
  27. package/src/templates/content-page/shortcodes.js +3 -5
  28. package/src/templates/register-page.js +96 -0
  29. package/src/utils/registrationConstants.js +7 -0
  30. package/src/utils/useRegistrationWidgetProps.js +204 -0
  31. package/src/utils/useSiteSettings.js +4 -0
  32. package/src/components/RegistrationLiteComponent.js +0 -293
  33. package/src/templates/login-page.js +0 -49
package/fn-wide.png ADDED
Binary file
package/gatsby-node.js CHANGED
@@ -454,6 +454,7 @@ exports.createPages = async ({ actions, graphql }) => {
454
454
  }
455
455
  frontmatter {
456
456
  templateKey
457
+ slug
457
458
  }
458
459
  internal {
459
460
  contentFilePath
@@ -471,17 +472,33 @@ exports.createPages = async ({ actions, graphql }) => {
471
472
  const nodes = result.data.allMdx.nodes;
472
473
 
473
474
  nodes.forEach((node) => {
474
- const { id, fields: { slug }, frontmatter: { templateKey }, internal: { contentFilePath } } = node;
475
+ const { id, fields: { slug }, frontmatter: { templateKey, slug: frontmatterSlug }, internal: { contentFilePath } } = node;
475
476
  const template = require.resolve(`./src/templates/${String(templateKey)}`);
476
- // remove content pages namespace from path
477
- const path = slug.replace(`${CONTENT_PAGES_PATH_NAME}`, "/");
477
+ // use frontmatter slug if set, otherwise derive from filename
478
+ const pagePath = frontmatterSlug
479
+ ? `/${frontmatterSlug.replace(/^\/+/, '')}/`
480
+ : slug.replace(`/${CONTENT_PAGES_PATH_NAME}`, "");
478
481
  const page = {
479
- path: path,
482
+ path: pagePath,
480
483
  component: `${template}?__contentFilePath=${contentFilePath}`,
481
484
  context: { id }
482
485
  };
483
486
  createPage(page);
484
487
  });
488
+
489
+ // Conditionally create /register page based on registrationMode
490
+ if (fs.existsSync(SITE_SETTINGS_FILE_PATH)) {
491
+ const siteSettings = JSON.parse(fs.readFileSync(SITE_SETTINGS_FILE_PATH));
492
+ const { REGISTRATION_MODE } = require('./src/utils/registrationConstants');
493
+ const registrationMode = siteSettings.registration?.registrationMode;
494
+ if (registrationMode === REGISTRATION_MODE.standalone) {
495
+ createPage({
496
+ path: '/register/',
497
+ component: require.resolve('./src/templates/register-page.js'),
498
+ context: {}
499
+ });
500
+ }
501
+ }
485
502
  };
486
503
 
487
504
  exports.onCreatePage = async ({ page, actions }) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openeventkit/event-site",
3
3
  "description": "Event Site",
4
- "version": "2.1.50",
4
+ "version": "2.1.52",
5
5
  "author": "Tipit LLC",
6
6
  "dependencies": {
7
7
  "@emotion/server": "^11.11.0",
@@ -55,7 +55,7 @@
55
55
  "font-awesome": "^4.7.0",
56
56
  "formik": "^2.4.6",
57
57
  "fs-extra": "^11.3.0",
58
- "full-schedule-widget": "3.1.2-beta.1",
58
+ "full-schedule-widget": "3.1.3",
59
59
  "gatsby": "^5.13.5",
60
60
  "gatsby-alias-imports": "^1.0.6",
61
61
  "gatsby-plugin-decap-cms": "^4.0.4",
@@ -89,7 +89,7 @@
89
89
  "moment-timezone": "^0.5.31",
90
90
  "my-orders-tickets-widget": "1.0.10",
91
91
  "object.assign": "^4.1.5",
92
- "openstack-uicore-foundation": "4.2.16",
92
+ "openstack-uicore-foundation": "4.2.29",
93
93
  "path-browserify": "^1.0.1",
94
94
  "prop-types": "^15.6.0",
95
95
  "react": "^18.2.0",
@@ -131,11 +131,12 @@
131
131
  "slick-carousel": "^1.8.1",
132
132
  "smoothscroll-polyfill": "^0.4.4",
133
133
  "socket.io-client": "^4.5.2",
134
+ "spark-md5": "^3.0.2",
134
135
  "speakers-widget": "4.0.2",
135
136
  "stream-browserify": "^3.0.0",
136
137
  "stream-chat": "^2.7.2",
137
138
  "stream-chat-react": "3.1.7",
138
- "summit-registration-lite": "6.0.8",
139
+ "summit-registration-lite": "7.0.2",
139
140
  "superagent": "8.0.9",
140
141
  "sweetalert2": "^11.11.1",
141
142
  "upcoming-events-widget": "3.0.7",
@@ -4,7 +4,6 @@ import {
4
4
  stopLoading,
5
5
  startLoading,
6
6
  } from 'openstack-uicore-foundation/lib/utils/actions';
7
- import { clearAccessToken } from 'openstack-uicore-foundation/lib/security/methods';
8
7
  import { getAccessTokenSafely } from '../utils/loginUtils';
9
8
 
10
9
  import { customErrorHandler } from '../utils/customErrorHandler';
@@ -72,7 +71,6 @@ export const getEventById = (
72
71
  dispatch(stopLoading());
73
72
  dispatch(createAction(GET_EVENT_DATA_ERROR)(e));
74
73
  console.log('ERROR: ', e);
75
- clearAccessToken();
76
74
  return (e);
77
75
  });
78
76
  };
@@ -1,7 +1,3 @@
1
- import {
2
- getAccessToken,
3
- clearAccessToken,
4
- } from 'openstack-uicore-foundation/lib/security/methods';
5
1
 
6
2
  import {
7
3
  getRequest,
@@ -44,7 +40,6 @@ export const getAttendeeData = (attendeeId) => async (dispatch, getState) => {
44
40
  .catch((e) => {
45
41
  dispatch(stopLoading());
46
42
  console.log('ERROR: ', e);
47
- clearAccessToken();
48
43
  return (e);
49
44
  });
50
45
  }
@@ -7,7 +7,6 @@ import {
7
7
 
8
8
  import {
9
9
  getAccessToken,
10
- clearAccessToken,
11
10
  } from 'openstack-uicore-foundation/lib/security/methods';
12
11
 
13
12
  import { customErrorHandler } from '../utils/customErrorHandler';
@@ -76,7 +75,6 @@ export const getAllVoteablePresentations = (page = 1, perPage = PresentationsDef
76
75
  }).catch(e => {
77
76
  console.log('ERROR: ', e);
78
77
  dispatch(stopLoading());
79
- clearAccessToken();
80
78
  return (e);
81
79
  });
82
80
  }
@@ -105,7 +103,6 @@ export const getVoteablePresentations = (page = 1, perPage = PresentationsDefaul
105
103
  { page }
106
104
  )(params)(dispatch).catch(e => {
107
105
  console.log('ERROR: ', e);
108
- clearAccessToken();
109
106
  return (e);
110
107
  });
111
108
  };
@@ -138,7 +135,6 @@ export const getPresentationById = (presentationId) => async (dispatch) => {
138
135
  console.log('ERROR: ', e);
139
136
  dispatch(stopLoading());
140
137
  dispatch(createAction(GET_PRESENTATION_DETAILS_ERROR)(e));
141
- clearAccessToken();
142
138
  return Promise.reject(e);
143
139
  });
144
140
  };
@@ -174,7 +170,6 @@ export const getRecommendedPresentations = (trackGroups) => async (dispatch) =>
174
170
  }).catch(e => {
175
171
  console.log('ERROR: ', e);
176
172
  dispatch(stopLoading());
177
- clearAccessToken();
178
173
  return (e);
179
174
  });
180
175
  };
@@ -1,7 +1,3 @@
1
- import {
2
- getAccessToken,
3
- clearAccessToken,
4
- } from 'openstack-uicore-foundation/lib/security/methods';
5
1
 
6
2
  import {
7
3
  getRequest,
@@ -43,7 +39,6 @@ export const getExtraQuestions = (attendeeId = null) => async (dispatch, getStat
43
39
  dispatch(stopLoading());
44
40
  }).catch(e => {
45
41
  console.log('ERROR: ', e);
46
- clearAccessToken();
47
42
  dispatch(stopLoading());
48
43
  return Promise.reject(e);
49
44
  });
@@ -12,7 +12,6 @@ import {
12
12
  import { putOnLocalStorage, getFromLocalStorage } from 'openstack-uicore-foundation/lib/utils/methods';
13
13
 
14
14
  import {
15
- clearAccessToken,
16
15
  passwordlessLogin,
17
16
  initLogOut
18
17
  } from 'openstack-uicore-foundation/lib/security/methods';
@@ -94,7 +93,6 @@ export const getDisqusSSO = (shortName) => async (dispatch, getState) => {
94
93
  .catch(e => {
95
94
  console.log('ERROR: ', e);
96
95
  Sentry.captureException(e)
97
- clearAccessToken();
98
96
  return Promise.reject(e);
99
97
  });
100
98
  }
@@ -128,9 +126,11 @@ export const getUserProfile = () => async (dispatch) => {
128
126
  }).catch((e) => {
129
127
  console.log('ERROR: ', e);
130
128
  dispatch(createAction(STOP_LOADING_PROFILE)());
131
- clearAccessToken();
132
- alertWarning('Error', "There was an error at Login Flow. Please retry.");
133
- initLogOut();
129
+ if (e?.status === 401) {
130
+ initLogOut();
131
+ } else {
132
+ alertWarning('Error', "There was an error at Login Flow. Please retry.");
133
+ }
134
134
  return (e);
135
135
  });
136
136
  }
@@ -158,7 +158,6 @@ export const getIDPProfile = () => async (dispatch) => {
158
158
  .catch((e) => {
159
159
  console.log('ERROR: ', e);
160
160
  dispatch(createAction(STOP_LOADING_IDP_PROFILE)())
161
- clearAccessToken();
162
161
  return (e);
163
162
  });
164
163
  }
@@ -212,7 +211,6 @@ export const scanBadge = (sponsorId) => async (dispatch) => {
212
211
  .catch(e => {
213
212
  console.log('ERROR: ', e);
214
213
  dispatch(createAction(SCAN_BADGE_ERROR)(e));
215
- clearAccessToken();
216
214
  return (e);
217
215
  });
218
216
  }
@@ -335,7 +333,9 @@ export const castPresentationVote = (presentation) => async (dispatch, getState)
335
333
 
336
334
  const errorHandler = (err) => (dispatch, state) => {
337
335
  const {status, response: {text}} = err;
338
- if (status === 412) {
336
+ if (status === 401) {
337
+ expiredToken(err);
338
+ } else if (status === 412) {
339
339
  if (text.includes('already vote')) {
340
340
  // 'confirm' as local vote
341
341
  dispatch(createAction(TOGGLE_PRESENTATION_VOTE)({presentation, isVoted: true}));
@@ -363,7 +363,6 @@ export const castPresentationVote = (presentation) => async (dispatch, getState)
363
363
  {presentation}
364
364
  )(params)(dispatch).catch((e) => {
365
365
  console.log('ERROR: ', e);
366
- clearAccessToken();
367
366
  // need to revert button state
368
367
  // first 'confirm' as local vote
369
368
  dispatch(createAction(TOGGLE_PRESENTATION_VOTE)({presentation, isVoted: true}));
@@ -387,7 +386,9 @@ export const uncastPresentationVote = (presentation) => async (dispatch, getStat
387
386
 
388
387
  const errorHandler = (err) => (dispatch, state) => {
389
388
  const {status, response: {text}} = err;
390
- if (status === 412 && text.includes('Vote not found')) {
389
+ if (status === 401) {
390
+ expiredToken(err);
391
+ } else if (status === 412 && text.includes('Vote not found')) {
391
392
  // tried removing a vote not longer present in api
392
393
  // confirming removal
393
394
  dispatch(createAction(TOGGLE_PRESENTATION_VOTE)({presentation, isVoted: false}));
@@ -405,7 +406,6 @@ export const uncastPresentationVote = (presentation) => async (dispatch, getStat
405
406
  {presentation}
406
407
  )(params)(dispatch).catch((e) => {
407
408
  console.log('ERROR: ', e);
408
- clearAccessToken();
409
409
  return e;
410
410
  });
411
411
  };
@@ -436,7 +436,6 @@ export const updateProfilePicture = (pic) => async (dispatch) => {
436
436
  .catch((e) => {
437
437
  console.log('ERROR: ', e);
438
438
  dispatch(createAction(STOP_LOADING_IDP_PROFILE)())
439
- clearAccessToken();
440
439
  return e;
441
440
  });
442
441
  }
@@ -466,7 +465,6 @@ export const updateProfile = (profile) => async (dispatch) => {
466
465
  .catch((e) => {
467
466
  console.log('ERROR: ', e);
468
467
  dispatch(createAction(STOP_LOADING_IDP_PROFILE)());
469
- clearAccessToken();
470
468
  return e;
471
469
  });
472
470
  }
@@ -497,7 +495,6 @@ export const updatePassword = (password) => async (dispatch) => {
497
495
  .catch((e) => {
498
496
  console.log('ERROR: ', e);
499
497
  dispatch(createAction(STOP_LOADING_IDP_PROFILE)())
500
- clearAccessToken();
501
498
  return e;
502
499
  });
503
500
  }
@@ -542,7 +539,6 @@ export const saveAttendeeQuestions = (values, ticketId = null) => async (dispatc
542
539
  }).catch(e => {
543
540
  dispatch(stopLoading());
544
541
  alertWarning('Error', "Error saving your Attendee info. Please retry.");
545
- clearAccessToken();
546
542
  return e;
547
543
  });
548
544
  };
@@ -581,7 +577,6 @@ export const getScheduleSyncLink = () => async (dispatch) => {
581
577
  customErrorHandler,
582
578
  )(params)(dispatch).catch((e) => {
583
579
  console.log('ERROR: ', e);
584
- clearAccessToken();
585
580
  return e;
586
581
  });
587
582
  };
@@ -636,7 +631,6 @@ export const doVirtualCheckIn = (attendee) => async (dispatch, getState) => {
636
631
  voidErrorHandler
637
632
  )(params)(dispatch).catch((e) => {
638
633
  console.log('ERROR: ', e);
639
- clearAccessToken();
640
634
  return e;
641
635
  });
642
636
  };
@@ -24,6 +24,7 @@ import {
24
24
  } from "@utils/envVariables";
25
25
 
26
26
  import { mapObjectToSelectOptions } from "../../../utils";
27
+ import { REGISTRATION_MODE } from "@utils/registrationConstants";
27
28
 
28
29
  const FONT_FORMATS = {
29
30
  truetype: "ttf",
@@ -179,6 +180,26 @@ const siteSettings = {
179
180
  })
180
181
  ]
181
182
  }),
183
+ objectField({
184
+ label: "Registration",
185
+ name: "registration",
186
+ fields: [
187
+ selectField({
188
+ label: "Registration Mode",
189
+ name: "registrationMode",
190
+ default: REGISTRATION_MODE.modal,
191
+ required: false,
192
+ options: mapObjectToSelectOptions(REGISTRATION_MODE),
193
+ hint: "MODAL: opens the registration form as a popup overlay. STANDALONE: redirects to a dedicated registration page. LINK: redirects to the URL specified in Registration Link, which can be an internal content page with an embedded registration form or an external URL."
194
+ }),
195
+ stringField({
196
+ label: "Registration Link",
197
+ name: "registrationLink",
198
+ required: false,
199
+ hint: "Only used when Registration Mode is LINK. Use a relative path (e.g. /my-page) for an internal page, or a full URL (e.g. https://example.com) for an external site. To embed the registration form in a content page, add the <RegistrationForm /> shortcode in the page body."
200
+ })
201
+ ]
202
+ }),
182
203
  objectField({
183
204
  label: "IDP Logo",
184
205
  name: "idpLogo",
@@ -43,12 +43,17 @@ module.exports = `
43
43
  providerLogo: File @fileByRelativePath
44
44
  providerLogoSize: Float
45
45
  }
46
+ type Registration {
47
+ registrationMode: String
48
+ registrationLink: String
49
+ }
46
50
  type MaintenanceMode {
47
51
  enabled: Boolean
48
52
  title: String
49
53
  subtitle: String
50
54
  }
51
55
  type SiteSettingsJson implements Node {
56
+ registration: Registration
52
57
  siteMetadata: SiteMetadata
53
58
  favicon: Favicon
54
59
  siteFont: SiteFont
@@ -11,6 +11,9 @@ import { CONTENT_PAGES_DIR_PATH } from "@utils/filePath";
11
11
  import { USER_REQUIREMENTS } from "@utils/pageAccessConstants";
12
12
 
13
13
  import { mapObjectToSelectOptions } from "../../utils";
14
+ import shortcodes from "../../../../templates/content-page/shortcodes";
15
+
16
+ const shortcodesHint = `Available shortcodes: ${Object.keys(shortcodes).map(name => `<${name} />`).join(", ")}`;
14
17
 
15
18
  const contentPagesCollection = {
16
19
  ...collectionDefaults({
@@ -33,6 +36,12 @@ const contentPagesCollection = {
33
36
  label: "Title",
34
37
  name: "title"
35
38
  }),
39
+ stringField({
40
+ label: "Slug",
41
+ name: "slug",
42
+ required: false,
43
+ hint: "URL path for this page (e.g. registration). Leave empty to use the default path based on the title. Changing this will change the page URL."
44
+ }),
36
45
  selectField({
37
46
  label: "User Requirement",
38
47
  name: "userRequirement",
@@ -42,7 +51,8 @@ const contentPagesCollection = {
42
51
  }),
43
52
  markdownField({
44
53
  label: "Body",
45
- name: "body"
54
+ name: "body",
55
+ hint: shortcodesHint
46
56
  })
47
57
  ]
48
58
  };
@@ -6,6 +6,7 @@ module.exports = `
6
6
  type MdxFrontmatter {
7
7
  templateKey: String
8
8
  title: String
9
+ slug: String
9
10
  userRequirement: String
10
11
  }
11
12
  type Mdx {
@@ -78,12 +78,8 @@ const marketingPage = {
78
78
  booleanField({
79
79
  label: "Display",
80
80
  name: "display",
81
- required: false
82
- }),
83
- stringField({
84
- label: "External Registration Link",
85
- name: "externalRegistrationLink",
86
- required: false
81
+ required: false,
82
+ hint: "Show or hide the register button on the hero. To change the register button behavior (open registration popup, navigate to standalone registration page, or redirect to an internal page or external URL), go to Site Settings > Registration."
87
83
  }),
88
84
  ]
89
85
  }),
@@ -45,7 +45,6 @@ module.exports = `
45
45
  type MarketingPageHeroRegistrationButton {
46
46
  text: String
47
47
  display: Boolean
48
- externalRegistrationLink: String
49
48
  }
50
49
  type MarketingPageHeroLoginButton {
51
50
  text: String
@@ -6,6 +6,7 @@ import Mdx from "../../components/Mdx";
6
6
 
7
7
  // function to transform content by replacing relative image URLs with absolute ones
8
8
  const transformContent = (mdx, getAsset) => {
9
+ if (!mdx) return "";
9
10
  // regex to identify Markdown image tags ![alt](url)
10
11
  const imageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g;
11
12
 
@@ -21,9 +22,19 @@ const transformContent = (mdx, getAsset) => {
21
22
  });
22
23
  };
23
24
 
25
+ // Override shortcodes that require Redux/Gatsby context with placeholders for CMS preview
26
+ const previewShortcodes = {
27
+ ...shortcodes,
28
+ RegistrationForm: () => (
29
+ <div style={{ border: '2px dashed #ccc', padding: '2rem', textAlign: 'center', margin: '1rem 0' }}>
30
+ <p style={{ fontSize: '1.2rem', color: '#666' }}>Registration Form Widget (preview not available)</p>
31
+ </div>
32
+ )
33
+ };
34
+
24
35
  // function to render transformed content with Mdx
25
36
  const renderContent = (mdx, getAsset) => (
26
- <Mdx shortcodes={shortcodes} content={transformContent(mdx, getAsset)}/>
37
+ <Mdx shortcodes={previewShortcodes} content={transformContent(mdx, getAsset)}/>
27
38
  );
28
39
 
29
40
  const ContentPagePreview = ({ entry, getAsset }) => {
@@ -12,7 +12,8 @@ import { getThirdPartyProviders } from "../actions/base-actions";
12
12
  // these two libraries are client-side only
13
13
  import LoginComponent from "summit-registration-lite/dist/components/login";
14
14
  import PasswordlessLoginComponent from "summit-registration-lite/dist/components/login-passwordless";
15
- import "summit-registration-lite/dist/index.css";
15
+ import "summit-registration-lite/dist/components/login.css";
16
+ import "summit-registration-lite/dist/components/login-passwordless.css";
16
17
  import IconButton from "./IconButton";
17
18
  import Link from "./Link";
18
19
 
@@ -1,20 +1,32 @@
1
1
  import * as React from "react";
2
2
  import { getSrc } from "gatsby-plugin-image";
3
3
  import AuthComponent from "../AuthComponent";
4
- import RegistrationLiteComponent from "../RegistrationLiteComponent";
4
+ import RegistrationModalComponent from "../RegistrationModalComponent";
5
+ import RegisterButton from "../RegisterButton";
6
+ import { REGISTRATION_MODE } from "@utils/registrationConstants";
7
+ import useSiteSettings from "@utils/useSiteSettings";
5
8
 
6
9
  import styles from "./styles.module.scss";
7
10
 
8
- const ButtonGroup = ({ location, registerButton, loginButton }) => (
9
- <>
10
- {registerButton?.display && (
11
- <span className={styles.link}>
12
- <RegistrationLiteComponent location={location} />
13
- </span>
14
- )}
15
- {loginButton?.display && <AuthComponent location={location} />}
16
- </>
17
- );
11
+ const ButtonGroup = ({ location, registerButton, loginButton }) => {
12
+ const siteSettings = useSiteSettings();
13
+ const mode = siteSettings?.registration?.registrationMode || REGISTRATION_MODE.modal;
14
+ return (
15
+ <>
16
+ {registerButton?.display && (mode === REGISTRATION_MODE.standalone || mode === REGISTRATION_MODE.link) && (
17
+ <span className={styles.link}>
18
+ <RegisterButton />
19
+ </span>
20
+ )}
21
+ {registerButton?.display && mode === REGISTRATION_MODE.modal && (
22
+ <span className={styles.link}>
23
+ <RegistrationModalComponent location={location} />
24
+ </span>
25
+ )}
26
+ {loginButton?.display && <AuthComponent location={location} />}
27
+ </>
28
+ );
29
+ };
18
30
 
19
31
  const MainColumn = ({ location, title, subTitle, date, time, buttons, backgroundSrc, fullWidth }) => {
20
32
  const backgroundImageStyle = backgroundSrc
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import { navigate } from "gatsby";
4
+ import { connect } from "react-redux";
5
+
6
+ import IconButton from "./IconButton";
7
+ import iconButtonStyles from "./IconButton/styles.module.scss";
8
+ import { REGISTRATION_MODE } from "@utils/registrationConstants";
9
+ import useSiteSettings from "@utils/useSiteSettings";
10
+
11
+ const RegisterButton = ({
12
+ marketingPageSettings,
13
+ children,
14
+ }) => {
15
+ const siteSettings = useSiteSettings();
16
+ const registration = siteSettings?.registration;
17
+ const mode = registration?.registrationMode || REGISTRATION_MODE.modal;
18
+
19
+ const handleClick = () => {
20
+ if (mode === REGISTRATION_MODE.link && registration?.registrationLink) {
21
+ const url = registration.registrationLink;
22
+ const isInternal = /^\/(?!\/)/.test(url);
23
+ if (isInternal) {
24
+ navigate(url);
25
+ } else {
26
+ window.location = url;
27
+ }
28
+ return;
29
+ }
30
+ navigate("/register");
31
+ }
32
+
33
+ const { registerButton } = marketingPageSettings.hero.buttons;
34
+
35
+ if (children) {
36
+ return React.cloneElement(children, { onClick: handleClick });
37
+ }
38
+
39
+ if (!registerButton.display) return null;
40
+
41
+ return (
42
+ <IconButton
43
+ className={iconButtonStyles.register}
44
+ iconClass="fa fa-2x fa-edit"
45
+ buttonText={registerButton.text}
46
+ onClick={handleClick}
47
+ />
48
+ );
49
+ };
50
+
51
+ RegisterButton.propTypes = {
52
+ children: PropTypes.node,
53
+ };
54
+
55
+ const mapStateToProps = ({ settingState }) => ({
56
+ marketingPageSettings: settingState.marketingPageSettings
57
+ });
58
+
59
+ export default connect(mapStateToProps)(RegisterButton);
@@ -0,0 +1,82 @@
1
+ import React from "react";
2
+ import { connect } from "react-redux";
3
+ import { navigate } from "gatsby";
4
+ import * as Sentry from "@sentry/react";
5
+ import NoSsr from "@mui/material/NoSsr";
6
+
7
+ import { SentryFallbackFunction } from "./SentryErrorComponent";
8
+ import RegistrationForm from "summit-registration-lite/dist/components/registration-form";
9
+ import "summit-registration-lite/dist/components/registration-form.css";
10
+
11
+ import { setPasswordlessLogin, setUserOrder, checkOrderData, getUserProfile, checkRequireExtraQuestionsByAttendee } from "../actions/user-actions";
12
+ import { getThirdPartyProviders } from "../actions/base-actions";
13
+ import { getExtraQuestions } from "../actions/summit-actions";
14
+
15
+ import useRegistrationWidgetProps from "@utils/useRegistrationWidgetProps";
16
+
17
+ const RegistrationFormShortcode = ({
18
+ summit,
19
+ userProfile,
20
+ idpProfile,
21
+ colorSettings,
22
+ attendee,
23
+ availableThirdPartyProviders,
24
+ allowsNativeAuth,
25
+ allowsOtpAuth,
26
+ loadingProfile,
27
+ loadingIDP,
28
+ setPasswordlessLogin,
29
+ setUserOrder,
30
+ checkOrderData,
31
+ getUserProfile,
32
+ getThirdPartyProviders,
33
+ getExtraQuestions,
34
+ checkRequireExtraQuestionsByAttendee
35
+ }) => {
36
+ const backUrl = typeof window !== 'undefined' ? window.location.pathname : '/';
37
+
38
+ const widgetProps = useRegistrationWidgetProps({
39
+ summit, userProfile, idpProfile, attendee, colorSettings,
40
+ loadingProfile, loadingIDP, availableThirdPartyProviders,
41
+ allowsNativeAuth, allowsOtpAuth,
42
+ setPasswordlessLogin, setUserOrder, checkOrderData,
43
+ getThirdPartyProviders, getExtraQuestions, checkRequireExtraQuestionsByAttendee,
44
+ backUrl,
45
+ closeWidget: () => navigate("/"),
46
+ });
47
+
48
+ if (!summit) return null;
49
+
50
+ return (
51
+ <NoSsr>
52
+ <Sentry.ErrorBoundary fallback={SentryFallbackFunction({componentName: "Registration Form"})}>
53
+ <div className="summit-registration-lite">
54
+ <RegistrationForm {...widgetProps} />
55
+ </div>
56
+ </Sentry.ErrorBoundary>
57
+ </NoSsr>
58
+ );
59
+ };
60
+
61
+ const mapStateToProps = ({ userState, summitState, settingState }) => ({
62
+ loadingProfile: userState.loading,
63
+ loadingIDP: userState.loadingIDP,
64
+ userProfile: userState.userProfile,
65
+ idpProfile: userState.idpProfile,
66
+ attendee: userState.attendee,
67
+ availableThirdPartyProviders: summitState.third_party_providers,
68
+ allowsNativeAuth: summitState.allows_native_auth,
69
+ allowsOtpAuth: summitState.allows_otp_auth,
70
+ summit: summitState.summit,
71
+ colorSettings: settingState.colorSettings,
72
+ });
73
+
74
+ export default connect(mapStateToProps, {
75
+ setPasswordlessLogin,
76
+ setUserOrder,
77
+ checkOrderData,
78
+ getUserProfile,
79
+ getThirdPartyProviders,
80
+ getExtraQuestions,
81
+ checkRequireExtraQuestionsByAttendee
82
+ })(RegistrationFormShortcode);