Skip to content

Commit

Permalink
setup a bunch of ssr infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
ecozoic committed Nov 8, 2018
1 parent 1f1c6cf commit ca75e52
Show file tree
Hide file tree
Showing 12 changed files with 493 additions and 20 deletions.
29 changes: 29 additions & 0 deletions components/Footer.jsx
@@ -0,0 +1,29 @@
import React from 'react';
import styled from 'styled-components';

// import FooterItem from './FooterItem';

const StyledFooter = styled.footer`
background-color: ${props => props.theme.colors.black};
border-top: 1px solid ${props => props.theme.colors.purple};
color: ${props => props.theme.colors.gray};
padding-bottom: 3rem;
`;

class Footer extends React.Component {
render() {
return (
<StyledFooter className="footer">
<div className="container">
<div className="columns">
{/*this.props.store.footer.sortedLinks.map(link => (
<FooterItem key={link.id} link={link} />
))*/}
</div>
</div>
</StyledFooter>
);
}
}

export default Footer;
141 changes: 141 additions & 0 deletions components/Header.jsx
@@ -0,0 +1,141 @@
import React from 'react';
import styled from 'styled-components';

import throttle from 'lodash.throttle';
import classnames from 'classnames';

// import SocialLink from './SocialLink';

const SCROLL_THROTTLE_MS = 100;
const SCROLL_THRESHOLD_PX = 80;

const Nav = styled.nav`
background-color: ${props =>
props.transparent ? 'transparent' : props.theme.colors.black};
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: ${props =>
props.transparent ? 'transparent' : props.theme.colors.purple};
transition: ${props => props.theme.transition.duration}
${props => props.theme.transition.easing};
`;

const LogoHeader = styled.h1`
display: none;
`;

const Logo = styled.img`
max-height: ${props => props.theme.scale.biggest}rem !important;
`;

const Burger = styled.div`
color: ${props =>
props.transparent
? props.theme.colors.blackTransparent
: props.theme.colors.white};
height: auto;
transition: all ${props => props.theme.transition.duration}
${props => props.theme.transition.easing};
&:hover {
color: ${props =>
props.transparent ? props.theme.colors.white : props.theme.colors.purple};
}
`;

const NavMenu = styled.div`
box-shadow: none;
@media screen and (max-width: 1087px) {
&.is-active {
background-color: ${props =>
props.transparent ? 'transparent' : props.theme.colors.purple};
display: inline-block;
position: absolute;
right: 0;
& .navbar-item > a {
color: ${props => props.theme.colors.black} !important;
&:hover {
color: ${props => props.theme.colors.white} !important;
}
}
}
}
`;

class Header extends React.Component {
state = {
scrollTop: 0,
burgerOpen: false,
};

componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
}

componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}

handleScroll = throttle(() => {
this.setState({
scrollTop: window.scrollY,
});
}, SCROLL_THROTTLE_MS);

handleBurgerClick = () => {
this.setState(prevState => ({
burgerOpen: !prevState.burgerOpen,
}));
};

render() {
const isTransparent = this.state.scrollTop <= SCROLL_THRESHOLD_PX;

return (
<Nav
transparent={isTransparent}
className="navbar is-fixed-top"
aria-label="main navigation"
>
<div className="navbar-brand">
<div className="navbar-item">
<Logo alt="logo" src="/static/logo.png" />
<LogoHeader>CLAVVS</LogoHeader>
</div>
<Burger
role="button"
className={classnames('navbar-burger', {
'is-active': this.state.burgerOpen,
})}
aria-label="menu"
aria-expanded="false"
transparent={isTransparent}
active={this.state.burgerOpen}
onClick={this.handleBurgerClick}
>
<span aria-hidden="true" />
<span aria-hidden="true" />
<span aria-hidden="true" />
</Burger>
</div>
<NavMenu
className={classnames('navbar-menu', {
'is-active': this.state.burgerOpen,
})}
transparent={isTransparent}
>
<div className="navbar-start" />
<div className="navbar-end">
{/* this.props.store.social.sortedLinks.map(link => (
<SocialLink
key={link.id}
link={link}
transparent={isTransparent}
/>
)) */}
</div>
</NavMenu>
</Nav>
);
}
}
export default Header;
47 changes: 47 additions & 0 deletions components/Hero.jsx
@@ -0,0 +1,47 @@
import React from 'react';
import styled from 'styled-components';

// import HeroButton from './HeroButton';

const HeroImage = styled.section`
background: url(/static/clavvs.jpg) no-repeat center / cover;
border-bottom: 1px solid ${props => props.theme.colors.purple};
@media (max-width: ${props => props.theme.breakpoints.desktop}) {
background-position-x: 75%;
}
@media (max-width: ${props => props.theme.breakpoints.mobile}) {
background-position-x: 60%;
}
`;

const ButtonContainer = styled.div`
display: flex;
justify-content: center;
& > a {
margin: ${props => props.theme.scale.bigger}rem;
@media (max-width: ${props => props.theme.breakpoints.mobile}) {
margin: ${props => props.theme.scale.smallest}rem;
padding: ${props => props.theme.scale.smallest}rem;
}
}
`;

class Hero extends React.Component {
render() {
return (
<HeroImage className="hero is-fullheight">
<div className="hero-head" />
<div className="hero-body" />
<div className="hero-foot">
<ButtonContainer className="container">
{/*this.props.store.hero.sortedLinks.map(link => (
<HeroButton key={link.id} link={link} />
))*/}
</ButtonContainer>
</div>
</HeroImage>
);
}
}

export default Hero;
22 changes: 22 additions & 0 deletions lib/analytics.js
@@ -0,0 +1,22 @@
import ReactGA from 'react-ga';

export const initGA = () => {
ReactGA.initialize('UA-77079907-1');
};

export const logPageView = () => {
ReactGA.set({ page: window.location.pathname });
ReactGA.pageview(window.location.pathname);
};

export const logEvent = (category = '', action = '') => {
if (category && action) {
ReactGA.event({ category, action });
}
};

export const logException = (description = '', fatal = false) => {
if (description) {
ReactGA.exception({ description, fatal });
}
};
54 changes: 54 additions & 0 deletions lib/theme.js
@@ -0,0 +1,54 @@
import color from 'color';

const black = '#13181d';
const purple = '#639';

export default {
colors: {
gray: '#666',
white: '#fff',
black,
blackTransparent: color(black)
.alpha(0.8)
.rgb()
.string(),
purple,
purpleTransparent: color(purple)
.alpha(0.25)
.rgb()
.string(),
},
font: {
family: '"Open Sans", sans-serif',
rootSize: '16px',
lineHeight: 1.5,
weights: {
light: 300,
regular: 400,
semibold: 600,
bold: 700,
xtrabold: 800,
},
},
scale: {
huge: 6.854,
biggest: 4.236,
bigger: 2.618,
big: 1.618,
normal: 1,
small: 0.618,
smaller: 0.382,
smallest: 0.236,
},
transition: {
duration: '.3s',
easing: 'ease-in-out',
},
breakpoints: {
mobile: '768px',
tablet: '769px',
desktop: '1024px',
widescreen: '1216px',
fullhd: '1408px',
},
};
7 changes: 7 additions & 0 deletions package.json
Expand Up @@ -12,9 +12,16 @@
"serve": "serve -p 8080 out"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.8",
"@fortawesome/free-solid-svg-icons": "^5.5.0",
"@fortawesome/react-fontawesome": "^0.1.3",
"classnames": "^2.2.6",
"color": "^3.1.0",
"lodash.throttle": "^4.1.1",
"next": "^7.0.2",
"react": "^16.6.1",
"react-dom": "^16.6.1",
"react-ga": "^2.5.3",
"styled-components": "^4.0.3"
},
"devDependencies": {
Expand Down
37 changes: 37 additions & 0 deletions pages/_app.js
@@ -0,0 +1,37 @@
import React from 'react';
import App, { Container } from 'next/app';
import Router from 'next/router';
import { ThemeProvider } from 'styled-components';

import theme from '../lib/theme';
import { initGA, logPageView } from '../lib/analytics';

export default class MyApp extends App {
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {};

if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}

return { pageProps };
}

componentDidMount() {
initGA();
logPageView();
Router.router.events.on('routeChangeComplete', logPageView);
}

render() {
const { Component, pageProps } = this.props;

return (
<Container>
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
</Container>
);
}
}

0 comments on commit ca75e52

Please sign in to comment.