diff --git a/gatsby-config.js b/gatsby-config.js index fc3e9b5..b3bfc55 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -33,6 +33,7 @@ module.exports = { schemas: { // all the schemas here test: require("./src/schemas/test.json"), + faq: require("./src/schemas/faq.json"), product_page: require("./src/schemas/product_page.json"), product: require("./src/schemas/product.json"), Process: require("./src/schemas/process.json"), @@ -47,9 +48,9 @@ module.exports = { resolve: "gatsby-plugin-react-svg", options: { rule: { - include: /vectors/ // See below to configure properly - } - } - } + include: /vectors/, // See below to configure properly + }, + }, + }, ], } diff --git a/src/components/contact/contact-styles.js b/src/components/contact/contact-styles.js index d5767b0..63dcbea 100644 --- a/src/components/contact/contact-styles.js +++ b/src/components/contact/contact-styles.js @@ -1,12 +1,12 @@ -import styled from "styled-components" +import styled from "@emotion/styled" import colors from "../../style/colors" import dimensions from "../../style/dimensions" - import { fontSizes } from "../../style/type-styles" import { layoutPaddingDesktop, layoutPaddingMobile, } from "../../style/variables" + export const ContactContainer = styled.div` min-height: 100vh; ` @@ -16,7 +16,6 @@ export const ContactForm = styled.div` width: 100%; @media (min-width: ${dimensions.maxwidthTablet}px) { width: 36vw; - } color: ${colors.blue900}; input { @@ -49,7 +48,7 @@ export const ContactSection = styled.div` export const ContactDescription = styled.div` margin-bottom: 64px; ` -export const ContactButton = styled.button` +export const ContactButton = styled.a` font-size: 16px; padding-right: 60px; padding-left: 60px; @@ -60,6 +59,11 @@ export const ContactButton = styled.button` color: ${colors.white900}; border: none; + transition: all 0.1s ease-in-out; + + &:hover { + box-shadow: 0 0 46px -9px ${colors.orange900}; + } ` export const ContactImageSection = styled.div` @@ -72,7 +76,6 @@ export const ContactImageSection = styled.div` object-fit: cover; } - @media (max-width: ${dimensions.maxwidthTablet}px) { margin-right: -${layoutPaddingMobile}; @@ -83,9 +86,7 @@ export const ContactImageSection = styled.div` height: 263px; object-fit: cover; } - } - ` export const SpecificContactInfo = styled.div` @@ -108,7 +109,4 @@ export const AddressSection = styled.div` margin-bottom: 110px; ` -export const UseCaseSection = styled.div` - - -` \ No newline at end of file +export const UseCaseSection = styled.div`` diff --git a/src/components/faq/faq-contact/FAQContact.js b/src/components/faq/faq-contact/FAQContact.js new file mode 100644 index 0000000..79ae096 --- /dev/null +++ b/src/components/faq/faq-contact/FAQContact.js @@ -0,0 +1,18 @@ +import React from "react" +import { ContactButton } from "../../contact/contact-styles" +import { Banner, CTABackground, CTATitle } from "./FAQContact.styles" +export const FAQContact = ({ + imageUrl, + ctaTitle, + ctaLabel, + ctaDestination, +}) => ( + <> + + + {ctaTitle} + {ctaLabel} + + + +) diff --git a/src/components/faq/faq-contact/FAQContact.styles.js b/src/components/faq/faq-contact/FAQContact.styles.js new file mode 100644 index 0000000..1edc9be --- /dev/null +++ b/src/components/faq/faq-contact/FAQContact.styles.js @@ -0,0 +1,41 @@ +import styled from "@emotion/styled" +import colors from "../../../style/colors" +import dimensions from "../../../style/dimensions" +import { H3 } from "../../../style/type-styles" +import { + layoutPaddingDesktop, + layoutPaddingMobile, +} from "../../../style/variables" + +export const Banner = styled.div` + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + background-image: url(${props => props.imageUrl}); + width: 100vw; + padding: 40px 60px; + margin: -${layoutPaddingDesktop}; + height: 70vh; + + @media (max-width: ${dimensions.maxwidthMobile}px) { + height: 40vh; + margin: -${layoutPaddingMobile}; + } +` + +export const CTABackground = styled.div` + width: 100%; + height: 100%; + + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + background-color: ${colors.white900}; +` + +export const CTATitle = styled(H3)` + color: ${colors.blue900}; +` diff --git a/src/components/faq/faq-question/FAQQuestion.js b/src/components/faq/faq-question/FAQQuestion.js new file mode 100644 index 0000000..ce407dd --- /dev/null +++ b/src/components/faq/faq-question/FAQQuestion.js @@ -0,0 +1,34 @@ +import React, { useState } from "react" +import CloseIcon from "../../../vectors/close.svg" +import OpenIcon from "../../../vectors/open.svg" +import { + FAQAnswer, + FAQQuestionTitle, + ToggleContainer, +} from "./FAQQuestion.styles" + +export const FAQQuestion = ({ questionText, answerText }) => { + const [isOpen, setOpen] = useState(false) + + return ( + <> + + {questionText} + {isOpen ? ( + setOpen(false)} + role="button" + aria-label="Close FAQ question" + /> + ) : ( + setOpen(true)} + role="button" + aria-label="Expand FAQ question" + /> + )} + + {isOpen && {answerText}} + + ) +} diff --git a/src/components/faq/faq-question/FAQQuestion.styles.js b/src/components/faq/faq-question/FAQQuestion.styles.js new file mode 100644 index 0000000..d65db58 --- /dev/null +++ b/src/components/faq/faq-question/FAQQuestion.styles.js @@ -0,0 +1,23 @@ +import styled from "@emotion/styled" +import colors from "../../../style/colors" +import { Body, H4 } from "../../../style/type-styles" + +export const ToggleContainer = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + width: 100%; +` + +export const FAQQuestionTitle = styled(H4)` + color: ${colors.blue900}; + margin: 0; +` + +export const FAQAnswer = styled(Body)` + color: ${colors.blue900}; + padding-left: 24px; + width: 90%; + line-height: 32px; +` diff --git a/src/components/faq/faq.js b/src/components/faq/faq.js new file mode 100644 index 0000000..04d493f --- /dev/null +++ b/src/components/faq/faq.js @@ -0,0 +1,74 @@ +import React from "react" +import { H3 } from "../../style/type-styles" +import { FAQContact } from "./faq-contact/FAQContact" +import { FAQQuestion } from "./faq-question/FAQQuestion" +import { + FAQContainer, + FAQQuestionsContainer, + FAQWrapper, + TopicContainer, + TopicFAQSection, +} from "./faq.styles" +import { TopicsPicker } from "./topics-picker/TopicsPicker" + +const FAQPage = ({ data }) => { + const { + main_section_heading, + topics_section_heading, + cta_button_destination, + cta_button_text, + cta_heading, + ctabackground, + frequently_asked_question, + individual_topic, + } = data + + const [selectedTopic, setSelected] = React.useState() + + return ( + +

{main_section_heading}

+ + + ({ + ...t, + label: t.topic_heading, + id: t.topic_heading + i, + selected: t.topic_heading === selectedTopic, + questions: frequently_asked_question.filter( + faq => faq.topic === t.topic_heading + ), + }))} + onTopicPicked={t => + setSelected( + t.topic_heading === selectedTopic ? undefined : t.topic_heading + ) + } + /> + + + + {frequently_asked_question + .filter(fq => (selectedTopic ? fq.topic === selectedTopic : true)) + .map(fq => ( + + + + ))} + + + +
+ ) +} + +export default FAQPage diff --git a/src/components/faq/faq.styles.js b/src/components/faq/faq.styles.js new file mode 100644 index 0000000..a057e0d --- /dev/null +++ b/src/components/faq/faq.styles.js @@ -0,0 +1,35 @@ +import styled from "@emotion/styled" +import dimensions from "../../style/dimensions" + +export const FAQContainer = styled.div` + padding-top: 12vh; +` +export const TopicFAQSection = styled.section` + display: flex; + flex-direction: row; + justify-content: space-between; + @media (max-width: ${dimensions.maxwidthDesktop}px) { + flex-direction: column-reverse; + } + margin-bottom: 20vh; + @media (max-width: ${dimensions.maxwidthMobile}px) { + margin-bottom: 10vh; + } +` + +export const TopicContainer = styled.div` + flex: 4; +` + +export const FAQQuestionsContainer = styled.div` + display: flex; + flex-direction: column; + flex: 6; + @media (max-width: ${dimensions.maxwidthDesktop}px) { + display: none; + } +` + +export const FAQWrapper = styled.div` + margin-bottom: 20px; +` diff --git a/src/components/faq/topics-picker/TopicsPicker.js b/src/components/faq/topics-picker/TopicsPicker.js new file mode 100644 index 0000000..db231e6 --- /dev/null +++ b/src/components/faq/topics-picker/TopicsPicker.js @@ -0,0 +1,44 @@ +import React, { useState } from "react" +import { FAQQuestion } from "../faq-question/FAQQuestion" +import { + TopicBox, + TopicFAQContainer, + TopicsContainer, +} from "./TopicsPicker.styles" + +export const TopicsPicker = ({ topics, onTopicPicked }) => { + const [openTopics, setOpen] = useState([]) + const onTopicSelected = topic => { + const { label } = topic + onTopicPicked(topic) + setOpen(prev => + prev.includes(label) ? prev.filter(t => t !== label) : [...prev, label] + ) + } + + return ( + + {topics.map(t => ( + + onTopicSelected(t)} + selected={t.selected} + > + {t.label} + + {openTopics.includes(t.label) && + t.questions.map(fq => ( + + + + ))} + + ))} + + ) +} diff --git a/src/components/faq/topics-picker/TopicsPicker.styles.js b/src/components/faq/topics-picker/TopicsPicker.styles.js new file mode 100644 index 0000000..9c1c834 --- /dev/null +++ b/src/components/faq/topics-picker/TopicsPicker.styles.js @@ -0,0 +1,59 @@ +import { css } from "@emotion/react" +import styled from "@emotion/styled" +import colors from "../../../style/colors" +import dimensions from "../../../style/dimensions" + +export const TopicsContainer = styled.div` + display: flex; + flex-direction: row; + flex-wrap: wrap; +` + +const SelectedBox = css` + border: 3px solid ${colors.orange900}; + background-color: ${colors.orange900_transparent}; +` + +export const TopicBox = styled.div` + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; + margin: 10px; + flex: 50%; + max-width: 40%; + aspect-ratio: 4/3; + font-weight: bolder; + + cursor: pointer; + border: 2px solid ${colors.orange900}; + background-color: transparent; + transition: all 0.1s ease-in-out; + color: ${colors.orange900}; + text-transform: uppercase; + + ${props => props.selected && SelectedBox}; + + &:hover { + ${SelectedBox}; + } + + @media (max-width: ${dimensions.maxwidthDesktop}px) { + flex: 100%; + max-width: 100%; + height: 100px; + } + @media (max-width: ${dimensions.maxwidthDesktop}px) { + width: 100%; + } +` + +export const TopicFAQContainer = styled.div` + flex: 100%; + max-width: 100%; + margin: 10px; + display: none; + @media (max-width: ${dimensions.maxwidthDesktop}px) { + display: initial; + } +` diff --git a/src/components/layout.js b/src/components/layout.js index 0d2e5b4..2117e43 100644 --- a/src/components/layout.js +++ b/src/components/layout.js @@ -1,16 +1,16 @@ import React from "react" import styled from "styled-components" -import "../style/typography.scss" -import "../style/global.scss" -import dimensions from "../style/dimensions" -import { layoutPaddingDesktop, layoutPaddingMobile } from "../style/variables" import Footer from "../components/footer/footer" import Header from "../components/header/header" +import dimensions from "../style/dimensions" +import "../style/global.scss" +import "../style/typography.scss" +import { layoutPaddingDesktop, layoutPaddingMobile } from "../style/variables" const LayoutContainer = styled.div`` const LayoutBody = styled.div` @media (min-width: ${dimensions.maxwidthTablet}px) { - padding: 0 ${layoutPaddingDesktop} ${layoutPaddingDesktop};s + padding: 0 ${layoutPaddingDesktop} ${layoutPaddingDesktop}; } @media (max-width: ${dimensions.maxwidthTablet}px) { diff --git a/src/pages/faq.js b/src/pages/faq.js new file mode 100644 index 0000000..178ba2d --- /dev/null +++ b/src/pages/faq.js @@ -0,0 +1,39 @@ +import { graphql } from "gatsby" +import React from "react" +import FAQPage from "../components/faq/faq" +import Layout from "../components/layout" + +export default function FAQ({ data }) { + return ( + + + + ) +} + +export const query = graphql` + query FAQQuery { + prismicFaqPage(data: {}) { + data { + main_section_heading + topics_section_heading + ctabackground { + url + } + cta_heading + cta_button_text + cta_button_destination { + url + } + frequently_asked_question { + question + answer + topic + } + individual_topic { + topic_heading + } + } + } + } +` diff --git a/src/schemas/faq.json b/src/schemas/faq.json new file mode 100644 index 0000000..246d048 --- /dev/null +++ b/src/schemas/faq.json @@ -0,0 +1,96 @@ +{ + "Main": {}, + "Top Questions": { + "main_section_heading": { + "type": "Text", + "config": { + "label": "Main Section Heading" + } + }, + "frequently_asked_question": { + "type": "Group", + "config": { + "fields": { + "question": { + "type": "Text", + "config": { + "label": "Question" + } + }, + "answer": { + "type": "Text", + "config": { + "label": "Answer" + } + }, + "topic": { + "type": "Text", + "config": { + "label": "topic", + "placeholder": "The topic this question answer pair is associated with" + } + } + }, + "label": "Frequently Asked Question" + } + } + }, + "Topics": { + "topics_section_heading": { + "type": "Text", + "config": { + "label": "Topics Section Heading" + } + }, + "individual_topic": { + "type": "Group", + "config": { + "fields": { + "topic_image": { + "type": "Image", + "config": { + "constraint": {}, + "thumbnails": [], + "label": "Topic Image" + } + }, + "topic_heading": { + "type": "Text", + "config": { + "label": "Topic Heading" + } + } + }, + "label": "Individual Topic" + } + } + }, + "Call To Action": { + "ctabackground": { + "type": "Image", + "config": { + "constraint": {}, + "thumbnails": [], + "label": "ctaBackground" + } + }, + "cta_heading": { + "type": "Text", + "config": { + "label": "CTA Heading" + } + }, + "cta_button_text": { + "type": "Text", + "config": { + "label": "CTA Button Text" + } + }, + "cta_button_destination": { + "type": "Link", + "config": { + "label": "CTA Button Destination" + } + } + } +} diff --git a/src/style/colors.js b/src/style/colors.js index caf71eb..929e416 100644 --- a/src/style/colors.js +++ b/src/style/colors.js @@ -8,12 +8,13 @@ const colors = { white900: "#FFFFFF", orange900: "#F27A28", + orange900_transparent: "rgb(242, 106, 33, .07)", blue900: "#245373", lightblue900: "#6480A5", lighterblue900: "#6EA8C0", softblue900: "#ECF3F7", gray900: "#585858", - black_overlay: "rgb(0, 0, 0, 0.55)" + black_overlay: "rgb(0, 0, 0, 0.55)", } -export default colors \ No newline at end of file +export default colors diff --git a/src/style/type-styles.js b/src/style/type-styles.js index 17cc5c0..8a8e277 100644 --- a/src/style/type-styles.js +++ b/src/style/type-styles.js @@ -4,6 +4,7 @@ const minSize = { h1: 50, h2: 30, h3: 20, + h4: 20, p: 16, nav: 16, sub1: 25, @@ -22,6 +23,7 @@ const fontSizes = { h1: `calc(${minSize.h1}px + (64 - ${minSize.h1}) * ((100vw - ${devices.mobile}px) / (${devices.desktop} - ${devices.mobile})))`, h2: `calc(${minSize.h2}px + (48 - ${minSize.h2}) * ((100vw - ${devices.mobile}px) / (${devices.desktop} - ${devices.mobile})))`, h3: `calc(${minSize.h3}px + (32 - ${minSize.h3}) * ((100vw - ${devices.mobile}px) / (${devices.desktop} - ${devices.mobile})))`, + h4: `calc(${minSize.h4}px + (22 - ${minSize.h4}) * ((100vw - ${devices.mobile}px) / (${devices.desktop} - ${devices.mobile})))`, p: `calc(${minSize.p}px + (24 - ${minSize.p}) * ((100vw - ${devices.mobile}px) / (${devices.desktop} - ${devices.mobile})))`, NavText: `calc(${minSize.nav}px + (24 - ${minSize.nav}) * ((100vw - ${devices.mobile}px) / (${devices.desktop} - ${devices.mobile})))`, Sub1: `calc(${minSize.sub1}px + (36 - ${minSize.sub1}) * ((100vw - ${devices.mobile}px) / (${devices.desktop} - ${devices.mobile})))`, @@ -43,6 +45,11 @@ const H3 = styled.h3` font-weight: bold; ` +const H4 = styled.h4` + font-size: ${fontSizes.h4}; + font-weight: bold; +` + const P = styled.p` font-size: ${fontSizes.p}; ` @@ -60,4 +67,4 @@ const Body = styled.div` font-size: ${fontSizes.body}; ` -export { H1, H2, H3, P, NavText, Sub1, Body } +export { H1, H2, H3, H4, P, NavText, Sub1, Body, fontSizes } diff --git a/src/vectors/close.svg b/src/vectors/close.svg new file mode 100644 index 0000000..c3cf8cd --- /dev/null +++ b/src/vectors/close.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/vectors/open.svg b/src/vectors/open.svg new file mode 100644 index 0000000..733b2d2 --- /dev/null +++ b/src/vectors/open.svg @@ -0,0 +1,5 @@ + + + + +