diff --git a/gatsby-config.js b/gatsby-config.js index 303274a..dc2587a 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -16,6 +16,10 @@ module.exports = { family: `Oxygen`, variants: [`400`, `700`], }, + { + family: `Oxygen Mono`, + variants: [`400`], + }, { family: `Montserrat`, variants: [`400`, `700`], diff --git a/package-lock.json b/package-lock.json index 371755f..cd23d6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14123,6 +14123,14 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-particles-js": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/react-particles-js/-/react-particles-js-2.7.0.tgz", + "integrity": "sha512-gsYIr55plOMB6nZW2iBjgXoqOZqBvggW9trNTk0mYHkvqQUpuxhcCDGwRwnts10XQ442PjzxZbklwMlhSOcfgA==", + "requires": { + "lodash": "^4.17.11" + } + }, "react-perfect-scrollbar": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/react-perfect-scrollbar/-/react-perfect-scrollbar-1.5.3.tgz", diff --git a/package.json b/package.json index 8fa89d0..fbc6a5e 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "react-dom": "^16.8.6", "react-helmet": "^5.2.1", "react-highlight": "^0.12.0", + "react-particles-js": "^2.7.0", "react-perfect-scrollbar": "^1.5.3", "styled-components": "^4.3.2", "typescript": "^3.5.3" diff --git a/src/components/DiscordButton/index.tsx b/src/components/DiscordButton/index.tsx index 5a748e8..d6c692a 100644 --- a/src/components/DiscordButton/index.tsx +++ b/src/components/DiscordButton/index.tsx @@ -1,13 +1,11 @@ -import React from "react" +import React, { PropsWithChildren } from "react" +import * as SC from "./styles" -function DiscordButton({ - lined = false, - children, -}: React.PropsWithChildren<{ lined: boolean }>) { +function DiscordButton({ children }: PropsWithChildren<{}>) { return ( - + + {children} + ) } diff --git a/src/components/DiscordButton/styles.tsx b/src/components/DiscordButton/styles.tsx new file mode 100644 index 0000000..413da38 --- /dev/null +++ b/src/components/DiscordButton/styles.tsx @@ -0,0 +1,28 @@ +import styled from "styled-components" +import DiscordLogo from "../../images/discord-logo.svg" + +export const DiscordButtonWrapper = styled.div` + margin-top: 32px; + display: flex; + align-items: center; + font-family: "Oxygen", sans-serif; + font-size: 30px; + font-weight: 700; + text-transform: uppercase; + background: #7289da; + color: #fff; + padding: 22px 35px; + border-radius: 5px; + transition: background 0.3s; + cursor: pointer; + box-shadow: 0 3px 18px rgba(0, 0, 0, 0.3); + + &:hover { + background: #5265ad; + } +` + +export const StyledDiscordLogo = styled(DiscordLogo)` + width: 38px; + margin-right: 16px; +` diff --git a/src/components/Footer/styles.tsx b/src/components/Footer/styles.tsx index e73d4a5..9b6039b 100644 --- a/src/components/Footer/styles.tsx +++ b/src/components/Footer/styles.tsx @@ -4,5 +4,16 @@ import styled from "styled-components" export const FooterWrapper = styled.footer` & a { display: inline; + color: #0090d8; + font-weight: 700; + border-bottom: 2px solid; + text-decoration: none; + transition: color 0.3s; + + &:hover, + &:focus { + color: #5dbbea; + transition: none; + } } ` diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index e682f4e..47e96c3 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,35 +1,90 @@ import { Link } from "gatsby" -import React, { PropsWithChildren } from "react" -import logo from "../../images/tph-logo.png" -import { Container } from "../Container" +import React, { PropsWithChildren, useLayoutEffect, useState } from "react" +import DiscordButton from "../DiscordButton" +import { WavesBottom, WavesTop } from "../Waves" import * as SC from "./styles" +interface IHeaderProps { + isHome: boolean +} + function MenuItem({ children, to }: PropsWithChildren<{ to: string }>) { return ( - - {children} + + {children} + ) } -export function Header() { +export function Header({ isHome }: IHeaderProps) { + // Hack to force Particle.js to rerender + const [noop, setNoop] = useState(0) + useLayoutEffect(() => { + setNoop(prevState => prevState + 1) + }, [isHome]) + return ( - - - + + + + + + + + + - + - - about - rules - faq - hotbot - resources - tech spotlight - - - + The Programmer's Hangout + + + about + rules + faq + hotbot + resources + tech spotlight + + join us + ) } diff --git a/src/components/Header/styles.tsx b/src/components/Header/styles.tsx index 3f4efae..c55225f 100644 --- a/src/components/Header/styles.tsx +++ b/src/components/Header/styles.tsx @@ -1,81 +1,191 @@ import { Link } from "gatsby" +import Particles from "react-particles-js" import styled from "styled-components" +import TPHLogo from "../../images/tph-logo.svg" export const HeaderWrapper = styled.header` - margin-bottom: 20px; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + position: relative; + min-height: auto; + background: #121240; + overflow: hidden; + + &.is-home { + min-height: 100vh; + } +` + +export const TitleWrapper = styled.div` + display: flex; + align-items: center; + margin-bottom: 22px; + + .is-home & { + flex-direction: column; + align-items: flex-start; + } +` + +export const Title = styled.h1` + margin: 0; + font-weight: 700; + font-size: 50px; + text-transform: uppercase; + line-height: 1; + color: #fff; + text-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); + + .is-home & { + margin: 32px 0; + font-size: 110px; + + @media screen and (max-width: 991px) { + font-size: 72px; + } + + @media screen and (max-width: 767px) { + font-size: 40px; + } + } +` + +export const FadedBottomWave = styled.div` + position: absolute; + transform: translateY(100%); + bottom: 0; + left: 0; + right: 0; + transition: opacity 0.5s, transform 0.5s; + opacity: 0; + + svg { + position: static; + } + + .is-home & { + opacity: 1; + transform: translateY(0); + } + + .is-home & svg { + position: static; + } +` + +export const StyledParticles = styled(Particles)` + mask-image: -webkit-linear-gradient( + top, + rgba(0, 0, 0, 0) 5%, + rgba(0, 0, 0, 1) 25%, + rgba(0, 0, 0, 1) 75%, + rgba(0, 0, 0, 0) 95% + ); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; ` export const InnerWrapper = styled.div` + width: 800px; + max-width: calc(100% - 64px); + padding: 32px; position: relative; display: flex; - align-items: center; + align-items: flex-start; flex-direction: column; ` -export const Logo = styled.img` - width: 122px; - height: 122px; - margin-bottom: 10px; +export const Logo = styled(TPHLogo)` + width: 70px; + margin: 0 15px 0 0; + position: relative; + z-index: 3; + + .is-home & { + width: 122px; + margin-bottom: 0 0 10px 0; + } ` export const Menu = styled.nav` display: flex; - align-items: flex-start; - justify-content: center; + justify-content: flex-start; flex-wrap: wrap; ` +export const MenuItemText = styled.div` + position: relative; + z-index: 5; +` + +/* underline bar, getting animated through hover */ +export const MenuItemLine = styled.div` + position: absolute; + z-index: 4; + height: 2px; + width: 100%; + margin-top: -3px; + bottom: 0; + background: #fff; + transition: all 0.3s; +` + export const MenuItem = styled(Link)` display: flex; align-items: center; font-size: 22px; text-decoration: none; - color: #555; + color: #fff; position: relative; transition: color 0.3s; - margin: 5px 10px; - - /* underline bar, getting animated through hover */ - &::after { - z-index: -1; - position: absolute; - content: ""; - height: 2px; - width: 100%; - margin-top: -3px; - bottom: 0; - background: #555; - transition: all 0.3s; - } + margin: 10px 20px 5px 0; + font-family: "Oxygen Mono"; &:hover { color: #fff; } - &:hover::after { + &:hover ${MenuItemLine} { padding: 8px; height: 100%; - background: #000; + background: #cf2e7d; box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1), 0 5px 11px rgba(0, 0, 0, 0.25); margin-left: -8px; margin-bottom: -8px; border-radius: 3px; } + &.disabled { + cursor: default; + pointer-events: none; + opacity: 0.7; + color: #fff !important; + } + + &.disabled ${MenuItemLine} { + bottom: 50%; + background: #fff !important; + } + &.active { font-weight: 700; - color: #d33636; + color: #cf2e7d; - &::after { - background: #d33636; + ${MenuItemLine} { + background: #cf2e7d; } &:hover { color: #fff; } - &:hover::after { - background: #d33636; + &:hover ${MenuItemLine} { + background: #cf2e7d; } } ` diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index bcb94c3..c899a70 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -6,15 +6,20 @@ */ import { graphql, useStaticQuery } from "gatsby" -import React, { PropsWithChildren } from "react" +import React, { Fragment, PropsWithChildren } from "react" import { GlobalStyles } from "../../globalStyles" import { Container } from "../Container" import { Footer } from "../Footer" import { Header } from "../Header" +import { WavesBottom } from "../Waves" import * as SC from "./styles" -export function Layout({ children }: PropsWithChildren<{}>) { +export function Layout({ + children, + location, +}: PropsWithChildren<{ location: Location }>) { + const isHome = location.pathname === "/" const data = useStaticQuery(graphql` query { site { @@ -28,14 +33,17 @@ export function Layout({ children }: PropsWithChildren<{}>) { return ( -
- - -

{data.site.siteMetadata.title}

- {children} -
-
-