init
This commit is contained in:
75
src/components/footer/index.tsx
Normal file
75
src/components/footer/index.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
|
||||
// import dcLogo from "../../images/dclogo.png";
|
||||
|
||||
import { Container, Section } from '../shared'
|
||||
import { SolidButton } from '../shared/styledComponents'
|
||||
import { StyledHeading, StyledDesc, InputStyled, StyledAnchor } from './style'
|
||||
|
||||
const anchorStyles = {
|
||||
color: '#888'
|
||||
}
|
||||
|
||||
const Footer = () => (
|
||||
<Section bottomArrow={false}>
|
||||
<div className="row">
|
||||
<div className="col-md-3 me-md-5">
|
||||
<StyledHeading>Data Controller</StyledHeading>
|
||||
<StyledDesc>
|
||||
Data Controller is a product of 4GL Apps, a brand of Bowe IO Ltd,
|
||||
which is a UK company with a focus on SAS Software,{' '}
|
||||
<StyledAnchor href="https://sasapps.io">Apps</StyledAnchor>, and
|
||||
Services.
|
||||
</StyledDesc>
|
||||
</div>
|
||||
<div className="col-md-3">
|
||||
<StyledHeading>Newsletter</StyledHeading>
|
||||
<form
|
||||
className="kwes-form"
|
||||
method="POST"
|
||||
action="https://kwes.io/api/foreign/forms/mxKuyK4lxZWnG2WNH3ga"
|
||||
>
|
||||
<div className="mb-3">
|
||||
<InputStyled
|
||||
type="email"
|
||||
name="email"
|
||||
className="form-control"
|
||||
aria-describedby="emailHelp"
|
||||
placeholder="Email Address*"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<InputStyled
|
||||
type="text"
|
||||
name="name"
|
||||
className="form-control"
|
||||
placeholder="First Name"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<InputStyled
|
||||
type="text"
|
||||
name="lastName"
|
||||
className="form-control"
|
||||
placeholder="Last Name"
|
||||
/>
|
||||
</div>
|
||||
<SolidButton>Subscribe</SolidButton>
|
||||
</form>
|
||||
</div>
|
||||
<div className="col-md-3">
|
||||
<StyledHeading>Other Resources</StyledHeading>
|
||||
<StyledDesc>
|
||||
Visit our educational and fun SAS® software quiz{' '}
|
||||
<StyledAnchor href="https://sasensei.com">Sasensei</StyledAnchor> and
|
||||
test your knowledge of SAS topics.
|
||||
</StyledDesc>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
|
||||
export default Footer
|
40
src/components/footer/style.js
Normal file
40
src/components/footer/style.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
export const StyledHeading = styled.h6`
|
||||
margin-bottom: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
color: #888;
|
||||
`
|
||||
export const StyledDesc = styled.p`
|
||||
color: #aaaaaa;
|
||||
font-size: 0.9rem;
|
||||
`
|
||||
|
||||
export const InputStyled = styled.input`
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 0.9rem;
|
||||
&:focus {
|
||||
color: inherit;
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
`
|
||||
|
||||
const Anchor = styled.a`
|
||||
color: #d4d4d4;
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
`
|
||||
|
||||
export const StyledAnchor = ({ children, href }) => (
|
||||
<Anchor href={href} target="_blank" rel="noopener">
|
||||
{children}
|
||||
</Anchor>
|
||||
)
|
37
src/components/herosection/index.tsx
Normal file
37
src/components/herosection/index.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import React from 'react'
|
||||
import { PageProps, Link } from 'gatsby'
|
||||
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { Hero, HeroHeading, HeroDesc } from './style'
|
||||
import { BottomSectionArrow, OutlineButton } from '../shared/styledComponents'
|
||||
import { Container } from '../shared'
|
||||
|
||||
import { pathPrefix } from '../../../gatsby-config.js'
|
||||
|
||||
type DataProps = {
|
||||
location: Location
|
||||
heading: string
|
||||
desc: string
|
||||
}
|
||||
|
||||
const HeroSection: React.FC<PageProps<DataProps>> = ({
|
||||
location,
|
||||
heading,
|
||||
desc
|
||||
}) => (
|
||||
<Hero bg={location.pathname === pathPrefix + '/'}>
|
||||
<Container>
|
||||
<HeroHeading>{heading}</HeroHeading>
|
||||
<HeroDesc>{desc}</HeroDesc>
|
||||
{location.pathname === pathPrefix + '/' && (
|
||||
<Link to="/contact/">
|
||||
<OutlineButton>Try Data Controller</OutlineButton>
|
||||
</Link>
|
||||
)}
|
||||
</Container>
|
||||
<BottomSectionArrow />
|
||||
</Hero>
|
||||
)
|
||||
|
||||
export default HeroSection
|
23
src/components/herosection/style.js
Normal file
23
src/components/herosection/style.js
Normal file
@ -0,0 +1,23 @@
|
||||
import styled from 'styled-components'
|
||||
import background from '../../images/home_hero_bg.png'
|
||||
|
||||
export const Hero = styled.main`
|
||||
position: relative;
|
||||
padding: 50px 0;
|
||||
color: white;
|
||||
background-color: #314351;
|
||||
background-repeat: no-repeat;
|
||||
background-image: ${(props) => (props.bg ? `url(${background})` : 'none')};
|
||||
background-attachment: scroll;
|
||||
background-position: bottom right;
|
||||
`
|
||||
|
||||
export const HeroHeading = styled.h1`
|
||||
font-family: 'Montserrat', 'HelveticaNeue', 'Helvetica Neue', Helvetica, Arial,
|
||||
sans-serif;
|
||||
text-transform: uppercase;
|
||||
`
|
||||
|
||||
export const HeroDesc = styled.p`
|
||||
opacity: 0.8;
|
||||
`
|
41
src/components/layout.tsx
Normal file
41
src/components/layout.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { PageProps } from 'gatsby'
|
||||
|
||||
import Navibar from './navibar'
|
||||
import HeroSection from './herosection'
|
||||
import Footer from './footer'
|
||||
|
||||
type DataProps = {
|
||||
children?: React.ReactNode
|
||||
heroSection: boolean
|
||||
}
|
||||
|
||||
const Layout: React.FC<PageProps<DataProps>> = ({
|
||||
location,
|
||||
children,
|
||||
heroSection = true,
|
||||
heading,
|
||||
desc
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
if (document.querySelector('script[data-name="kwes-script"]')) return
|
||||
|
||||
const kwesScript = document.createElement('script')
|
||||
kwesScript.setAttribute('rel', 'noopener')
|
||||
kwesScript.setAttribute('src', 'https://kwes.io/v2/kwes-script.js')
|
||||
kwesScript.setAttribute('data-name', 'kwes-script')
|
||||
document.head.appendChild(kwesScript)
|
||||
})
|
||||
return (
|
||||
<>
|
||||
<Navibar location={location} />
|
||||
{heroSection && (
|
||||
<HeroSection location={location} heading={heading} desc={desc} />
|
||||
)}
|
||||
{children}
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
105
src/components/navibar/index.tsx
Normal file
105
src/components/navibar/index.tsx
Normal file
@ -0,0 +1,105 @@
|
||||
import React from 'react'
|
||||
import { Link, PageProps } from 'gatsby'
|
||||
|
||||
import dcLogo from '../../images/dclogo.png'
|
||||
|
||||
import { Container } from '../shared'
|
||||
import { logoStyles, CustomNavBar, ulStyles, Li, StyledLink } from './style'
|
||||
|
||||
import { pathPrefix } from '../../../gatsby-config.js'
|
||||
|
||||
const naviLinks = [
|
||||
{
|
||||
name: 'Home',
|
||||
url: '/',
|
||||
active: 'no'
|
||||
},
|
||||
{
|
||||
name: 'About',
|
||||
url: '/about/',
|
||||
active: 'no'
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
url: '/blog/',
|
||||
active: 'no'
|
||||
},
|
||||
{
|
||||
name: 'FAQ',
|
||||
url: '/faq/',
|
||||
active: 'no'
|
||||
},
|
||||
{
|
||||
name: 'Documentation',
|
||||
url: 'https://docs.datacontroller.io/',
|
||||
active: 'no'
|
||||
},
|
||||
{
|
||||
name: 'Pricing',
|
||||
url: '/pricing/',
|
||||
active: 'no'
|
||||
},
|
||||
{
|
||||
name: 'Book Demo',
|
||||
url: '/contact/',
|
||||
active: 'no'
|
||||
},
|
||||
{
|
||||
name: 'Source Code',
|
||||
url: 'https://git.datacontroller.io/dc/dc',
|
||||
active: 'no'
|
||||
}
|
||||
]
|
||||
|
||||
type DataProps = {
|
||||
location: Location
|
||||
}
|
||||
|
||||
const Navibar: React.FC<PageProps<DataProps>> = ({ location }) => {
|
||||
naviLinks.forEach((link) => (link.active = 'no'))
|
||||
const currentLink = naviLinks.find(
|
||||
(link) => pathPrefix + link.url === location?.pathname
|
||||
)
|
||||
if (currentLink) currentLink.active = 'yes'
|
||||
return (
|
||||
<CustomNavBar className="navbar navbar-expand-lg">
|
||||
<Container>
|
||||
<Link to="/">
|
||||
<img src={dcLogo} style={logoStyles} alt="Data Controller Logo" />
|
||||
</Link>
|
||||
<button
|
||||
className="navbar-toggler collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbarSupportedContent"
|
||||
aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<div className="navbar-toggler-icon" id="nav-icon4">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</button>
|
||||
<div className="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul className="navbar-nav mb-2 mb-lg-0" style={ulStyles}>
|
||||
{naviLinks.map((link, index) => (
|
||||
<Li key={index} className="nav-item">
|
||||
<StyledLink
|
||||
to={link.url}
|
||||
className="nav-link"
|
||||
active={link.active}
|
||||
>
|
||||
{link.name}
|
||||
</StyledLink>
|
||||
</Li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</Container>
|
||||
</CustomNavBar>
|
||||
)
|
||||
}
|
||||
|
||||
export default Navibar
|
333
src/components/navibar/style.js
Normal file
333
src/components/navibar/style.js
Normal file
@ -0,0 +1,333 @@
|
||||
import React from 'react'
|
||||
import styled, { css } from 'styled-components'
|
||||
import { Link } from 'gatsby'
|
||||
|
||||
// styles
|
||||
export const logoStyles = {
|
||||
height: '55px'
|
||||
}
|
||||
export const ulStyles = {
|
||||
marginLeft: 'auto'
|
||||
}
|
||||
|
||||
export const CustomNavBar = styled.nav`
|
||||
padding: 0;
|
||||
background-color: #314351;
|
||||
color: white;
|
||||
font-size: 0.85rem;
|
||||
|
||||
/* Icon 1 */
|
||||
#nav-icon1,
|
||||
#nav-icon2,
|
||||
#nav-icon3,
|
||||
#nav-icon4 {
|
||||
width: 60px;
|
||||
height: 45px;
|
||||
position: relative;
|
||||
margin: 10px auto;
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
-webkit-transition: 0.5s ease-in-out;
|
||||
-moz-transition: 0.5s ease-in-out;
|
||||
-o-transition: 0.5s ease-in-out;
|
||||
transition: 0.5s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#nav-icon1 span,
|
||||
#nav-icon3 span,
|
||||
#nav-icon4 span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 9px;
|
||||
width: 100%;
|
||||
background: #79a843;
|
||||
border-radius: 9px;
|
||||
opacity: 1;
|
||||
left: 0;
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
-webkit-transition: 0.25s ease-in-out;
|
||||
-moz-transition: 0.25s ease-in-out;
|
||||
-o-transition: 0.25s ease-in-out;
|
||||
transition: 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
#nav-icon1 span:nth-child(1) {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#nav-icon1 span:nth-child(2) {
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
#nav-icon1 span:nth-child(3) {
|
||||
top: 36px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon1 span:nth-child(1) {
|
||||
top: 18px;
|
||||
-webkit-transform: rotate(135deg);
|
||||
-moz-transform: rotate(135deg);
|
||||
-o-transform: rotate(135deg);
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon1 span:nth-child(2) {
|
||||
opacity: 0;
|
||||
left: -60px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon1 span:nth-child(3) {
|
||||
top: 18px;
|
||||
-webkit-transform: rotate(-135deg);
|
||||
-moz-transform: rotate(-135deg);
|
||||
-o-transform: rotate(-135deg);
|
||||
transform: rotate(-135deg);
|
||||
}
|
||||
|
||||
/* Icon 2 */
|
||||
|
||||
#nav-icon2 {
|
||||
}
|
||||
|
||||
#nav-icon2 span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 9px;
|
||||
width: 50%;
|
||||
background: #d3531a;
|
||||
opacity: 1;
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
-webkit-transition: 0.25s ease-in-out;
|
||||
-moz-transition: 0.25s ease-in-out;
|
||||
-o-transition: 0.25s ease-in-out;
|
||||
transition: 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
#nav-icon2 span:nth-child(even) {
|
||||
left: 50%;
|
||||
border-radius: 0 9px 9px 0;
|
||||
}
|
||||
|
||||
#nav-icon2 span:nth-child(odd) {
|
||||
left: 0px;
|
||||
border-radius: 9px 0 0 9px;
|
||||
}
|
||||
|
||||
#nav-icon2 span:nth-child(1),
|
||||
#nav-icon2 span:nth-child(2) {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#nav-icon2 span:nth-child(3),
|
||||
#nav-icon2 span:nth-child(4) {
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
#nav-icon2 span:nth-child(5),
|
||||
#nav-icon2 span:nth-child(6) {
|
||||
top: 36px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(1),
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(6) {
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(2),
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(5) {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-o-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(1) {
|
||||
left: 5px;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(2) {
|
||||
left: calc(50% - 5px);
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(3) {
|
||||
left: -50%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(4) {
|
||||
left: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(5) {
|
||||
left: 5px;
|
||||
top: 29px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon2 span:nth-child(6) {
|
||||
left: calc(50% - 5px);
|
||||
top: 29px;
|
||||
}
|
||||
|
||||
/* Icon 3 */
|
||||
|
||||
#nav-icon3 span:nth-child(1) {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#nav-icon3 span:nth-child(2),
|
||||
#nav-icon3 span:nth-child(3) {
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
#nav-icon3 span:nth-child(4) {
|
||||
top: 36px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon3 span:nth-child(1) {
|
||||
top: 18px;
|
||||
width: 0%;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon3 span:nth-child(2) {
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon3 span:nth-child(3) {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-o-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon3 span:nth-child(4) {
|
||||
top: 18px;
|
||||
width: 0%;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
/* Icon 4 */
|
||||
|
||||
#nav-icon4 {
|
||||
}
|
||||
|
||||
#nav-icon4 span:nth-child(1) {
|
||||
top: 0px;
|
||||
-webkit-transform-origin: left center;
|
||||
-moz-transform-origin: left center;
|
||||
-o-transform-origin: left center;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
#nav-icon4 span:nth-child(2) {
|
||||
top: 18px;
|
||||
-webkit-transform-origin: left center;
|
||||
-moz-transform-origin: left center;
|
||||
-o-transform-origin: left center;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
#nav-icon4 span:nth-child(3) {
|
||||
top: 36px;
|
||||
-webkit-transform-origin: left center;
|
||||
-moz-transform-origin: left center;
|
||||
-o-transform-origin: left center;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon4 span:nth-child(1) {
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
top: -3px;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon4 span:nth-child(2) {
|
||||
width: 0%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.navbar-toggler:not(.collapsed) #nav-icon4 span:nth-child(3) {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-o-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
top: 39px;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
padding: 0;
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const LinkUnderlineStyles = css`
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: calc(100% - 1.6rem);
|
||||
height: 2px;
|
||||
bottom: 0;
|
||||
background: white;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s ease;
|
||||
`
|
||||
|
||||
// styled components
|
||||
export const Li = styled.li`
|
||||
position: relative;
|
||||
@media (min-width: 992px) {
|
||||
&:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
top: 25%;
|
||||
right: 0;
|
||||
background: white;
|
||||
}
|
||||
&:nth-last-child(1) {
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
export const StyledLink = styled((props) => <Link {...props} />)`
|
||||
padding-right: 0.8rem !important;
|
||||
padding-left: 0.8rem !important;
|
||||
color: white;
|
||||
|
||||
&:before {
|
||||
${LinkUnderlineStyles}
|
||||
opacity: ${(props) => (props.active === 'yes' ? '1' : 0)};
|
||||
}
|
||||
&:hover {
|
||||
color: white;
|
||||
&:before {
|
||||
${LinkUnderlineStyles}
|
||||
}
|
||||
}
|
||||
`
|
80
src/components/seo.tsx
Normal file
80
src/components/seo.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
import * as React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useStaticQuery, graphql } from 'gatsby'
|
||||
|
||||
const Seo = ({ description, lang, meta, title, previewImg = undefined }) => {
|
||||
const { site } = useStaticQuery(graphql`
|
||||
query {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
description
|
||||
siteUrl
|
||||
author {
|
||||
name
|
||||
}
|
||||
social {
|
||||
linkedin
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
const author = site.siteMetadata?.author?.name
|
||||
const metaDescription = description || site.siteMetadata.description
|
||||
const defaultTitle = site.siteMetadata?.title
|
||||
const pageTitle = title ? `${title} | ${defaultTitle}` : defaultTitle
|
||||
const siteUrl = site.siteMetadata?.siteUrl
|
||||
const image = previewImg
|
||||
? `${siteUrl}${previewImg}`
|
||||
: `${siteUrl}/img/data-controller.svg`
|
||||
|
||||
return (
|
||||
<Helmet
|
||||
htmlAttributes={{
|
||||
lang
|
||||
}}
|
||||
title={pageTitle}
|
||||
meta={[
|
||||
{ name: 'author', property: 'author', content: author },
|
||||
{
|
||||
name: 'description',
|
||||
property: 'og:description',
|
||||
content: metaDescription
|
||||
},
|
||||
// { name: 'facebook:site', content: '', },
|
||||
{ name: 'image', property: 'og:image', content: image },
|
||||
{
|
||||
name: `linkedin:site`,
|
||||
content: site.siteMetadata?.social?.linkedin || ``
|
||||
},
|
||||
{ name: `twitter:card`, content: `summary` },
|
||||
// { name: `twitter:creator`, content: site.siteMetadata?.social?.twitter || `` },
|
||||
{ name: `twitter:description`, content: metaDescription },
|
||||
// { name: 'twitter:site', content: `${site?.twitter}`, },
|
||||
{ name: `twitter:title`, content: title },
|
||||
// { name: 'youtube:site', content: `${site?.youtube}`, },
|
||||
{ property: `og:title`, content: title },
|
||||
{ property: `og:type`, content: `website` }
|
||||
].concat(meta)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Seo.defaultProps = {
|
||||
lang: `en`,
|
||||
meta: [],
|
||||
description: ``,
|
||||
title: ``
|
||||
}
|
||||
|
||||
Seo.propTypes = {
|
||||
description: PropTypes.string,
|
||||
lang: PropTypes.string,
|
||||
meta: PropTypes.arrayOf(PropTypes.object),
|
||||
title: PropTypes.string
|
||||
}
|
||||
|
||||
export default Seo
|
18
src/components/shared/container.tsx
Normal file
18
src/components/shared/container.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { PageProps } from 'gatsby'
|
||||
|
||||
type DataProps = {
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
@media (min-width: 576px) {
|
||||
max-width: 1310px;
|
||||
padding: 0px 50px;
|
||||
}
|
||||
`
|
||||
|
||||
export const Container: React.FC<PageProps<DataProps>> = ({ children }) => {
|
||||
return <StyledDiv className="container">{children}</StyledDiv>
|
||||
}
|
3
src/components/shared/index.ts
Normal file
3
src/components/shared/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export { Container } from './container'
|
||||
export { Section } from './section'
|
||||
export { ScheduleDemo } from './scheduleDemo'
|
53
src/components/shared/scheduleDemo.tsx
Normal file
53
src/components/shared/scheduleDemo.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { FaEnvelope } from 'react-icons/fa'
|
||||
|
||||
export const StyledLink = styled((props) => <Link {...props} />)`
|
||||
color: rgb(255, 255, 255);
|
||||
background-color: rgb(144, 196, 69);
|
||||
border-radius: 0px;
|
||||
padding: 50px 10px;
|
||||
width: 100%;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
position: relative;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
font-size: 1.3rem;
|
||||
line-height: 1.2em;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
font-family: Montserrat, HelveticaNeue, 'Helvetica Neue', Helvetica, Arial;
|
||||
|
||||
svg {
|
||||
opacity: 0;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
&:hover {
|
||||
color: white;
|
||||
background-color: #314351;
|
||||
svg {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
transition: all 0.3s ease;
|
||||
`
|
||||
|
||||
const iconStyles = { marginTop: '-2px', marginLeft: '5px' }
|
||||
const textStyles = { opacity: '0.7', fontSize: '1rem', margin: '12px auto 0' }
|
||||
|
||||
export const ScheduleDemo = () => {
|
||||
return (
|
||||
<StyledLink to="/contact">
|
||||
<span>
|
||||
Schedule a Free Demo <FaEnvelope size={18} style={iconStyles} />
|
||||
</span>
|
||||
<p style={textStyles}>
|
||||
Contact us for a free demonstration of Data Controller.
|
||||
</p>
|
||||
</StyledLink>
|
||||
)
|
||||
}
|
34
src/components/shared/section.tsx
Normal file
34
src/components/shared/section.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { PageProps } from 'gatsby'
|
||||
import { BottomSectionArrow } from './styledComponents'
|
||||
import { Container } from './'
|
||||
|
||||
type DataProps = {
|
||||
children?: React.ReactNode
|
||||
color?: string
|
||||
bgColor?: string
|
||||
bottomArrow?: boolean
|
||||
}
|
||||
|
||||
const StyledSection = styled.div`
|
||||
position: relative;
|
||||
padding: 50px 0;
|
||||
color: ${(props) => props.color || 'white'};
|
||||
background-color: ${(props) => props.bgColor || '#314351'};
|
||||
`
|
||||
|
||||
export const Section: React.FC<PageProps<DataProps>> = ({
|
||||
children,
|
||||
bgColor,
|
||||
color,
|
||||
bottomArrow = true
|
||||
}) => {
|
||||
return (
|
||||
<StyledSection bgColor={bgColor} color={color}>
|
||||
<Container>{children}</Container>
|
||||
{bottomArrow && <BottomSectionArrow />}
|
||||
</StyledSection>
|
||||
)
|
||||
}
|
88
src/components/shared/styledComponents.js
Normal file
88
src/components/shared/styledComponents.js
Normal file
@ -0,0 +1,88 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const BottomArrow = styled.div`
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
background: inherit;
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
left: 50%;
|
||||
// right: 0;
|
||||
// margin-left: auto;
|
||||
// margin-right: auto;
|
||||
z-index: 10;
|
||||
`
|
||||
const BottomArrowWrapper = styled.div`
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
margin-top: 50px;
|
||||
background-color: inherit;
|
||||
`
|
||||
|
||||
export const BottomSectionArrow = () => (
|
||||
<BottomArrowWrapper>
|
||||
<BottomArrow />
|
||||
</BottomArrowWrapper>
|
||||
)
|
||||
|
||||
export const SectionHeading = styled.h2`
|
||||
text-align: ${(props) => (props.center === 'no' ? 'left' : 'center')};
|
||||
letter-spacing: 1px;
|
||||
font-weight: 400;
|
||||
font-family: 'Montserrat', 'HelveticaNeue', 'Helvetica Neue', Helvetica, Arial,
|
||||
sans-serif;
|
||||
text-transform: uppercase;
|
||||
`
|
||||
|
||||
export const SectionDesc = styled.p`
|
||||
text-align: ${(props) => (props.center === 'no' ? 'left' : 'center')};
|
||||
opacity: ${(props) => props.opacity ?? 0.6};
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
`
|
||||
const StyledSolidButton = styled.button`
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 0.75rem;
|
||||
border-width: 2px;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
&.btn-dark {
|
||||
background-color: #2e4252;
|
||||
}
|
||||
`
|
||||
|
||||
export const SolidButton = ({
|
||||
children,
|
||||
theme = 'light',
|
||||
type = 'submit',
|
||||
onClick = undefined
|
||||
}) => (
|
||||
<StyledSolidButton
|
||||
type={type}
|
||||
className={`btn btn-${theme}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</StyledSolidButton>
|
||||
)
|
||||
|
||||
const StyledOutlineButton = styled.button`
|
||||
margin: 50px 0;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 0.75rem;
|
||||
border-width: 2px;
|
||||
`
|
||||
|
||||
export const OutlineButton = ({ children }) => (
|
||||
<StyledOutlineButton type="button" className="btn btn-outline-light">
|
||||
{children}
|
||||
</StyledOutlineButton>
|
||||
)
|
Reference in New Issue
Block a user