@openstack_dev/gatsby-theme-marketing-oif-core 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gatsby-browser.js CHANGED
@@ -1,5 +1,3 @@
1
- import ReduxWrapper from "./src/state/ReduxWrapper";
1
+ import { ReduxWrapperWithCacheProvider } from "./src/state/ReduxWrapper";
2
2
 
3
- export const wrapRootElement = ReduxWrapper;
4
-
5
- export const onClientEntry = () => {};
3
+ export const wrapRootElement = ReduxWrapperWithCacheProvider;
package/gatsby-config.js CHANGED
@@ -221,9 +221,7 @@ module.exports = {
221
221
  description,
222
222
  },
223
223
  plugins,
224
- /*
225
224
  flags: {
226
225
  DEV_SSR: true,
227
226
  },
228
- */
229
227
  };
package/gatsby-ssr.js CHANGED
@@ -1,50 +1,56 @@
1
- import * as ReactDOMServer from "react-dom/server";
1
+ import * as React from "react";
2
2
  import { JSDOM } from "jsdom";
3
3
  import { XMLHttpRequest } from "xmlhttprequest";
4
- import { ThemeProvider } from "@mui/material/styles";
5
- import CssBaseline from "@mui/material/CssBaseline";
6
- import theme from "./src/theme";
7
- import ReduxWrapper from "./src/state/ReduxWrapper";
4
+ import { renderToString } from "react-dom/server";
5
+ import { CacheProvider } from "@emotion/react";
6
+ import createEmotionServer from "@emotion/server/create-instance";
7
+ import { ReduxWrapper } from "./src/state/ReduxWrapper";
8
8
  import { HeadComponents } from "./src/components/head-components";
9
+ import createEmotionCache from "./src/utils/createEmotionCache";
9
10
 
10
-
11
- export const onRenderBody = ({
12
- setHtmlAttributes,
13
- setHeadComponents,
14
- setPreBodyComponents,
15
- setPostBodyComponents,
16
- }, pluginOptions) => {
17
- if (process.env.NODE_ENV === `production`) {
11
+ export const onRenderBody = ({ setHeadComponents }) => {
12
+ if (process.env.NODE_ENV === "production") {
18
13
  setHeadComponents(HeadComponents);
19
14
  }
20
15
  };
21
16
 
22
17
  export const replaceRenderer = ({
23
- bodyComponent,
24
- setHeadComponents,
25
- replaceBodyHTMLString,
26
- }) => {
27
-
28
- const html = ReactDOMServer.renderToString(
29
- <ThemeProvider theme={theme}>
30
- <CssBaseline />
31
- {bodyComponent}
32
- </ThemeProvider>
18
+ bodyComponent,
19
+ setHeadComponents,
20
+ replaceBodyHTMLString,
21
+ }) => {
22
+ const cache = createEmotionCache();
23
+ const { extractCriticalToChunks } = createEmotionServer(cache);
24
+
25
+ const emotionStyles = extractCriticalToChunks(
26
+ renderToString(<CacheProvider value={cache}>{bodyComponent}</CacheProvider>),
33
27
  );
34
28
 
35
- replaceBodyHTMLString(html);
29
+ setHeadComponents(
30
+ emotionStyles.styles.map((style) => (
31
+ <style
32
+ data-emotion={`${style.key} ${style.ids.join(" ")}`}
33
+ key={style.key}
34
+ dangerouslySetInnerHTML={{ __html: style.css }}
35
+ />
36
+ )),
37
+ );
38
+
39
+ // render the result from `extractCritical`
40
+ replaceBodyHTMLString(emotionStyles.html);
36
41
  };
37
42
 
38
43
  export const wrapRootElement = ReduxWrapper;
39
44
 
40
45
  // build enabler polyfills
41
46
  global.dom = new JSDOM("...");
42
- global.window = dom.window;
43
- global.document = dom.window.document;
47
+ global.window = global.dom.window;
48
+ global.document = global.dom.window.document;
44
49
  global.navigator = global.window.navigator;
45
50
  global.window.matchMedia = () => ({
46
51
  matches: false,
47
52
  addListener: () => {},
48
- removeListener: () => {}
53
+ removeListener: () => {},
49
54
  });
55
+
50
56
  global.XMLHttpRequest = XMLHttpRequest;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openstack_dev/gatsby-theme-marketing-oif-core",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Base theme for Marketing Sites",
5
5
  "author": "smarcet",
6
6
  "keywords": [
@@ -22,7 +22,12 @@
22
22
  "**/*": "prettier --write --ignore-unknown"
23
23
  },
24
24
  "dependencies": {
25
+ "@emotion/cache": "^11.11.0",
26
+ "@emotion/react": "^11.11.4",
27
+ "@emotion/server": "^11.11.0",
28
+ "@emotion/styled": "^11.11.5",
25
29
  "@fortawesome/fontawesome-free": "^6.5.2",
30
+ "@loadable/component": "^5.16.4",
26
31
  "@mui/icons-material": "^5.15.15",
27
32
  "@mui/material": "^5.15.15",
28
33
  "@ncwidgets/file-relation": "^0.8.0",
@@ -108,6 +113,7 @@
108
113
  "react-iframe-comm": "^1.2.2",
109
114
  "react-immutable-proptypes": "^2.2.0",
110
115
  "react-laag": "^2.0.5",
116
+ "react-loadable-visibility": "^3.0.2",
111
117
  "react-medium-image-zoom": "^4.3.5",
112
118
  "react-redux": "^7.2.6",
113
119
  "react-rte": "^0.16.3",
@@ -2,13 +2,19 @@ import React from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import CssBaseline from "@mui/material/CssBaseline";
4
4
  import { ThemeProvider } from "@mui/material/styles";
5
+ import loadable from "@loadable/component";
5
6
  import Footer from "./Footer";
6
7
  import SponsoredProjectsNav from "./SponsoredProjectsNav";
7
8
  import SubscribeForm from "./SubscribeForm";
8
9
  import AnnouncementBanner from "./AnnouncementBanner";
9
10
  import Header from "./Header";
10
- import Navbar from "./Navbar";
11
11
  import theme from "../theme";
12
+ import NavBarPlaceholder from "./Navbar/placeholder";
13
+
14
+ const Navbar = loadable(() => import("./Navbar"), {
15
+ ssr: false,
16
+ fallback: <NavBarPlaceholder />,
17
+ });
12
18
 
13
19
  function Layout({ children }) {
14
20
  return (
@@ -15,6 +15,7 @@ import AddIcon from "@mui/icons-material/Add";
15
15
  import RemoveIcon from "@mui/icons-material/Remove";
16
16
  import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
17
17
  import Button from "@mui/material/Button";
18
+ import Link from "../Link";
18
19
 
19
20
  import navbarContent from "../../content/navbar/index.json";
20
21
 
@@ -28,11 +29,6 @@ function Navbar({ isLoggedUser, member }) {
28
29
  const [navbarMenu, setNavbarMenu] = React.useState(null);
29
30
  const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false);
30
31
  const [isSearchBarOpen, setIsSearchBarOpen] = React.useState(false);
31
- const [domLoaded, setDomLoaded] = React.useState(false);
32
-
33
- React.useEffect(() => {
34
- setDomLoaded(true);
35
- }, []);
36
32
 
37
33
  const handleSetActiveMenu = (option) => {
38
34
  setNavbarMenu(navbarMenu === option ? null : option);
@@ -78,399 +74,393 @@ function Navbar({ isLoggedUser, member }) {
78
74
  };
79
75
 
80
76
  return (
81
- <>
82
- {domLoaded && (
83
- <nav role="navigation">
84
- <Script
85
- src={`${getEnvVariable(
86
- SEARCH_WIDGET_BASE_URL,
87
- )}/widget/embed.min.js`}
88
- onLoad={() => console.log("Script loaded")}
89
- />
90
- <AppBar
91
- position="static"
92
- className={styles.navbar}
93
- sx={{ backgroundColor: "#fff", boxShadow: "none" }}
94
- >
95
- <Container maxWidth="xl">
96
- <Toolbar disableGutters sx={{ flexWrap: "wrap" }}>
97
- <Box className={styles.navbarHeader}>
98
- <div className={styles.brandWrapper}>
99
- <a
100
- className={styles.navbarBrand}
101
- href="/"
102
- alt="Openstack logo"
103
- aria-label="Go to homepage"
104
- />
105
- </div>
106
- <Box
107
- className={styles.searchWrapper}
108
- sx={{ display: { xs: "none", md: "flex" } }}
109
- >
110
- <div
111
- role="button"
112
- tabIndex={0}
113
- onKeyDown={(event) => {
114
- if (event.key === "Enter" || event.key === " ") setIsSearchBarOpen(true);
115
- }}
116
- onClick={() => setIsSearchBarOpen(true)}
117
- className={styles.searchComponent}
118
- >
119
- <SearchIcon className={styles.searchIcon} />
120
- <span className={styles.headerSearchText}>Search</span>
121
- </div>
122
- <Box
123
- className={`openstack-search-bar ${styles.openstackSearchBar}`}
124
- style={{
125
- visibility: isSearchBarOpen ? "visible" : "hidden",
126
- opacity: isSearchBarOpen ? "1" : "0",
127
- }}
128
- data-baseurl={getEnvVariable(SEARCH_WIDGET_BASE_URL)}
129
- data-context="www-openstack"
130
- />
131
- </Box>
132
- </Box>
133
- {/* Mobile Menu */}
134
- <Box
135
- className={styles.mobileMenuWrapper}
136
- sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}
77
+ <nav role="navigation">
78
+ <Script
79
+ src={`${getEnvVariable(SEARCH_WIDGET_BASE_URL)}/widget/embed.min.js`}
80
+ onLoad={() => console.log("Script loaded")}
81
+ />
82
+ <AppBar
83
+ position="static"
84
+ className={styles.navbar}
85
+ sx={{ backgroundColor: "#fff", boxShadow: "none" }}
86
+ >
87
+ <Container maxWidth="xl">
88
+ <Toolbar disableGutters sx={{ flexWrap: "wrap" }}>
89
+ <Box className={styles.navbarHeader}>
90
+ <div className={styles.brandWrapper}>
91
+ <a
92
+ className={styles.navbarBrand}
93
+ href="/"
94
+ alt="Openstack logo"
95
+ aria-label="Go to homepage"
96
+ />
97
+ </div>
98
+ <Box
99
+ className={styles.searchWrapper}
100
+ sx={{ display: { xs: "none", md: "flex" } }}
101
+ >
102
+ <div
103
+ role="button"
104
+ tabIndex={0}
105
+ onKeyDown={(event) => {
106
+ if (event.key === "Enter" || event.key === " ") setIsSearchBarOpen(true);
107
+ }}
108
+ onClick={() => setIsSearchBarOpen(true)}
109
+ className={styles.searchComponent}
137
110
  >
138
- <IconButton
139
- className={styles.toggleIcon}
140
- size="large"
141
- aria-label="account of current user"
142
- aria-controls="menu-appbar"
143
- aria-haspopup="true"
144
- onClick={() => handleMobileMenuToggle()}
145
- color="inherit"
146
- >
147
- <MenuIcon />
148
- </IconButton>
149
- </Box>
150
- {/* Desktop Menu */}
111
+ <SearchIcon className={styles.searchIcon} />
112
+ <span className={styles.headerSearchText}>Search</span>
113
+ </div>
151
114
  <Box
152
- sx={{
153
- flexGrow: 1,
154
- display: {
155
- xs: "none",
156
- md: isSearchBarOpen ? "none" : "flex",
157
- },
158
- justifyContent: "flex-end",
115
+ className={`openstack-search-bar ${styles.openstackSearchBar}`}
116
+ style={{
117
+ visibility: isSearchBarOpen ? "visible" : "hidden",
118
+ opacity: isSearchBarOpen ? "1" : "0",
159
119
  }}
120
+ data-baseurl={getEnvVariable(SEARCH_WIDGET_BASE_URL)}
121
+ data-context="www-openstack"
122
+ />
123
+ </Box>
124
+ </Box>
125
+ {/* Mobile Menu */}
126
+ <Box
127
+ className={styles.mobileMenuWrapper}
128
+ sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}
129
+ >
130
+ <IconButton
131
+ className={styles.toggleIcon}
132
+ size="large"
133
+ aria-label="account of current user"
134
+ aria-controls="menu-appbar"
135
+ aria-haspopup="true"
136
+ onClick={() => handleMobileMenuToggle()}
137
+ color="inherit"
138
+ >
139
+ <MenuIcon />
140
+ </IconButton>
141
+ </Box>
142
+ {/* Desktop Menu */}
143
+ <Box
144
+ sx={{
145
+ flexGrow: 1,
146
+ display: {
147
+ xs: "none",
148
+ md: isSearchBarOpen ? "none" : "flex",
149
+ },
150
+ justifyContent: "flex-end",
151
+ }}
152
+ >
153
+ {navbarContent.items.map(
154
+ (item) => item.display && (
155
+ <Link
156
+ className={styles.navbarOption}
157
+ key={item.title}
158
+ sx={{ my: 2, display: "block" }}
159
+ href={item.link}
160
160
  >
161
- {navbarContent.items.map(
162
- (item) => item.display && (
163
- <Button
164
- className={styles.navbarOption}
165
- key={item.title}
166
- sx={{ my: 2, display: "block" }}
167
- disableRipple
168
- onClick={() => handleNavigation(item.link)}
169
- >
170
- {item.items?.length > 0 ? (
171
- <>
172
- {item.title}
173
- <ArrowDropDownIcon
174
- className={styles.arrowDownIcon}
161
+ {item.items?.length > 0 ? (
162
+ <>
163
+ {item.title}
164
+ <ArrowDropDownIcon className={styles.arrowDownIcon} />
165
+ <Box className={styles.dropDownMenu}>
166
+ {item.items.map((subItem) => (!subItem.title && !subItem.link ? (
167
+ <div
168
+ className={styles.divider}
169
+ key={subItem.title}
175
170
  />
176
- <Box className={styles.dropDownMenu}>
177
- {item.items.map((subItem) => (!subItem.title && !subItem.link ? (
178
- <div className={styles.divider} />
179
- ) : (
180
- <Button
181
- className={styles.dropdownMenuOption}
182
- key={subItem.title}
183
- onClick={() => handleNavigation(subItem.link)}
184
- sx={{ display: "block" }}
185
- disableRipple
186
- >
187
- {subItem.title}
188
- </Button>
189
- )))}
190
- </Box>
191
- </>
192
- ) : (
193
- item.title
194
- )}
195
- </Button>
196
- ),
171
+ ) : (
172
+ <Button
173
+ className={styles.dropdownMenuOption}
174
+ key={subItem.title}
175
+ onClick={() => handleNavigation(subItem.link)}
176
+ sx={{ display: "block" }}
177
+ disableRipple
178
+ >
179
+ {subItem.title}
180
+ </Button>
181
+ )))}
182
+ </Box>
183
+ </>
184
+ ) : (
185
+ item.title
197
186
  )}
198
- </Box>
199
- {isLoggedUser ? (
200
- <Box
201
- maxWidth="15%"
202
- sx={{
203
- display: {
204
- xs: "none",
205
- md: isSearchBarOpen ? "none" : "flex",
206
- },
207
- justifyContent: "flex-end",
208
- marginLeft: "auto",
209
- }}
210
- >
187
+ </Link>
188
+ ),
189
+ )}
190
+ </Box>
191
+ {isLoggedUser ? (
192
+ <Box
193
+ maxWidth="15%"
194
+ sx={{
195
+ display: {
196
+ xs: "none",
197
+ md: isSearchBarOpen ? "none" : "flex",
198
+ },
199
+ justifyContent: "flex-end",
200
+ marginLeft: "auto",
201
+ }}
202
+ >
203
+ <Box
204
+ className={`${styles.navbarOption}`}
205
+ sx={{ my: 2, display: "block" }}
206
+ >
207
+ My Account
208
+ <ArrowDropDownIcon className={styles.arrowDownIcon} />
209
+ <Box className={styles.dropDownMenu}>
211
210
  <Button
212
- className={`${styles.navbarOption}`}
213
- sx={{ my: 2, display: "block" }}
211
+ className={styles.dropdownMenuOption}
212
+ onClick={() => handleNavigation("/profile/")}
213
+ sx={{ display: "block" }}
214
214
  disableRipple
215
215
  >
216
- My Account
217
- <ArrowDropDownIcon className={styles.arrowDownIcon} />
218
- <Box className={styles.dropDownMenu}>
219
- <Button
220
- className={styles.dropdownMenuOption}
221
- onClick={() => handleNavigation("/profile/")}
222
- sx={{ display: "block" }}
223
- disableRipple
224
- >
225
- Edit Profile
226
- </Button>
227
- <Button
228
- className={styles.dropdownMenuOption}
229
- onClick={() => handleNavigation(
230
- `/community/members/profile/${
231
- member.id
232
- }/${`${member.first_name.toLowerCase()}-${member.last_name.toLowerCase()}`}`,
233
- )}
234
- sx={{ display: "block" }}
235
- disableRipple
236
- >
237
- View Public Profile
238
- </Button>
239
- <div className={styles.divider} />
240
- <Button
241
- className={styles.dropdownMenuOption}
242
- sx={{ display: "block" }}
243
- onClick={onClickLogout}
244
- disableRipple
245
- >
246
- Log out
247
- </Button>
248
- </Box>
216
+ Edit Profile
249
217
  </Button>
250
- </Box>
251
- ) : (
252
- <Box
253
- maxWidth="15%"
254
- sx={{
255
- display: {
256
- xs: "none",
257
- md: isSearchBarOpen ? "none" : "flex",
258
- },
259
- justifyContent: "flex-end",
260
- marginLeft: "auto",
261
- }}
262
- >
263
218
  <Button
264
- className={`${styles.navbarOption} ${styles.join}`}
265
- sx={{ my: 2, display: "block" }}
219
+ className={styles.dropdownMenuOption}
220
+ onClick={() => handleNavigation(
221
+ `/community/members/profile/${
222
+ member.id
223
+ }/${`${member.first_name.toLowerCase()}-${member.last_name.toLowerCase()}`}`,
224
+ )}
225
+ sx={{ display: "block" }}
266
226
  disableRipple
267
227
  >
268
- Join
269
- <ArrowDropDownIcon className={styles.arrowDownIcon} />
270
- <Box className={styles.dropDownMenu}>
271
- <Button
272
- className={styles.dropdownMenuOption}
273
- onClick={() => handleNavigation("https://openinfra.dev/join")}
274
- sx={{ display: "block" }}
275
- disableRipple
276
- >
277
- Sign up for Foundation Membership
278
- </Button>
279
- <Button
280
- className={styles.dropdownMenuOption}
281
- onClick={() => handleNavigation("https://openinfra.dev/join")}
282
- sx={{ display: "block" }}
283
- disableRipple
284
- >
285
- Sponsor the Foundation
286
- </Button>
287
- <Button
288
- className={styles.dropdownMenuOption}
289
- onClick={() => handleNavigation("https://openinfra.dev")}
290
- sx={{ display: "block" }}
291
- disableRipple
292
- >
293
- More about the Foundation
294
- </Button>
295
- </Box>
228
+ View Public Profile
296
229
  </Button>
230
+ <div className={styles.divider} />
297
231
  <Button
298
- className={`${styles.navbarOption} ${styles.login}`}
299
- onClick={() => doLogin("/")}
300
- sx={{ my: 2, display: "block" }}
232
+ className={styles.dropdownMenuOption}
233
+ sx={{ display: "block" }}
234
+ onClick={onClickLogout}
301
235
  disableRipple
302
236
  >
303
- Log in
237
+ Log out
304
238
  </Button>
305
239
  </Box>
306
- )}
307
- </Toolbar>
240
+ </Box>
241
+ </Box>
242
+ ) : (
308
243
  <Box
309
- className={`${styles.openstackSearchBarMobile} openstack-search-bar ossw-mobile`}
244
+ maxWidth="15%"
310
245
  sx={{
311
- visibility: {
312
- xs: isMobileMenuOpen ? "visible" : "hidden",
313
- md: "hidden",
246
+ display: {
247
+ xs: "none",
248
+ md: isSearchBarOpen ? "none" : "flex",
314
249
  },
315
- opacity: { xs: isMobileMenuOpen ? "1" : "0", md: "0" },
316
- height: { xs: isMobileMenuOpen ? "auto" : 0, md: 0 },
317
- color: "#8a959e",
250
+ justifyContent: "flex-end",
251
+ marginLeft: "auto",
318
252
  }}
319
- data-baseurl={getEnvVariable(SEARCH_WIDGET_BASE_URL)}
320
- data-context="www-openstack"
321
- />
322
- {isMobileMenuOpen && (
253
+ >
323
254
  <Box
324
- className={styles.navbarMobileMenu}
325
- sx={{
326
- display: { xs: "flex", md: "none" },
327
- }}
255
+ className={`${styles.navbarOption} ${styles.join}`}
256
+ sx={{ my: 2, display: "block" }}
328
257
  >
329
- {navbarContent.items.map(
330
- (item) => item.display && (
331
- <>
258
+ Join
259
+ <ArrowDropDownIcon className={styles.arrowDownIcon} />
260
+ <Box className={styles.dropDownMenu}>
261
+ <Button
262
+ className={styles.dropdownMenuOption}
263
+ onClick={() => handleNavigation("https://openinfra.dev/join")}
264
+ sx={{ display: "block" }}
265
+ disableRipple
266
+ >
267
+ Sign up for Foundation Membership
268
+ </Button>
269
+ <Button
270
+ className={styles.dropdownMenuOption}
271
+ onClick={() => handleNavigation("https://openinfra.dev/join")}
272
+ sx={{ display: "block" }}
273
+ disableRipple
274
+ >
275
+ Sponsor the Foundation
276
+ </Button>
277
+ <Button
278
+ className={styles.dropdownMenuOption}
279
+ onClick={() => handleNavigation("https://openinfra.dev")}
280
+ sx={{ display: "block" }}
281
+ disableRipple
282
+ >
283
+ More about the Foundation
284
+ </Button>
285
+ </Box>
286
+ </Box>
287
+ <Button
288
+ className={`${styles.navbarOption} ${styles.login}`}
289
+ onClick={() => doLogin("/")}
290
+ sx={{ my: 2, display: "block" }}
291
+ disableRipple
292
+ >
293
+ Log in
294
+ </Button>
295
+ </Box>
296
+ )}
297
+ </Toolbar>
298
+ <Box
299
+ className={`${styles.openstackSearchBarMobile} openstack-search-bar ossw-mobile`}
300
+ sx={{
301
+ visibility: {
302
+ xs: isMobileMenuOpen ? "visible" : "hidden",
303
+ md: "hidden",
304
+ },
305
+ opacity: { xs: isMobileMenuOpen ? "1" : "0", md: "0" },
306
+ height: { xs: isMobileMenuOpen ? "auto" : 0, md: 0 },
307
+ color: "#8a959e",
308
+ }}
309
+ data-baseurl={getEnvVariable(SEARCH_WIDGET_BASE_URL)}
310
+ data-context="www-openstack"
311
+ />
312
+ {isMobileMenuOpen && (
313
+ <Box
314
+ className={styles.navbarMobileMenu}
315
+ sx={{
316
+ display: { xs: "flex", md: "none" },
317
+ }}
318
+ >
319
+ {navbarContent.items.map(
320
+ (item) => item.display && (
321
+ <>
322
+ <Button
323
+ disableRipple
324
+ className={styles.mobileOption}
325
+ key={`${item.title}-mobile`}
326
+ onClick={() => handleSetActiveMenu(item.title)}
327
+ >
328
+ {item.title}
329
+ {item.items?.length > 0
330
+ && (item.title === navbarMenu ? (
331
+ <RemoveIcon aria-hidden="true" />
332
+ ) : (
333
+ <AddIcon aria-hidden="true" />
334
+ ))}
335
+ </Button>
336
+ {item.items?.length > 0 && item.title === navbarMenu && (
337
+ <Box className={styles.mobileDropdownMenu}>
338
+ {item.items.map((subItem) => (!subItem.title && !subItem.link ? (
339
+ <div
340
+ className={styles.divider}
341
+ key={subItem.title}
342
+ />
343
+ ) : (
332
344
  <Button
345
+ className={styles.mobileDropdownOption}
346
+ key={`${subItem.title}-mobile`}
347
+ onClick={() => handleNavigation(subItem.link)}
348
+ sx={{ display: "block" }}
333
349
  disableRipple
334
- className={styles.mobileOption}
335
- key={`${item.title}-mobile`}
336
- onClick={() => handleSetActiveMenu(item.title)}
337
350
  >
338
- {item.title}
339
- {item.items?.length > 0
340
- && (item.title === navbarMenu ? (
341
- <RemoveIcon aria-hidden="true" />
342
- ) : (
343
- <AddIcon aria-hidden="true" />
344
- ))}
351
+ {subItem.title}
345
352
  </Button>
346
- {item.items?.length > 0
347
- && item.title === navbarMenu && (
348
- <Box className={styles.mobileDropdownMenu}>
349
- {item.items.map((subItem) => (!subItem.title && !subItem.link ? (
350
- <div className={styles.divider} />
351
- ) : (
352
- <Button
353
- className={styles.mobileDropdownOption}
354
- key={subItem.title}
355
- onClick={() => handleNavigation(subItem.link)}
356
- sx={{ display: "block" }}
357
- disableRipple
358
- >
359
- {subItem.title}
360
- </Button>
361
- )))}
362
- </Box>
363
- )}
364
- </>
365
- ),
353
+ )))}
354
+ </Box>
366
355
  )}
367
- {isLoggedUser ? (
368
- <>
356
+ </>
357
+ ),
358
+ )}
359
+ {isLoggedUser ? (
360
+ <>
361
+ <Button
362
+ className={styles.mobileOption}
363
+ onClick={() => handleSetActiveMenu("My Account")}
364
+ disableRipple
365
+ >
366
+ My Account
367
+ {navbarMenu === "My Account" ? (
368
+ <RemoveIcon aria-hidden="true" />
369
+ ) : (
370
+ <AddIcon aria-hidden="true" />
371
+ )}
372
+ </Button>
373
+ {navbarMenu === "My Account" && (
374
+ <Box className={styles.mobileDropdownMenu}>
369
375
  <Button
370
- className={styles.mobileOption}
371
- onClick={() => handleSetActiveMenu("My Account")}
376
+ className={styles.mobileDropdownOption}
377
+ onClick={() => handleNavigation("/profile/")}
378
+ sx={{ display: "block" }}
372
379
  disableRipple
373
380
  >
374
- My Account
375
- {navbarMenu === "My Account" ? (
376
- <RemoveIcon aria-hidden="true" />
377
- ) : (
378
- <AddIcon aria-hidden="true" />
379
- )}
381
+ Edit Profile
380
382
  </Button>
381
- {navbarMenu === "My Account" && (
382
- <Box className={styles.mobileDropdownMenu}>
383
- <Button
384
- className={styles.mobileDropdownOption}
385
- onClick={() => handleNavigation("/profile/")}
386
- sx={{ display: "block" }}
387
- disableRipple
388
- >
389
- Edit Profile
390
- </Button>
391
- <Button
392
- className={styles.mobileDropdownOption}
393
- onClick={() => handleNavigation(
394
- `/community/members/profile/${
395
- member.id
396
- }/${`${member.first_name.toLowerCase()}-${member.last_name.toLowerCase()}`}`,
397
- )}
398
- sx={{ display: "block" }}
399
- disableRipple
400
- >
401
- View Public Profile
402
- </Button>
403
- <div className={styles.divider} />
404
- <Button
405
- className={styles.mobileDropdownOption}
406
- sx={{ display: "block" }}
407
- onClick={onClickLogout}
408
- disableRipple
409
- >
410
- Log out
411
- </Button>
412
- </Box>
413
- )}
414
- </>
415
- ) : (
416
- <Box>
417
383
  <Button
418
- className={`${styles.navbarOption} ${styles.join}`}
419
- sx={{ my: 2, display: "block" }}
384
+ className={styles.mobileDropdownOption}
385
+ onClick={() => handleNavigation(
386
+ `/community/members/profile/${
387
+ member.id
388
+ }/${`${member.first_name.toLowerCase()}-${member.last_name.toLowerCase()}`}`,
389
+ )}
390
+ sx={{ display: "block" }}
420
391
  disableRipple
421
392
  >
422
- Join
423
- <ArrowDropDownIcon className={styles.arrowDownIcon} />
424
- <Box className={styles.dropDownMenu}>
425
- <Button
426
- className={styles.dropdownMenuOption}
427
- onClick={() => handleNavigation("https://openinfra.dev/join")}
428
- sx={{ display: "block" }}
429
- disableRipple
430
- >
431
- Sign up for Foundation Membership
432
- </Button>
433
- <Button
434
- className={styles.dropdownMenuOption}
435
- onClick={() => handleNavigation("https://openinfra.dev/join")}
436
- sx={{ display: "block" }}
437
- disableRipple
438
- >
439
- Sponsor the Foundation
440
- </Button>
441
- <Button
442
- className={styles.dropdownMenuOption}
443
- onClick={() => handleNavigation("https://openinfra.dev")}
444
- sx={{ display: "block" }}
445
- disableRipple
446
- >
447
- More about the Foundation
448
- </Button>
449
- </Box>
393
+ View Public Profile
450
394
  </Button>
395
+ <div className={styles.divider} />
451
396
  <Button
452
- className={`${styles.navbarOption} ${styles.login}`}
453
- onClick={() => doLogin("/")}
454
- sx={{ my: 2, display: "block" }}
397
+ className={styles.mobileDropdownOption}
398
+ sx={{ display: "block" }}
399
+ onClick={onClickLogout}
455
400
  disableRipple
456
401
  >
457
- Log in
402
+ Log out
458
403
  </Button>
459
404
  </Box>
460
405
  )}
406
+ </>
407
+ ) : (
408
+ <Box>
409
+ <Box
410
+ className={`${styles.navbarOption} ${styles.join}`}
411
+ sx={{ my: 2, display: "block" }}
412
+ >
413
+ Join
414
+ <ArrowDropDownIcon className={styles.arrowDownIcon} />
415
+ <Box className={styles.dropDownMenu}>
416
+ <Button
417
+ className={styles.dropdownMenuOption}
418
+ onClick={() => handleNavigation("https://openinfra.dev/join")}
419
+ sx={{ display: "block" }}
420
+ disableRipple
421
+ >
422
+ Sign up for Foundation Membership
423
+ </Button>
424
+ <Button
425
+ className={styles.dropdownMenuOption}
426
+ onClick={() => handleNavigation("https://openinfra.dev/join")}
427
+ sx={{ display: "block" }}
428
+ disableRipple
429
+ >
430
+ Sponsor the Foundation
431
+ </Button>
432
+ <Button
433
+ className={styles.dropdownMenuOption}
434
+ onClick={() => handleNavigation("https://openinfra.dev")}
435
+ sx={{ display: "block" }}
436
+ disableRipple
437
+ >
438
+ More about the Foundation
439
+ </Button>
440
+ </Box>
441
+ </Box>
442
+ <Button
443
+ className={`${styles.navbarOption} ${styles.login}`}
444
+ onClick={() => doLogin("/")}
445
+ sx={{ my: 2, display: "block" }}
446
+ disableRipple
447
+ >
448
+ Log in
449
+ </Button>
461
450
  </Box>
462
451
  )}
463
- </Container>
464
- </AppBar>
465
- </nav>
466
- )}
467
- </>
452
+ </Box>
453
+ )}
454
+ </Container>
455
+ </AppBar>
456
+ </nav>
468
457
  );
469
458
  }
470
459
 
471
460
  Navbar.propTypes = {
472
461
  isLoggedUser: PropTypes.bool.isRequired,
473
- member: PropTypes.object.isRequired,
462
+ member: PropTypes.oneOfType([PropTypes.object, PropTypes.oneOf([null])])
463
+ .isRequired,
474
464
  };
475
465
 
476
466
  const mapStateToProps = ({ loggedUserState }) => ({
@@ -118,6 +118,7 @@
118
118
  white-space: nowrap;
119
119
  background-color: transparent;
120
120
  margin: 0;
121
+ align-items: center;
121
122
  &:hover {
122
123
  color: #333;
123
124
  background-color: transparent;
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ import AppBar from "@mui/material/AppBar";
3
+ import { Container } from "@mui/material";
4
+ import styles from "./index.module.scss";
5
+
6
+ function NavBarPlaceholder() {
7
+ return (
8
+ <nav role="navigation">
9
+ <AppBar
10
+ position="static"
11
+ className={styles.navbar}
12
+ sx={{ backgroundColor: "#fff", boxShadow: "none" }}
13
+ >
14
+ <Container maxWidth="xl" />
15
+ </AppBar>
16
+ </nav>
17
+ );
18
+ }
19
+
20
+ export default NavBarPlaceholder;
@@ -1 +1 @@
1
- { "staticJsonFilesBuildTime": [], "lastBuild": 1713872964380 }
1
+ { "staticJsonFilesBuildTime": [], "lastBuild": 1713964554954 }
@@ -1,9 +1,11 @@
1
1
  import * as React from "react";
2
2
  import { Provider } from "react-redux";
3
3
  import { PersistGate } from "redux-persist/integration/react";
4
+ import { CacheProvider } from "@emotion/react";
4
5
  import { store, persistor } from "./store";
6
+ import createEmotionCache from "../utils/createEmotionCache";
5
7
 
6
- function ReduxWrapper({ element }) {
8
+ export function ReduxWrapper({ element }) {
7
9
  return (
8
10
  <Provider store={store}>
9
11
  <PersistGate persistor={persistor}>{() => element}</PersistGate>
@@ -11,4 +13,13 @@ function ReduxWrapper({ element }) {
11
13
  );
12
14
  }
13
15
 
14
- export default ReduxWrapper;
16
+ export function ReduxWrapperWithCacheProvider({ element }) {
17
+ const cache = createEmotionCache();
18
+ return (
19
+ <CacheProvider value={cache}>
20
+ <Provider store={store}>
21
+ <PersistGate persistor={persistor}>{() => element}</PersistGate>
22
+ </Provider>
23
+ </CacheProvider>
24
+ );
25
+ }
@@ -0,0 +1,5 @@
1
+ import createCache from "@emotion/cache";
2
+
3
+ const createEmotionCache = (options) => createCache(options ?? { key: "css" });
4
+
5
+ export default createEmotionCache;