@openeventkit/event-site 2.1.18 → 2.1.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 (86) hide show
  1. package/.github/workflows/jest.yml +1 -1
  2. package/babel.config.json +9 -9
  3. package/gatsby-node.js +67 -125
  4. package/jest.setup.js +2 -0
  5. package/netlify.toml +1 -1
  6. package/package.json +25 -16
  7. package/src/__mocks__/@mdx-js/mdx.js +32 -0
  8. package/src/__mocks__/@mdx-js/react.js +15 -0
  9. package/src/__mocks__/rehype-external-links.js +3 -0
  10. package/src/__mocks__/remark-gfm.js +3 -0
  11. package/src/actions/fetch-entities-actions.js +45 -87
  12. package/src/actions/update-data-actions.js +2 -2
  13. package/src/actions/user-actions.js +578 -430
  14. package/src/cms/config/collections/configurationsCollection/siteSettings/index.js +2 -0
  15. package/src/cms/config/collections/configurationsCollection/siteSettings/typeDefs.js +10 -0
  16. package/src/cms/preview-templates/ContentPagePreview.js +27 -29
  17. package/src/components/AvatarEditorModal/index.js +10 -0
  18. package/src/components/CertificatePDF.js +313 -0
  19. package/src/components/CertificateSection.js +139 -0
  20. package/src/components/FullSchedule.js +83 -66
  21. package/src/components/Mdx.js +39 -0
  22. package/src/components/__tests__/Mdx.test.jsx +70 -0
  23. package/src/content/site-settings/index.json +1 -1
  24. package/src/content/sponsors.json +1 -1
  25. package/src/i18n/locales/en.json +9 -1
  26. package/src/pages/a/[...].js +3 -0
  27. package/src/reducers/user-reducer.js +89 -27
  28. package/src/routes/authorization-callback-route.js +20 -2
  29. package/src/styles/rsvp-page.module.scss +63 -0
  30. package/src/templates/full-profile-page.js +61 -2
  31. package/src/templates/marketing-page-template/MainColumn.js +40 -42
  32. package/src/templates/rsvp-page.js +144 -0
  33. package/src/utils/alerts.js +1 -1
  34. package/src/utils/build-json/BaseAPIRequest.js +25 -0
  35. package/src/utils/build-json/EventsAPIRequest.js +171 -0
  36. package/src/utils/build-json/SpeakersAPIRequest.js +62 -0
  37. package/src/utils/build-json/SummitAPIRequest.js +115 -0
  38. package/src/utils/build-json/constants.js +5 -0
  39. package/src/utils/certificateSettings.js +45 -0
  40. package/src/utils/customErrorHandler.js +40 -1
  41. package/src/utils/rsvpConstants.js +7 -0
  42. package/src/utils/useMarketingSettings.js +48 -1
  43. package/src/utils/useSiteSettings.js +11 -0
  44. package/src/workers/feeds.worker.js +85 -90
  45. package/src/workers/sync_strategies/activity_synch_strategy.js +147 -102
  46. package/src/workers/sync_strategies/speaker_synch_strategy.js +3 -3
  47. package/src/workers/sync_strategies/track_synch_strategy.js +149 -48
  48. package/src/workers/synch.worker.js +123 -88
  49. package/static/fonts/fonts.css +120 -20
  50. package/static/fonts/nunito-sans/nunito-sans-v18-latin-200.woff2 +0 -0
  51. package/static/fonts/nunito-sans/nunito-sans-v18-latin-200italic.ttf +0 -0
  52. package/static/fonts/nunito-sans/nunito-sans-v18-latin-200italic.woff2 +0 -0
  53. package/static/fonts/nunito-sans/nunito-sans-v18-latin-300.woff2 +0 -0
  54. package/static/fonts/nunito-sans/nunito-sans-v18-latin-300italic.ttf +0 -0
  55. package/static/fonts/nunito-sans/nunito-sans-v18-latin-300italic.woff2 +0 -0
  56. package/static/fonts/nunito-sans/nunito-sans-v18-latin-400.ttf +0 -0
  57. package/static/fonts/nunito-sans/nunito-sans-v18-latin-400.woff2 +0 -0
  58. package/static/fonts/nunito-sans/nunito-sans-v18-latin-400italic.ttf +0 -0
  59. package/static/fonts/nunito-sans/nunito-sans-v18-latin-400italic.woff2 +0 -0
  60. package/static/fonts/nunito-sans/nunito-sans-v18-latin-500.ttf +0 -0
  61. package/static/fonts/nunito-sans/nunito-sans-v18-latin-500.woff2 +0 -0
  62. package/static/fonts/nunito-sans/nunito-sans-v18-latin-500italic.ttf +0 -0
  63. package/static/fonts/nunito-sans/nunito-sans-v18-latin-500italic.woff2 +0 -0
  64. package/static/fonts/nunito-sans/nunito-sans-v18-latin-600.woff2 +0 -0
  65. package/static/fonts/nunito-sans/nunito-sans-v18-latin-600italic.woff2 +0 -0
  66. package/static/fonts/nunito-sans/nunito-sans-v18-latin-700.ttf +0 -0
  67. package/static/fonts/nunito-sans/nunito-sans-v18-latin-700.woff2 +0 -0
  68. package/static/fonts/nunito-sans/nunito-sans-v18-latin-700italic.woff2 +0 -0
  69. package/static/fonts/nunito-sans/nunito-sans-v18-latin-800.ttf +0 -0
  70. package/static/fonts/nunito-sans/nunito-sans-v18-latin-800.woff2 +0 -0
  71. package/static/fonts/nunito-sans/nunito-sans-v18-latin-800italic.woff2 +0 -0
  72. package/static/fonts/nunito-sans/nunito-sans-v18-latin-900.ttf +0 -0
  73. package/static/fonts/nunito-sans/nunito-sans-v18-latin-900.woff2 +0 -0
  74. package/static/fonts/nunito-sans/nunito-sans-v18-latin-900italic.woff2 +0 -0
  75. package/static/fonts/nunito-sans/nunito-sans-v12-latin-300.woff +0 -0
  76. package/static/fonts/nunito-sans/nunito-sans-v12-latin-300.woff2 +0 -0
  77. package/static/fonts/nunito-sans/nunito-sans-v12-latin-300italic.woff +0 -0
  78. package/static/fonts/nunito-sans/nunito-sans-v12-latin-300italic.woff2 +0 -0
  79. package/static/fonts/nunito-sans/nunito-sans-v12-latin-600.woff +0 -0
  80. package/static/fonts/nunito-sans/nunito-sans-v12-latin-600.woff2 +0 -0
  81. package/static/fonts/nunito-sans/nunito-sans-v12-latin-600italic.woff +0 -0
  82. package/static/fonts/nunito-sans/nunito-sans-v12-latin-600italic.woff2 +0 -0
  83. package/static/fonts/nunito-sans/nunito-sans-v12-latin-700.woff +0 -0
  84. package/static/fonts/nunito-sans/nunito-sans-v12-latin-700.woff2 +0 -0
  85. package/static/fonts/nunito-sans/nunito-sans-v12-latin-700italic.woff +0 -0
  86. package/static/fonts/nunito-sans/nunito-sans-v12-latin-700italic.woff2 +0 -0
@@ -1,81 +1,98 @@
1
1
  import React from "react";
2
2
  import * as Sentry from "@sentry/react";
3
- import { connect } from "react-redux";
4
- import { needsLogin } from "../utils/alerts";
5
- import { addToSchedule, removeFromSchedule } from "../actions/user-actions";
6
- import { callAction, getShareLink } from "../actions/schedule-actions";
3
+ import {connect} from "react-redux";
4
+ import {needsLogin} from "../utils/alerts";
5
+ import {
6
+ addToSchedule,
7
+ cancelRSVP,
8
+ removeFromSchedule,
9
+ RSVP_CANCELLED,
10
+ RSVP_CONFIRMED,
11
+ rsvpToEvent
12
+ } from "../actions/user-actions";
13
+ import {callAction, getShareLink} from "../actions/schedule-actions";
7
14
 
8
15
  // these two libraries are client-side only
9
16
  import Schedule from "full-schedule-widget/dist";
10
17
  import "full-schedule-widget/dist/index.css";
11
-
12
- import useMarketingSettings, { MARKETING_SETTINGS_KEYS } from "@utils/useMarketingSettings";
13
- import { SentryFallbackFunction } from "./SentryErrorComponent";
18
+ import useMarketingSettings, {MARKETING_SETTINGS_KEYS} from "@utils/useMarketingSettings";
19
+ import {SentryFallbackFunction} from "./SentryErrorComponent";
14
20
 
15
21
  const FullSchedule = ({
16
- summit,
17
- className,
18
- userProfile,
19
- colorSettings,
20
- addToSchedule,
21
- removeFromSchedule,
22
- callAction,
23
- filters,
24
- view,
25
- allowClick = true,
26
- schedKey,
27
- ...rest
28
- }) => {
29
- const { getSettingByKey } = useMarketingSettings();
30
- const defaultImage = getSettingByKey(MARKETING_SETTINGS_KEYS.scheduleDefaultImage);
31
- const summitLogoPrint = getSettingByKey(MARKETING_SETTINGS_KEYS.fullScheduleSummitLogoPrint);
32
- const componentProps = {
33
- title: "Schedule",
34
- summit,
35
- marketingSettings: colorSettings,
36
- userProfile,
37
- withThumbs: false,
38
- defaultImage: defaultImage,
39
- summitLogoPrint: summitLogoPrint ? summitLogoPrint : null,
40
- showSendEmail: false,
41
- onStartChat: null,
42
- shareLink: getShareLink(filters, view),
43
- filters,
44
- view,
45
- onEventClick: allowClick ? () => { } : null,
46
- needsLogin: needsLogin,
47
- triggerAction: (action, payload) => {
48
- switch (action) {
49
- case "ADDED_TO_SCHEDULE": {
50
- return addToSchedule(payload.event);
51
- }
52
- case "REMOVED_FROM_SCHEDULE": {
53
- return removeFromSchedule(payload.event);
54
- }
55
- default:
56
- return callAction(schedKey, action, payload);
57
- }
58
- },
59
- ...rest,
60
- };
22
+ summit,
23
+ className,
24
+ userProfile,
25
+ colorSettings,
26
+ addToSchedule,
27
+ removeFromSchedule,
28
+ rsvpToEvent,
29
+ cancelRSVP,
30
+ callAction,
31
+ filters,
32
+ view,
33
+ allowClick = true,
34
+ schedKey,
35
+ ...rest
36
+ }) => {
37
+ const {getSettingByKey} = useMarketingSettings();
38
+ const defaultImage = getSettingByKey(MARKETING_SETTINGS_KEYS.scheduleDefaultImage);
39
+ const summitLogoPrint = getSettingByKey(MARKETING_SETTINGS_KEYS.fullScheduleSummitLogoPrint);
40
+ const componentProps = {
41
+ title: "Schedule",
42
+ summit,
43
+ marketingSettings: colorSettings,
44
+ userProfile,
45
+ withThumbs: false,
46
+ defaultImage: defaultImage,
47
+ summitLogoPrint: summitLogoPrint ? summitLogoPrint : null,
48
+ showSendEmail: false,
49
+ onStartChat: null,
50
+ shareLink: getShareLink(filters, view),
51
+ filters,
52
+ view,
53
+ onEventClick: allowClick ? () => {
54
+ } : null,
55
+ needsLogin: needsLogin,
56
+ triggerAction: (action, payload) => {
57
+ switch (action) {
58
+ case "ADDED_TO_SCHEDULE": {
59
+ return addToSchedule(payload.event);
60
+ }
61
+ case "REMOVED_FROM_SCHEDULE": {
62
+ return removeFromSchedule(payload.event);
63
+ }
64
+ case RSVP_CONFIRMED: {
65
+ return rsvpToEvent(payload.event);
66
+ }
67
+ case RSVP_CANCELLED: {
68
+ return cancelRSVP(payload.event);
69
+ }
70
+ default:
71
+ return callAction(schedKey, action, payload);
72
+ }
73
+ },
74
+ ...rest,
75
+ };
61
76
 
62
- return (
63
- <div className={className || "schedule-container"}>
64
- <Sentry.ErrorBoundary fallback={SentryFallbackFunction({componentName: "Full Schedule"})}>
65
- <Schedule {...componentProps} />
66
- </Sentry.ErrorBoundary>
67
- </div>
68
- );
77
+ return (
78
+ <div className={className || "schedule-container"}>
79
+ <Sentry.ErrorBoundary fallback={SentryFallbackFunction({componentName: "Full Schedule"})}>
80
+ <Schedule {...componentProps} />
81
+ </Sentry.ErrorBoundary>
82
+ </div>
83
+ );
69
84
  };
70
85
 
71
- const mapStateToProps = ({ userState, settingState }) => ({
72
- userProfile: userState.userProfile,
73
- colorSettings: settingState.colorSettings,
74
- allowClick: settingState?.widgets?.schedule?.allowClick
86
+ const mapStateToProps = ({userState, settingState}) => ({
87
+ userProfile: userState.userProfile,
88
+ colorSettings: settingState.colorSettings,
89
+ allowClick: settingState?.widgets?.schedule?.allowClick
75
90
  });
76
91
 
77
92
  export default connect(mapStateToProps, {
78
- addToSchedule,
79
- removeFromSchedule,
80
- callAction,
93
+ addToSchedule,
94
+ removeFromSchedule,
95
+ rsvpToEvent,
96
+ cancelRSVP,
97
+ callAction,
81
98
  })(FullSchedule);
@@ -0,0 +1,39 @@
1
+ // src/components/Mdx.jsx
2
+ import React, { useMemo } from "react";
3
+ import { evaluateSync } from "@mdx-js/mdx";
4
+ import * as jsxRuntime from "react/jsx-runtime";
5
+ import remarkGfm from "remark-gfm";
6
+ import rehypeExternalLinks from "rehype-external-links";
7
+ import { MDXProvider, useMDXComponents } from "@mdx-js/react";
8
+
9
+ const Mdx = ({ content, shortcodes }) => {
10
+ const Comp = useMemo(() => {
11
+ if (!content) return null;
12
+ try {
13
+ const mod = evaluateSync(content, {
14
+ // MDX runtime needs the React jsx runtime symbols:
15
+ ...jsxRuntime,
16
+ remarkPlugins: [remarkGfm],
17
+ rehypePlugins: [[rehypeExternalLinks, { target: "_blank", rel: ["nofollow","noopener","noreferrer"] }]],
18
+ // Wire MDX context so MDXProvider / components prop actually work:
19
+ useMDXComponents
20
+ // development: process.env.NODE_ENV !== "production",
21
+ });
22
+ return mod.default; // <-- this is the React component
23
+ } catch (err) {
24
+ console.error("MDX evaluate error:", err);
25
+ return null;
26
+ }
27
+ }, [content]);
28
+
29
+ if (!Comp) return null;
30
+
31
+ return (
32
+ <MDXProvider components={shortcodes}>
33
+ <Comp />
34
+ </MDXProvider>
35
+ );
36
+
37
+ };
38
+
39
+ export default Mdx;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+ import React from "react";
5
+ import { render, screen } from "@testing-library/react";
6
+ import Mdx from "../Mdx";
7
+
8
+ // Shortcode components for MDXProvider wiring check
9
+ const Button = ({ children }) => <button data-testid="shortcode-btn">{children}</button>;
10
+ const Link = ({ href, children }) => <a data-testid="shortcode-link" href={href}>{children}</a>;
11
+
12
+ const SHORTCODES = { Button, a: Link };
13
+
14
+ describe("<Mdx /> (minimal MDX mocks)", () => {
15
+ let consoleErrorSpy;
16
+
17
+ beforeEach(() => {
18
+ consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {});
19
+ });
20
+
21
+ afterEach(() => {
22
+ consoleErrorSpy.mockRestore();
23
+ });
24
+
25
+ test("renders nothing when content is empty/null", () => {
26
+ const { container, rerender } = render(<Mdx content={null} shortcodes={SHORTCODES} />);
27
+ expect(container).toBeEmptyDOMElement();
28
+
29
+ rerender(<Mdx content={""} shortcodes={SHORTCODES} />);
30
+ expect(container).toBeEmptyDOMElement();
31
+ });
32
+
33
+ test("renders compiled component (shows raw content via mock)", () => {
34
+ const mdx = "# Hello\n\nThis is **bold** text.";
35
+ render(<Mdx content={mdx} shortcodes={{}} />);
36
+
37
+ // From our mock, the compiled component renders a data-testid with the raw source
38
+ const el = screen.getByTestId("mdx-source");
39
+ expect(el).toHaveTextContent(/# Hello/);
40
+ expect(el).toHaveTextContent(/This is \*\*bold\*\* text\./);
41
+ });
42
+
43
+ test("passes shortcodes via MDXProvider (keys visible to compiled component)", () => {
44
+ render(<Mdx content={"anything"} shortcodes={SHORTCODES} />);
45
+
46
+ // Our mock compiled component exposes the component keys in data-components
47
+ const marker = screen.getByTestId("mdx-components");
48
+ const keys = (marker.getAttribute("data-components") || "").split(",").filter(Boolean);
49
+
50
+ expect(keys).toEqual(expect.arrayContaining(["Button", "a"]));
51
+ });
52
+
53
+ test("updates when content changes", () => {
54
+ const first = "First content";
55
+ const second = "Second content";
56
+ const { rerender } = render(<Mdx content={first} shortcodes={{}} />);
57
+
58
+ expect(screen.getByTestId("mdx-source")).toHaveTextContent(first);
59
+
60
+ rerender(<Mdx content={second} shortcodes={{}} />);
61
+ expect(screen.getByTestId("mdx-source")).toHaveTextContent(second);
62
+ });
63
+
64
+ test("invalid MDX triggers evaluateSync error and renders nothing", () => {
65
+ const { container } = render(<Mdx content={"BAD_MDX"} shortcodes={{}} />);
66
+ // Our component catches evaluateSync error; ensure it logged at least once
67
+ expect(consoleErrorSpy).toHaveBeenCalled();
68
+ expect(container).toBeEmptyDOMElement();
69
+ });
70
+ });
@@ -1 +1 @@
1
- {"favicon":{"asset":"icon.png"},"widgets":{"chat":{"enabled":true,"showQA":false,"showHelp":false,"defaultScope":"page"},"schedule":{"allowClick":true}},"identityProviderButtons":[{"buttonColor":"#082238","providerLabel":"Continue with FNid","providerLogo":"logo_fn.svg","providerLogoSize":27},{"buttonColor":"#0A66C2","providerLabel":"Sign in with LinkedIn","providerParam":"linkedin","providerLogo":"logo_linkedin.svg","providerLogoSize":18},{"buttonColor":"#000000","providerLabel":"Sign in with Apple","providerParam":"apple","providerLogoSize":17,"providerLogo":"logo_apple.svg"},{"buttonColor":"#1877F2","providerLabel":"Login with Facebook","providerParam":"facebook","providerLogo":"logo_facebook.svg","providerLogoSize":20}],"maintenanceMode":{"enabled":false,"title":"Site under maintenance","subtitle":"Please reload page shortly"},"staticJsonFilesBuildTime":[{"file":"src/data/summit.json","build_time":1755202866239},{"file":"src/data/events.json","build_time":1755202885829},{"file":"src/data/events.idx.json","build_time":1755202885863},{"file":"src/data/speakers.json","build_time":1755202892384},{"file":"src/data/speakers.idx.json","build_time":1755202892387},{"file":"src/content/sponsors.json","build_time":1755202892817},{"file":"src/data/voteable-presentations.json","build_time":1755202893268}],"lastBuild":1755202893268}
1
+ {"favicon":{"asset":"icon.png"},"widgets":{"chat":{"enabled":true,"showQA":false,"showHelp":false,"defaultScope":"page"},"schedule":{"allowClick":true}},"identityProviderButtons":[{"buttonColor":"#082238","providerLabel":"Continue with FNid","providerLogo":"logo_fn.svg","providerLogoSize":27},{"buttonColor":"#0A66C2","providerLabel":"Sign in with LinkedIn","providerParam":"linkedin","providerLogo":"logo_linkedin.svg","providerLogoSize":18},{"buttonColor":"#000000","providerLabel":"Sign in with Apple","providerParam":"apple","providerLogoSize":17,"providerLogo":"logo_apple.svg"},{"buttonColor":"#1877F2","providerLabel":"Login with Facebook","providerParam":"facebook","providerLogo":"logo_facebook.svg","providerLogoSize":20}],"maintenanceMode":{"enabled":false,"title":"Site under maintenance","subtitle":"Please reload page shortly"},"staticJsonFilesBuildTime":[{"file":"src/data/summit.json","build_time":1757078904637},{"file":"src/data/events.json","build_time":1757078906503},{"file":"src/data/events.idx.json","build_time":1757078906506},{"file":"src/data/speakers.json","build_time":1757078907177},{"file":"src/data/speakers.idx.json","build_time":1757078907177},{"file":"src/content/sponsors.json","build_time":1757078912121},{"file":"src/data/voteable-presentations.json","build_time":1757078912473}],"lastBuild":1757078912473}
@@ -1 +1 @@
1
- []
1
+ [{"id":533,"created":1754503947,"last_edited":1755716348,"order":1,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":"","intro":"","external_link":"","video_link":"","chat_link":"","featured_event_id":0,"header_image_alt_text":"","side_image_alt_text":"","header_image_mobile_alt_text":"","carousel_advertise_image_alt_text":"","show_logo_in_event_page":true,"lead_report_setting_id":6,"company":{"id":1,"created":1579886208,"last_edited":1579886208,"name":"Intel Corporation","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/1/logos/OCP21GLO-SessionBrandingBar-Sponsor-Intel2.png","big_logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/1/logos/OCP21GLO-SessionBrandingBar-Sponsor-Intel3.png","color":"#f0f0ee"},"extra_questions":[763],"members":[],"sponsorship":{"id":2072,"widget_title":"","lobby_template":null,"expo_hall_template":null,"sponsor_page_template":null,"event_page_template":null,"sponsor_page_use_disqus_widget":false,"sponsor_page_use_live_event_widget":false,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":3,"should_display_on_expo_hall_page":false,"should_display_on_lobby_page":false,"type":{"id":9,"created":1605551482,"last_edited":1605551482,"name":"Silver","label":"Silver","order":9,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":543,"created":1754667572,"last_edited":1754667572,"order":2,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":3,"created":1580138376,"last_edited":1580138376,"name":"Tipit , LLC","url":null,"url_segment":null,"city":null,"state":null,"country":null,"description":null,"industry":null,"contributions":null,"member_level":"None","overview":null,"products":null,"commitment":null,"commitment_author":null,"logo":null,"big_logo":null,"color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":564,"created":1755645526,"last_edited":1755645526,"order":3,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":4,"created":1582745992,"last_edited":1582745992,"name":"FNTECH","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/4/logos/FNTECH-BLK-logo-rgb-1-color-white-720px2.png","big_logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/4/logos/FNTECH-BLK-logo-rgb-1-color-white-720px3.png","color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":565,"created":1755716372,"last_edited":1755716401,"order":4,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":5,"created":1594672447,"last_edited":1594672447,"name":"Meta","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/5/logos/OCP21GLO-SessionBrandingBar-Sponsor-Meta1.png","big_logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/5/logos/OCP21GLO-SessionBrandingBar-Sponsor-Meta.png","color":"#f0f0ee"},"extra_questions":[],"members":[36416],"sponsorship":{"id":2073,"widget_title":"","lobby_template":null,"expo_hall_template":null,"sponsor_page_template":null,"event_page_template":null,"sponsor_page_use_disqus_widget":false,"sponsor_page_use_live_event_widget":false,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":1,"should_display_on_expo_hall_page":false,"should_display_on_lobby_page":false,"type":{"id":2,"created":1579287407,"last_edited":1579287407,"name":"Diamond","label":"20 x 20 booth","order":2,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":566,"created":1755717072,"last_edited":1755717072,"order":5,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":11,"created":1603222606,"last_edited":1603222606,"name":"FakeCo","url":null,"url_segment":null,"city":null,"state":null,"country":null,"description":null,"industry":null,"contributions":null,"member_level":null,"overview":null,"products":null,"commitment":null,"commitment_author":null,"logo":null,"big_logo":null,"color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":567,"created":1755717143,"last_edited":1755717143,"order":6,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":12,"created":1603223078,"last_edited":1603223078,"name":"Phase Two","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/12/logos/IF2020-Phasetwo-Presentedby-Logo.png","big_logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/12/logos/IF2020-Phasetwo-Presentedby-Logo1.png","color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":568,"created":1755717768,"last_edited":1755717768,"order":7,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":6,"created":1600118396,"last_edited":1600118396,"name":"FNtest","url":null,"url_segment":null,"city":null,"state":null,"country":null,"description":null,"industry":null,"contributions":null,"member_level":"None","overview":null,"products":null,"commitment":null,"commitment_author":null,"logo":null,"big_logo":null,"color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2076,"widget_title":"test2","lobby_template":"carousel","expo_hall_template":null,"sponsor_page_template":null,"event_page_template":null,"sponsor_page_use_disqus_widget":false,"sponsor_page_use_live_event_widget":false,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":7,"should_display_on_expo_hall_page":false,"should_display_on_lobby_page":false,"type":{"id":8,"created":1603223268,"last_edited":1603223268,"name":"Featured","label":"Featured","order":8,"size":"Large"}},"ads":[],"materials":[],"social_networks":[]},{"id":569,"created":1755717799,"last_edited":1755717799,"order":8,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":13,"created":1603223094,"last_edited":1603223094,"name":"Essentia Water","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/13/logos/IF2020-Essentia-Presentedby-Logo-V2.png","big_logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/13/logos/IF2020-Essentia-Presentedby-Logo-V21.png","color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":570,"created":1755717951,"last_edited":1755717951,"order":9,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":8,"created":1603222234,"last_edited":1603222234,"name":"Z by HP","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/8/logos/IF2020-ZbyHP-Presentedby-Logo.png","big_logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/8/logos/IF2020-ZbyHP-Presentedby-Logo1.png","color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":571,"created":1755717973,"last_edited":1755717973,"order":10,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":24,"created":1605551226,"last_edited":1605551226,"name":"Bronze - Lower Tier","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":null,"big_logo":null,"color":"#DADADA"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":572,"created":1755717993,"last_edited":1755717993,"order":11,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":47,"created":1629851431,"last_edited":1629851431,"name":"BizLink Technology, Inc.","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/47/logos/OCP21GLO-SessionBrandingBar-Sponsor-Bizlink.png","big_logo":null,"color":"#DADADA"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]},{"id":573,"created":1755718518,"last_edited":1755718518,"order":12,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":79,"created":1630351802,"last_edited":1630351802,"name":"Test and Validation","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":null,"big_logo":null,"color":"#DADADA"},"extra_questions":[],"members":[],"sponsorship":{"id":2083,"widget_title":"test8","lobby_template":"small-images","expo_hall_template":null,"sponsor_page_template":null,"event_page_template":null,"sponsor_page_use_disqus_widget":false,"sponsor_page_use_live_event_widget":false,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":13,"should_display_on_expo_hall_page":false,"should_display_on_lobby_page":false,"type":{"id":19,"created":1630352146,"last_edited":1630352146,"name":"Experience Center","label":"Experience Center","order":19,"size":"Small"}},"ads":[],"materials":[],"social_networks":[]},{"id":574,"created":1755718559,"last_edited":1755718559,"order":13,"summit_id":69,"is_published":true,"side_image":null,"header_image":null,"header_image_mobile":null,"carousel_advertise_image":null,"marquee":null,"intro":null,"external_link":null,"video_link":null,"chat_link":null,"featured_event_id":0,"header_image_alt_text":null,"side_image_alt_text":null,"header_image_mobile_alt_text":null,"carousel_advertise_image_alt_text":null,"show_logo_in_event_page":true,"lead_report_setting_id":0,"company":{"id":10,"created":1603222343,"last_edited":1603222343,"name":"Microsoft","url":"","url_segment":null,"city":"","state":"","country":"","description":"","industry":"","contributions":"","member_level":"None","overview":"","products":"","commitment":"","commitment_author":"","logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/10/logos/OCP21GLO-SessionBrandingBar-Sponsor-Microsoft1.png","big_logo":"https://summit-api-dev-assets.nyc3.digitaloceanspaces.com/companies/10/logos/OCP21GLO-SessionBrandingBar-Sponsor-Microsoft.png","color":"#f0f0ee"},"extra_questions":[],"members":[],"sponsorship":{"id":2071,"widget_title":"test","lobby_template":"small-images","expo_hall_template":"big-images","sponsor_page_template":"big-header","event_page_template":"big-images","sponsor_page_use_disqus_widget":true,"sponsor_page_use_live_event_widget":true,"sponsor_page_use_schedule_widget":false,"sponsor_page_use_banner_widget":false,"badge_image":null,"badge_image_alt_text":"","summit_id":69,"order":2,"should_display_on_expo_hall_page":true,"should_display_on_lobby_page":true,"type":{"id":3,"created":1579890943,"last_edited":1579890943,"name":"Gold","label":"not sure??","order":3,"size":"Medium"}},"ads":[],"materials":[],"social_networks":[]}]
@@ -9,5 +9,13 @@
9
9
  "title": "No Stream Available",
10
10
  "message": "No event data found for this overflow stream."
11
11
  }
12
+ },
13
+ "rsvp_page": {
14
+ "invite_message": "You have been invited to RSVP {{event}}",
15
+ "decline_message": "You have declined your invitation.",
16
+ "confirm_message": "Your attendance to this event is confirmed.",
17
+ "speakers": "Speakers",
18
+ "accept_button": "YES, I will attend.",
19
+ "decline_button": "NO, I will not attend."
12
20
  }
13
- }
21
+ }
@@ -15,6 +15,7 @@ import ShowOpenRoute from "../../routes/ShowOpenRoute";
15
15
  import WithBadgeRoute from "../../routes/WithBadgeRoute";
16
16
  import PosterDetailPage from "../../templates/poster-detail-page";
17
17
  import MyTicketsPage from "../../templates/my-tickets-page";
18
+ import RsvpPage from "../../templates/rsvp-page";
18
19
  import withRealTimeUpdates from "../../utils/real_time_updates/withRealTimeUpdates";
19
20
  import withFeedsWorker from "../../utils/withFeedsWorker";
20
21
  import Seo from "../../components/Seo";
@@ -78,10 +79,12 @@ const App = ({ isLoggedUser, user, summitPhase, allowClick = true, data }) => {
78
79
  allowClick={allowClick}
79
80
  />
80
81
  <InvitationsRejectPage path="/invitations/reject/:invitationToken" location={location} data={data} />
82
+ <RsvpPage path="/rsvp" location={location} />
81
83
  <WithAuthRoute path="/" isLoggedIn={isLoggedUser} location={location}>
82
84
  <MyTicketsPage path="/my-tickets" isLoggedIn={isLoggedUser} user={user} location={location} />
83
85
  <FullProfilePage path="/profile" summitPhase={summitPhase} isLoggedIn={isLoggedUser} user={user} location={location} />
84
86
  <ExtraQuestionsPage path="/extra-questions" isLoggedIn={isLoggedUser} user={user} location={location} />
87
+
85
88
  { mySchedulePageJson && !mySchedulePageJson.needsTicketAuthz && mySchedulePage({location, summitPhase,isLoggedUser, user, allowClick, title:mySchedulePageJson.title, key: mySchedulePageJson.key }) }
86
89
  <WithAuthzRoute path="/" summitPhase={summitPhase} isLoggedIn={isLoggedUser} user={user} location={location}>
87
90
  <PostersPage path="/posters" trackGroupId={0} location={location} />
@@ -1,25 +1,34 @@
1
1
  import { reduceReducers } from '../utils/reducer-utils';
2
2
  import { LOGOUT_USER } from 'openstack-uicore-foundation/lib/security/actions';
3
3
  import {
4
- GET_DISQUS_SSO,
5
- GET_USER_PROFILE,
6
- START_LOADING_PROFILE,
7
- STOP_LOADING_PROFILE,
8
- GET_IDP_PROFILE,
9
- SET_USER_TICKET,
10
- START_LOADING_IDP_PROFILE,
11
- STOP_LOADING_IDP_PROFILE,
12
- ADD_TO_SCHEDULE,
13
- REMOVE_FROM_SCHEDULE,
14
- SCHEDULE_SYNC_LINK_RECEIVED,
15
- SET_USER_ORDER,
16
- CAST_PRESENTATION_VOTE_RESPONSE,
17
- UNCAST_PRESENTATION_VOTE_RESPONSE,
18
- TOGGLE_PRESENTATION_VOTE,
19
- TICKET_OWNER_CHANGED,
20
- RECEIVE_INVITATION,
21
- REQUEST_INVITATION,
22
- REJECT_INVITATION
4
+
5
+ GET_DISQUS_SSO,
6
+ GET_USER_PROFILE,
7
+ START_LOADING_PROFILE,
8
+ STOP_LOADING_PROFILE,
9
+ GET_IDP_PROFILE,
10
+ SET_USER_TICKET,
11
+ START_LOADING_IDP_PROFILE,
12
+ STOP_LOADING_IDP_PROFILE,
13
+ ADD_TO_SCHEDULE,
14
+ REMOVE_FROM_SCHEDULE,
15
+ SCHEDULE_SYNC_LINK_RECEIVED,
16
+ SET_USER_ORDER,
17
+ CAST_PRESENTATION_VOTE_RESPONSE,
18
+ UNCAST_PRESENTATION_VOTE_RESPONSE,
19
+ TOGGLE_PRESENTATION_VOTE,
20
+ TICKET_OWNER_CHANGED,
21
+ RECEIVE_INVITATION,
22
+ REQUEST_INVITATION,
23
+ REJECT_INVITATION,
24
+ RSVP_CONFIRMED,
25
+ RSVP_CANCELLED,
26
+ REQUEST_RSVP_INVITATION,
27
+ RECEIVE_RSVP_INVITATION,
28
+ RSVP_INVITATION_ERROR,
29
+ RSVP_INVITATION_ACCEPTED,
30
+ RSVP_INVITATION_REJECTED
31
+
23
32
  } from '../actions/user-actions';
24
33
  import { RESET_STATE } from '../actions/base-actions-definitions';
25
34
  import { isAuthorizedUser } from '../utils/authorizedGroups';
@@ -34,6 +43,7 @@ const DEFAULT_STATE = {
34
43
  hasTicket: false,
35
44
  attendee: null,
36
45
  invitation: null,
46
+ rsvpInvitation: null,
37
47
  }
38
48
 
39
49
  const userReducer = (state = DEFAULT_STATE, action) => {
@@ -64,7 +74,7 @@ const userReducer = (state = DEFAULT_STATE, action) => {
64
74
  return { ...state, hasTicket: payload }
65
75
  case SET_USER_ORDER: {
66
76
  // we need to verify that the ticket is for current attendee
67
- const currentUserTickets = (payload?.tickets || []).filter(t => t?.owner?.email == state.userProfile?.email);
77
+ const currentUserTickets = (payload?.tickets || []).filter(t => t?.owner?.email == state.userProfile?.email);
68
78
  return {
69
79
  ...state,
70
80
  hasTicket: (state.hasTicket || currentUserTickets.length > 0),
@@ -82,6 +92,16 @@ const userReducer = (state = DEFAULT_STATE, action) => {
82
92
  case REMOVE_FROM_SCHEDULE: {
83
93
  return { ...state, userProfile: { ...state.userProfile, schedule_summit_events: [...state.userProfile.schedule_summit_events.filter(ev => ev.id !== payload.id)] } }
84
94
  }
95
+ case RSVP_CONFIRMED: {
96
+ return { ...state, userProfile: { ...state.userProfile, rsvp: [...state.userProfile.rsvp, {...payload} ] } }
97
+ }
98
+ case RSVP_CANCELLED: {
99
+ return { ...state, userProfile: {
100
+ ...state.userProfile,
101
+ rsvp: [...state?.userProfile?.rsvp?.filter(r => r.event_id !== payload.id)],
102
+ rsvp_invitations:state?.userProfile?.rsvp_invitations?.filter(i => i.event_id !== payload.id),
103
+ } }
104
+ }
85
105
  case GET_DISQUS_SSO:
86
106
  const disqus = payload.response;
87
107
  return { ...state, loading: false, disqusSSO: disqus };
@@ -93,10 +113,10 @@ const userReducer = (state = DEFAULT_STATE, action) => {
93
113
  const isUserTicket = state.userProfile?.summit_tickets.some(t => t.id === ticketUpdated.id);
94
114
  let currentUserTickets = [...state.userProfile?.summit_tickets];
95
115
  // if is an user ticket and is reassigned or unassiged, remove it from current user tickets
96
- if(isUserTicket) {
97
- if(ticketUpdated?.owner_id === 0 || ticketUpdated?.owner?.member_id !== state.userProfile.id) {
98
- currentUserTickets = [...currentUserTickets].filter(t => t.id !== ticketUpdated.id)
99
- }
116
+ if (isUserTicket) {
117
+ if (ticketUpdated?.owner_id === 0 || ticketUpdated?.owner?.member_id !== state.userProfile.id) {
118
+ currentUserTickets = [...currentUserTickets].filter(t => t.id !== ticketUpdated.id)
119
+ }
100
120
  }
101
121
  // if the new ticket belongs to the current user, add it to current user tickets
102
122
  if (ticketUpdated?.owner?.member_id === state.userProfile.id) {
@@ -112,13 +132,55 @@ const userReducer = (state = DEFAULT_STATE, action) => {
112
132
  };
113
133
  }
114
134
  case REQUEST_INVITATION: {
115
- return {...state, invitation: null};
135
+ return { ...state, invitation: null };
116
136
  }
117
137
  case RECEIVE_INVITATION: {
118
- return {...state, invitation: payload.response}
138
+ return { ...state, invitation: payload.response }
119
139
  }
120
140
  case REJECT_INVITATION: {
121
- return {...state, invitation: {...state.invitation, status: 'Rejected'}}
141
+ return { ...state, invitation: { ...state.invitation, status: 'Rejected' } }
142
+ }
143
+ case REQUEST_RSVP_INVITATION: {
144
+ return { ...state, rsvpInvitation: null }
145
+ }
146
+ case RECEIVE_RSVP_INVITATION: {
147
+ return { ...state, rsvpInvitation: payload.response }
148
+ }
149
+ case RSVP_INVITATION_ERROR: {
150
+ const { errorMessage } = payload;
151
+ return { ...state, rsvpInvitation: { errorMessage } }
152
+ }
153
+ case RSVP_INVITATION_ACCEPTED: {
154
+ const invitation = payload.response;
155
+ const userProfile = state.userProfile? {
156
+ ...state?.userProfile,
157
+ rsvp_invitations:[ ...state?.userProfile?.rsvp_invitations,{
158
+ event_id: invitation.event_id,
159
+ status: invitation.status,
160
+ }],
161
+ rsvp: [...state?.userProfile?.rsvp, {...invitation.rsvp}],
162
+ schedule_summit_events: [...state?.userProfile?.schedule_summit_events, {id: invitation.event_id}]
163
+ } : null;
164
+
165
+ return { ...state,
166
+ rsvpInvitation: invitation,
167
+ // update invitations and rsvps
168
+ userProfile: userProfile,
169
+ }
170
+ }
171
+ case RSVP_INVITATION_REJECTED: {
172
+ // update invitations
173
+ const invitation = payload.response;
174
+ const userProfile = state.userProfile ? {...state?.userProfile,
175
+ rsvp_invitations:[ ...state?.userProfile?.rsvp_invitations,{
176
+ event_id: invitation.event_id,
177
+ status: invitation.status,
178
+ }],
179
+ }: null;
180
+ return { ...state,
181
+ rsvpInvitation: invitation,
182
+ userProfile: userProfile,
183
+ }
122
184
  }
123
185
  default:
124
186
  return state;
@@ -17,7 +17,7 @@ import { navigate } from "gatsby";
17
17
  import { Redirect } from "@gatsbyjs/reach-router";
18
18
  import { connect } from "react-redux";
19
19
  import AbstractAuthorizationCallbackRoute from "openstack-uicore-foundation/lib/security/abstract-auth-callback-route";
20
- import { getUserProfile, addToSchedule, removeFromSchedule } from "../actions/user-actions";
20
+ import { getUserProfile, addToSchedule, removeFromSchedule, rsvpToEvent, cancelRSVP } from "../actions/user-actions";
21
21
  import Interstitial from "../components/Interstitial";
22
22
  import { getEnvVariable, IDP_BASE_URL, OAUTH2_CLIENT_ID } from "@utils/envVariables";
23
23
  import { getPendingAction } from "@utils/schedule";
@@ -35,9 +35,25 @@ class AuthorizationCallbackRoute extends AbstractAuthorizationCallbackRoute {
35
35
  _callback(backUrl) {
36
36
  this.props.getUserProfile().then(() => {
37
37
  const pendingAction = getPendingAction();
38
+
38
39
  if (pendingAction) {
40
+ console.log(`AuthorizationCallbackRoute::_callback pendingAction ${pendingAction}`);
39
41
  const { action, event } = pendingAction;
40
- action === "ADD_EVENT" ? this.props.addToSchedule(event) : this.props.removeFromSchedule(event);
42
+ switch (action.type) {
43
+ case "ADD_EVENT":
44
+ this.props.addToSchedule(event);
45
+ break;
46
+ case "REMOVE_EVENT":
47
+ this.props.removeFromSchedule(event);
48
+ break;
49
+ case "ADD_RSVP":
50
+ this.props.rsvpToEvent(event);
51
+ break;
52
+ case "REMOVE_RSVP":
53
+ this.props.cancelRSVP(event);
54
+ break;
55
+ }
56
+
41
57
  }
42
58
  backUrl = URI.decode(backUrl);
43
59
  // fallback
@@ -88,4 +104,6 @@ export default connect(mapStateToProps, {
88
104
  getUserProfile,
89
105
  addToSchedule,
90
106
  removeFromSchedule,
107
+ rsvpToEvent,
108
+ cancelRSVP,
91
109
  })(AuthorizationCallbackRoute);