diff --git a/gatsby-config.js b/gatsby-config.js
index 5065438..1329ae2 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -5,7 +5,42 @@ module.exports = {
title: `Abc Project Design`,
description: `Easy as ABC`,
keywords: `Foo bar baz`,
- navData: [],
+ navData: [
+ {
+ title: "Home",
+ to: "/"
+ },
+ {
+ title: "Services",
+ to: "/services",
+ subNav: [
+ {
+ title: "Bathrooms",
+ to: "/services/bathrooms"
+ },
+ {
+ title: "Tiling",
+ to: "/services/tiling"
+ },
+ {
+ title: "Electrics",
+ to: "/services/electrics"
+ },
+ {
+ title: "Carpentry",
+ to: "/services/carpentry"
+ }
+ ]
+ },
+ {
+ title: "About",
+ to: "/about"
+ },
+ {
+ title: "Contact",
+ to: "/contact"
+ }
+ ],
reviews: [
{
name: "Rated People",
diff --git a/src/components/card.js b/src/components/card.js
index 4b80755..b2af622 100644
--- a/src/components/card.js
+++ b/src/components/card.js
@@ -1,11 +1,11 @@
import React from "react";
+import { Link as GatsbyLink } from "gatsby";
import Img from "gatsby-image";
import styled from "styled-components";
const Container = styled.div`
display: flex;
align-items: center;
- overflow: hidden;
margin: 0 calc(var(--spacing-x-xs) * -1) var(--spacing-y-sm);
@media (max-width: 30em) {
@@ -15,15 +15,34 @@ const Container = styled.div`
}
`;
-const Media = styled.div`
+const Media = styled.span`
padding: 0 var(--spacing-x-xs);
+ transition: transform 0.15s ease-in, filter 0.15s ease-in;
`;
-const Content = styled.div`
+
+const Content = styled.span`
padding: 0 var(--spacing-x-xs);
`;
-export default function Card({ image, children }) {
- return (
+const Link = styled(GatsbyLink)`
+ outline: 0;
+ text-decoration: none;
+ color: var(--color-black);
+
+ &:hover ${Media} {
+ transform: scale(1.1);
+ filter: brightness(110%) contrast(110%);
+ }
+
+ @media (max-width: 30em) {
+ &:nth-child(even) ${Container} {
+ flex-direction: row-reverse;
+ }
+ }
+`;
+
+export default function Card({ image, children, to }) {
+ const render = () => (
{image && (
@@ -39,4 +58,5 @@ export default function Card({ image, children }) {
{children}
);
+ return to ? {render()} : render();
}
diff --git a/src/components/footer.js b/src/components/footer.js
index e77daee..c3e37e8 100644
--- a/src/components/footer.js
+++ b/src/components/footer.js
@@ -10,6 +10,7 @@ const Content = styled.div`
max-width: var(--theme-max-width);
margin: 0 auto;
padding: var(--spacing-y-lg) var(--spacing-x-sm);
+ font-size: var(--font-size-sm);
text-align: center;
`;
diff --git a/src/components/header-logo.js b/src/components/header-logo.js
index 075a6a6..8076bed 100644
--- a/src/components/header-logo.js
+++ b/src/components/header-logo.js
@@ -79,7 +79,7 @@ const Slogan = styled.p`
export default function HeaderLogo({ transition }) {
const [visible, setVisible] = useState(!transition);
- useEffect(() => transition && setVisible(true));
+ useEffect(() => transition && setVisible(true), [transition]);
return (
diff --git a/src/components/menu-button.js b/src/components/menu-button.js
index 4f155c4..bb2b7b6 100644
--- a/src/components/menu-button.js
+++ b/src/components/menu-button.js
@@ -9,6 +9,15 @@ const Container = styled.button`
background-color: transparent;
padding: 4px 8px;
border: 0;
+ cursor: pointer;
+
+ &:focus {
+ outline: 0;
+ }
+
+ @media (min-width: 30em) {
+ display: none;
+ }
`;
const Bar = styled.span`
diff --git a/src/components/nav-item.js b/src/components/nav-item.js
new file mode 100644
index 0000000..97b7d93
--- /dev/null
+++ b/src/components/nav-item.js
@@ -0,0 +1,47 @@
+import React from "react";
+import styled, { css } from "styled-components";
+import NavLink from "./nav-link";
+
+const SubList = styled.ul`
+ margin: 0 0 0 var(--spacing-x-md);
+ padding: 0;
+ list-style: none;
+
+ @media (min-width: 30em) {
+ display: none;
+ flex-direction: column;
+ position: absolute;
+ margin: 0;
+ padding: var(--spacing-y-xs) var(--spacing-x-xs);
+ background-color: rgba(0, 0, 0, 0.6);
+ backdrop-filter: blur(2px);
+ }
+`;
+
+const ListItem = styled.li`
+ position: relative;
+
+ &:focus-within ${SubList}, &:hover ${SubList} {
+ @media (min-width: 30em) {
+ display: flex;
+ }
+ }
+`;
+
+export default function NavItem({ children, subNav, ...other }) {
+ const hasChildren = subNav && subNav.length > 0;
+ return (
+
+ {children}
+ {hasChildren && (
+
+ {subNav.map((link, i) => (
+
+ {link.title}
+
+ ))}
+
+ )}
+
+ );
+}
diff --git a/src/components/nav-link.js b/src/components/nav-link.js
index d1e76f1..06a1b8c 100644
--- a/src/components/nav-link.js
+++ b/src/components/nav-link.js
@@ -1,56 +1,30 @@
import React from "react";
-import styled, { css } from "styled-components";
import { Link as GatsbyLink } from "gatsby";
+import styled from "styled-components";
-const SubList = styled.ul`
- position: absolute;
- display: none;
- flex-direction: column;
- min-width: 120px;
- margin: 0;
+const Link = styled(GatsbyLink)`
+ display: inline-block;
padding: 0;
- list-style: none;
-`;
+ margin-bottom: var(--spacing-y-sm);
+ color: var(--color-white);
+ font-size: var(--font-size-lg);
+ text-decoration: none;
+ cursor: pointer;
-const ListItem = styled.li`
- position: relative;
- margin: 0 var(--spacing-y-xs);
+ &:focus {
+ outline: none;
+ }
- &:hover ${SubList} {
- @media (min-width: 40rem) {
- display: flex;
- }
+ @media (min-width: 30em) {
+ font-size: var(--font-size-sm);
+ margin: 0 var(--spacing-x-xs);
+ padding: 9px 0;
+ border-bottom: 2px solid
+ ${props => (props.active ? `var(--color-white)` : `transparent`)};
}
`;
-const Link = styled(GatsbyLink)`
- display: block;
- color: white;
- text-decoration: none;
- padding: 5px;
- margin-top: var(--spacing-y-xs);
- border-bottom: 2px solid transparent;
-
- ${props =>
- props.active &&
- css`
- border-color: var(--color-white);
- `}
-`;
-
-export default function NavLink({ children, subLinks, ...other }) {
- return (
-
- {children}
- {subLinks && subLinks.length > 0 && (
-
- {subLinks.map((link, i) => (
-
- {link.title}
-
- ))}
-
- )}
-
- );
+export default function NavLink({ location, children, to }) {
+ console.log(location);
+ return {children};
}
diff --git a/src/components/nav.js b/src/components/nav.js
index d99ab9f..7c0af59 100644
--- a/src/components/nav.js
+++ b/src/components/nav.js
@@ -1,60 +1,86 @@
import React from "react";
+import { Link } from "gatsby";
import styled from "styled-components";
-import NavLink from "./nav-link";
+import NavItem from "./nav-item";
import MenuButton from "./menu-button";
+import LogoArrows from "../icons/logo-arrows.svg";
const Container = styled.div`
- position: ${props => (props.open ? "fixed" : "absolute")};
+ position: fixed;
top: 0;
right: 0;
bottom: 0;
+ left: 0;
+ display: flex;
+ flex-direction: column-reverse;
z-index: 6;
+ background-color: ${props =>
+ props.open ? `rgba(0, 0, 0, 0.8)` : `rgba(0, 0, 0, 0.4)`};
+ backdrop-filter: blur(2px);
transform: ${props =>
- props.open ? `translate3d(0, 0, 0)` : `translate3d(100%, 0, 0)`};
- transition: transform 0.15s;
-
+ props.open
+ ? `translate3d(0, 0, 0)`
+ : `translate3d(0, calc(-100% + 40px), 0)`};
+ transition: transform 0.3s ease-in-out, background-color 0.3s ease-in-out;
@media (min-width: 30em) {
- bottom: auto;
- left: 0;
+ position: absolute;
display: flex;
- background-color: rgba(0, 0, 0, 0.4);
- backdrop-filter: blur(2px);
+ flex-direction: row;
+ bottom: auto;
+ background-color: rgba(0, 0, 0, 0.6);
transform: none;
transition: none;
}
`;
const Menu = styled.div`
- position: absolute;
- top: 0;
- left: 0;
- padding: var(--spacing-y-xs) var(--spacing-x-md) 0 0;
- transform: translateX(-100%);
+ display: flex;
+ justify-content: space-between;
+ align-items: stretch;
+ color: white;
+ margin: var(--spacing-x-xs) var(--spacing-y-sm);
+`;
- @media (min-width: 30em) {
- display: none;
+const Heading = styled(Link)`
+ display: flex;
+ flex-direction: column;
+ justify-content: space-around;
+ opacity: ${props => (props.visible ? 1 : 0)};
+ transform: opacity 0.3s ease-in;
+
+ svg {
+ width: 24px;
+ height: 12px;
+
+ &:first-of-type {
+ path:first-child {
+ fill: var(--theme-color-primary);
+ }
+
+ path:last-child {
+ fill: var(--theme-color-secondary);
+ }
+ }
+ &:last-of-type {
+ transform: rotate(180deg);
+ path:first-child {
+ fill: var(--theme-color-dark);
+ }
+
+ path:last-child {
+ fill: var(--theme-color-secondary);
+ }
+ }
}
`;
const Content = styled.nav`
- margin: 0 var(--spacing-x-sm);
+ flex-grow: 1;
+ margin: var(--spacing-y-lg) var(--spacing-x-md);
- @media (max-width: 30em) {
- background-color: rgba(0, 0, 0, 0.4);
- }
-`;
-
-const Overlay = styled.div`
- @media (max-width: 30em) {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 5;
- display: ${props => (props.visible ? `block` : `none`)};
- background-color: rgba(0, 0, 0, 0.75);
- backdrop-filter: blur(2px);
+ @media (min-width: 30em) {
+ display: flex;
+ margin: 0;
}
`;
@@ -70,25 +96,25 @@ const List = styled.ul`
`;
export default function Nav({ data, open, setOpen }) {
- const handleOverlayClick = () => setOpen(false);
const handleButtonClick = () => setOpen(!open);
return (
- <>
-
-
-
-
-
-
- {data.map((link, i) => (
-
- {link.title}
-
- ))}
-
-
-
-
- >
+
+
+
+
+
+
+
+
+
+
+ {data.map((link, i) => (
+
+ {link.title}
+
+ ))}
+
+
+
);
}
diff --git a/src/images/bathroom2.png b/src/images/bathroom2.png
new file mode 100644
index 0000000..5566608
Binary files /dev/null and b/src/images/bathroom2.png differ
diff --git a/src/images/service_bathroom.png b/src/images/service_bathroom.png
new file mode 100644
index 0000000..fc72906
Binary files /dev/null and b/src/images/service_bathroom.png differ
diff --git a/src/images/service_carpentry.png b/src/images/service_carpentry.png
new file mode 100644
index 0000000..5119f19
Binary files /dev/null and b/src/images/service_carpentry.png differ
diff --git a/src/images/service_electrics.png b/src/images/service_electrics.png
new file mode 100644
index 0000000..41a9b30
Binary files /dev/null and b/src/images/service_electrics.png differ
diff --git a/src/images/service_tiling.png b/src/images/service_tiling.png
new file mode 100644
index 0000000..82249ea
Binary files /dev/null and b/src/images/service_tiling.png differ
diff --git a/src/layout.js b/src/layout.js
index bc701ee..a73a6b1 100644
--- a/src/layout.js
+++ b/src/layout.js
@@ -1,6 +1,7 @@
-import React from "react";
+import React, { useState } from "react";
import { useStaticQuery, graphql } from "gatsby";
import { Helmet } from "react-helmet";
+import Nav from "./components/nav";
import Footer from "./components/footer";
import { createGlobalStyle } from "styled-components";
import "@fontsource/cooper-hewitt/400.css";
@@ -65,6 +66,7 @@ const GlobalStyle = createGlobalStyle`
box-sizing: border-box;
margin: 0;
font-family: 'Cooper Hewitt', sans-serif;
+ overflow-x: hidden;
overflow-y: ${props => (props.navOpen ? "hidden" : "auto")};
}
@@ -83,7 +85,8 @@ const GlobalStyle = createGlobalStyle`
}
`;
-export default function Layout({ children }) {
+export default function Layout({ location, children }) {
+ console.log(location);
const data = useStaticQuery(graphql`
query HeaderQuery {
site {
@@ -91,11 +94,20 @@ export default function Layout({ children }) {
title
description
keywords
+ navData {
+ title
+ to
+ subNav {
+ title
+ to
+ }
+ }
}
}
}
`);
- const { title, description, keywords } = data.site.siteMetadata;
+ const { title, description, keywords, navData } = data.site.siteMetadata;
+ const [navOpen, setNavOpen] = useState();
return (
<>
@@ -106,10 +118,11 @@ export default function Layout({ children }) {
{ name: "keywords", content: keywords }
]}
/>
-
+
{children}
+
>
);
}
diff --git a/src/pages/404.js b/src/pages/404.js
index e94a7b7..c591891 100644
--- a/src/pages/404.js
+++ b/src/pages/404.js
@@ -1,5 +1,5 @@
import React from "react";
-import { graphql } from "gatsby";
+import { Link, graphql } from "gatsby";
import Layout from "../layout";
import Header from "../components/header";
import HeaderLogo from "../components/header-logo";
@@ -9,10 +9,12 @@ export default function Index({ data }) {
return (
-
+
+ Page not found
+ Back Home
+
);
}
diff --git a/src/pages/colours.js b/src/pages/colours.js
new file mode 100644
index 0000000..976bb73
--- /dev/null
+++ b/src/pages/colours.js
@@ -0,0 +1,70 @@
+import React from "react";
+import { graphql } from "gatsby";
+import Layout from "../layout";
+import Header from "../components/header";
+import HeaderLogo from "../components/header-logo";
+import Section from "../components/section";
+import Text from "../components/text";
+
+export default function Index({ data }) {
+ return (
+
+
+
+ ABC Project Design
+ Easy as ABC
+
+
+
+
+ --theme-color-primary: #9c0905;
+
+
+ --theme-color-secondary: #9590a8;
+
+
+ --theme-color-tertiary: #bbcbcb;
+
+
+ --theme-color-light: #e5ffde;
+
+
+ --theme-color-dark: #000a61;
+
+
+
+ );
+}
+
+export const query = graphql`
+ query {
+ headerImage: file(relativePath: { eq: "bathroom.png" }) {
+ childImageSharp {
+ fluid(maxWidth: 1920, quality: 100) {
+ ...GatsbyImageSharpFluid_withWebp
+ }
+ }
+ }
+ }
+`;
diff --git a/src/pages/index.js b/src/pages/index.js
index 82c726f..19a7019 100644
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -4,6 +4,7 @@ import Layout from "../layout";
import Header from "../components/header";
import HeaderLogo from "../components/header-logo";
import Section from "../components/section";
+import Card from "../components/card";
import ReviewSummary from "../components/review-summary";
import CustomSlick from "../components/custom-slick";
import Text from "../components/text";
@@ -12,7 +13,7 @@ export default function Index({ data }) {
return (
@@ -25,6 +26,32 @@ export default function Index({ data }) {
operate in Essex, Hertfordshire, Kent and London.
+
+
+ Bathrooms
+
+
+ Tiling
+
+
+ Electrics
+
+
+ Carpentry
+
+
{data.site.siteMetadata.reviews.map((review, i) => (
@@ -45,6 +72,34 @@ export const query = graphql`
}
}
}
+ bathroomImage: file(relativePath: { eq: "service_bathroom.png" }) {
+ childImageSharp {
+ fixed(width: 96, height: 54, quality: 100) {
+ ...GatsbyImageSharpFixed_withWebp
+ }
+ }
+ }
+ tilingImage: file(relativePath: { eq: "service_tiling.png" }) {
+ childImageSharp {
+ fixed(width: 96, height: 54, quality: 100) {
+ ...GatsbyImageSharpFixed_withWebp
+ }
+ }
+ }
+ electricsImage: file(relativePath: { eq: "service_electrics.png" }) {
+ childImageSharp {
+ fixed(width: 96, height: 54, quality: 100) {
+ ...GatsbyImageSharpFixed_withWebp
+ }
+ }
+ }
+ carpentryImage: file(relativePath: { eq: "service_carpentry.png" }) {
+ childImageSharp {
+ fixed(width: 96, height: 54, quality: 100) {
+ ...GatsbyImageSharpFixed_withWebp
+ }
+ }
+ }
site {
siteMetadata {
reviews {
diff --git a/src/pages/services/bathrooms.js b/src/pages/services/bathrooms.js
new file mode 100644
index 0000000..64e8442
--- /dev/null
+++ b/src/pages/services/bathrooms.js
@@ -0,0 +1,26 @@
+import React from "react";
+import { graphql } from "gatsby";
+import Layout from "../../layout";
+import Header from "../../components/header";
+
+export default function Index({ data }) {
+ return (
+
+
+
+ );
+}
+
+export const query = graphql`
+ query {
+ headerImage: file(relativePath: { eq: "bathroom2.png" }) {
+ childImageSharp {
+ fluid(maxWidth: 1920, quality: 100) {
+ ...GatsbyImageSharpFluid_withWebp
+ }
+ }
+ }
+ }
+`;
diff --git a/src/pages/services/index.js b/src/pages/services/index.js
new file mode 100644
index 0000000..0d0410c
--- /dev/null
+++ b/src/pages/services/index.js
@@ -0,0 +1,27 @@
+import React from "react";
+import { graphql } from "gatsby";
+import Layout from "../../layout";
+import Header from "../../components/header";
+
+export default function Index({ location, data }) {
+ console.log(location);
+ return (
+
+
+
+ );
+}
+
+export const query = graphql`
+ query {
+ headerImage: file(relativePath: { eq: "bathroom2.png" }) {
+ childImageSharp {
+ fluid(maxWidth: 1920, quality: 100) {
+ ...GatsbyImageSharpFluid_withWebp
+ }
+ }
+ }
+ }
+`;