Skip to content

Commit

Permalink
Add modal and banner to header (#560)
Browse files Browse the repository at this point in the history
* Add modal and banner to header

* Update header snapshot

* Make release banner pos relative

* Refactor release banner to own component

* Update header snapshot

* Temporarily disable header text check
  • Loading branch information
Tammo-Feldmann authored Jul 10, 2023
1 parent f143b20 commit 504947e
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 26 deletions.
50 changes: 27 additions & 23 deletions playwright/e2e/header.spec.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
const { test, expect } = require('@playwright/test');
import config from "../playwright.config";
import { site } from "../../test/__fixtures__";
const { test, expect } = require("@playwright/test")
import config from "../playwright.config"
import { site } from "../../test/__fixtures__"

const baseUrl = config.use?.baseURL;
const baseUrl = config.use?.baseURL

test.describe('Header', () => {
let page;
test.describe("Header", () => {
let page

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
await page.goto(baseUrl);
});
test.beforeAll(async ({ browser }) => {
page = await browser.newPage()
await page.goto(baseUrl)
})

test('renders correctly', async () => {
await expect(page.locator('header')).toHaveText(site.siteMetadata.headerType);
test("renders correctly", async () => {
// TODO re-enable this header test once temporary release banner is removed
// await expect(page.locator('header')).toHaveText(site.siteMetadata.headerType);

const nasaLogo = page.locator('[data-cy=nasa-logo]');
await expect(nasaLogo).toHaveAttribute('alt', "NASA's red, white and blue insignia, nicknamed the 'meatball'");
const nasaLogo = page.locator("[data-cy=nasa-logo]")
await expect(nasaLogo).toHaveAttribute(
"alt",
"NASA's red, white and blue insignia, nicknamed the 'meatball'"
)

const navItems = await page.locator('nav').locator('li');
await expect(navItems).toHaveCount(5);
const navItems = await page.locator("nav").locator("li")
await expect(navItems).toHaveCount(5)

await expect(navItems.nth(0)).toHaveText('Explore');
await expect(navItems.nth(1)).toHaveText('Glossary');
await expect(navItems.nth(2)).toHaveText('About');
await expect(navItems.nth(3)).toHaveText('FAQS');
await expect(navItems.nth(4)).toHaveText('Contact');
});
});
await expect(navItems.nth(0)).toHaveText("Explore")
await expect(navItems.nth(1)).toHaveText("Glossary")
await expect(navItems.nth(2)).toHaveText("About")
await expect(navItems.nth(3)).toHaveText("FAQS")
await expect(navItems.nth(4)).toHaveText("Contact")
})
})
66 changes: 66 additions & 0 deletions src/components/__tests__/__snapshots__/header.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,72 @@ exports[`Header renders correctly 1`] = `
className="header___StyledHeader-sc-4sefiz-0 eymLSC"
id="main-header"
>
<div
className="release-banner___StyledDiv-sc-2g9opo-2 kTagCK"
>
July 2023 Update! While CASEI has been publicly available in beta mode
since 2021, we are launching our
<button
className="release-banner___StyledButton2-sc-2g9opo-3 cfqzWr"
onClick={[Function]}
>
full-release version
</button>
<button
className="button__Clickable-sc-1yw7vig-0 button___StyledClickable2-sc-1yw7vig-1 fRqvWm kXXfwm"
data-cy="remove-filter"
onClick={[Function]}
type="button"
>
<span
aria-label="remove-filter-icon"
role="img"
>
<svg
height="12px"
viewBox="0 0 16 16"
width="12px"
xmlns="http://www.w3.org/2000/svg"
>
<polygon
fill="#262a31"
points="13.707,3.707 12.293,2.293 8,6.586 3.707,2.293 2.293,3.707 6.586,8 2.293,12.293 3.707,13.707 8,9.414 12.293,13.707 13.707,12.293 9.414,8"
/>
</svg>
</span>
</button>
</div>
<div
className="modal__Backdrop-sc-1e4q5bt-0 dIthjC"
onClick={[Function]}
>
<div
className="release-banner__Component-sc-2g9opo-0 feanVv"
>
<p>
July 2023 Update! While CASEI has been publicly available in beta mode since 2021, there is now a majority (65%) of known NASA airborne and field campaigns represented across the database and a unique range of search/browse functionality built into CASEI and its API.
</p>
<br />
<p>
As you explore CASEI in this full-release version, keep in mind that additional campaigns, platforms, instruments, and data products are still being curated. We welcome
<button
className="release-banner___StyledButton-sc-2g9opo-1 blnDoP"
onClick={[Function]}
>
your feedback
</button>
!
</p>
<br />
<button
className="button__Clickable-sc-1yw7vig-0 button___StyledClickable-sc-1yw7vig-2 fRqvWm jVedgi"
onClick={[Function]}
>
okay
</button>
</div>
</div>
<div
className="header___StyledDiv-sc-4sefiz-1 hgzXFp"
>
Expand Down
3 changes: 2 additions & 1 deletion src/components/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { StaticImage } from "gatsby-plugin-image"
import { colors, layout, breakpoints } from "../theme"
import { CaseiLogoIcon } from "../icons"
import { NEGATIVE } from "../utils/constants"

import StickyBanner from "./sticky-banner"
import ReleaseBanner from "./release-banner"

const Header = ({ shortname, children, mode }) => {
const offsetCalculator = (scrollDirection, _, currentScroll) => {
Expand All @@ -29,6 +29,7 @@ const Header = ({ shortname, children, mode }) => {
rgba(68, 63, 63, 0.08) 0px 2px 6px 0px;
`}
>
<ReleaseBanner />
<div
css={`
margin: 0 auto;
Expand Down
5 changes: 3 additions & 2 deletions src/components/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ const Component = styled.div`
pointer-events: auto;
`

export const Modal = ({ handleClose, isOpen, children }) => {
export const Modal = ({ handleClose, isOpen, children, Custom }) => {
return (
<Backdrop
isOpen={isOpen}
onClick={e => (e.target === e.currentTarget ? handleClose() : null)}
>
<Component>{children}</Component>
{Custom ? <Custom /> : <Component>{children}</Component>}
</Backdrop>
)
}
Expand All @@ -43,4 +43,5 @@ Modal.propTypes = {
handleClose: PropTypes.func.isRequired,
isOpen: PropTypes.bool.isRequired,
children: PropTypes.element,
Custom: PropTypes.element,
}
148 changes: 148 additions & 0 deletions src/components/release-banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import React, { useEffect, useState } from "react"
import PropTypes from "prop-types"
import styled from "styled-components"

import { CloseIcon } from "../icons"
import Button, { IconButton } from "./button"
import { Modal } from "./modal"
import { FEEDBACK_FORM_URL, POSITIVE } from "../utils/constants"
import { colors } from "../theme"

const Component = styled.div`
width: 25rem;
padding: 2rem;
position: relative;
overflow: hidden;
max-height: 720px;
border-radius: 3px;
background: #f2f7fb;
pointer-events: auto;
color: ${colors[POSITIVE].text};
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
`

const ReleaseBanner = () => {
const [hasSeenNotice, setHasSeenNotice] = useState(false)
const [isModalOpen, setModal] = useState(false)

// This runs when the page is loaded.
useEffect(() => {
if (localStorage.getItem("has_seen_notice")) {
setHasSeenNotice(true)
}
}, [])

const markReleaseNoticeSeen = () => {
localStorage.setItem("has_seen_notice", "true")
setHasSeenNotice(true)
setModal(false)
}

const ModalBody = () => (
<Component>
<p>
July 2023 Update! While CASEI has been publicly available in beta mode
since 2021, there is now a majority (65%) of known NASA airborne and
field campaigns represented across the database and a unique range of
search/browse functionality built into CASEI and its API.
</p>
<br />
<p>
As you explore CASEI in this full-release version, keep in mind that
additional campaigns, platforms, instruments, and data products are
still being curated. We welcome
<button
css={`
background: none;
color: inherit;
border: none;
padding: 0 0 0 4px;
font: inherit;
cursor: pointer;
outline: inherit;
text-transform: lowercase;
text-decoration: underline;
&:hover {
opacity: 0.8;
}
`}
onClick={() => {
markReleaseNoticeSeen()
window.open(FEEDBACK_FORM_URL, "_blank")
}}
>
your feedback
</button>
!
</p>
<br />
<Button action={markReleaseNoticeSeen}>okay</Button>
</Component>
)

return (
<>
<div
css={`
position: relative;
background: #ebba33;
color: ${colors[POSITIVE].text};
opacity: 0.95;
width: 100%;
justify-content: center;
align-items: center;
padding: 1rem;
z-index: 400;
display: ${hasSeenNotice ? "none" : "flex"};
`}
>
{`July 2023 Update! While CASEI has been publicly available in beta mode
since 2021, we are launching our `}
<button
css={`
background: none;
color: inherit;
border: none;
padding: 0 0 0 4px;
font: inherit;
cursor: pointer;
outline: inherit;
text-transform: lowercase;
text-decoration: underline;
&:hover {
opacity: 0.8;
}
`}
onClick={() => {
setModal(true)
}}
>
{" "}
full-release version
</button>
<IconButton
id="remove-filter"
action={markReleaseNoticeSeen}
icon={<CloseIcon color={colors[POSITIVE].text} />}
/>
</div>
<Modal
id="modal"
isOpen={isModalOpen}
handleClose={() => setModal(false)}
Custom={ModalBody}
></Modal>
</>
)
}

ReleaseBanner.propTypes = {
shortname: PropTypes.string.isRequired,
children: PropTypes.element,
mode: PropTypes.string.isRequired,
}

export default ReleaseBanner

0 comments on commit 504947e

Please sign in to comment.