Migrate to Next

This commit is contained in:
2022-11-11 22:41:53 +00:00
parent 58e38dbedd
commit 4aaad4d704
352 changed files with 15583 additions and 21335 deletions

10
pages/_app.js Normal file
View File

@@ -0,0 +1,10 @@
import React from "react";
import "@styles/globals.css";
import "@fontsource/cooper-hewitt/400.css";
import "@fontsource/cooper-hewitt/700.css";
function Application({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default Application;

45
pages/about.js Normal file
View File

@@ -0,0 +1,45 @@
import React from "react";
import { Header, Layout, Section, Text } from "@components/index";
import bannerImg from "../images/banner_bathroom.jpg";
export default function About() {
return (
<Layout title="About">
<Header image={bannerImg} position="br">
<Text size="xl" weight="bold" noMargin>
<em>Easy as</em> ABC
</Text>
</Header>
<Section title="About ABC Project Design">
<Text>
ABC Project Design Ltd is a medium sized family run business with more
than 30 years experience in the building and construction industry. We
offer a fully certified and accredited bathroom refurbishment service.
</Text>
<Text>
We currently have 15 skilled tradesman within our workforce and
operate in Essex, Hertfordshire, Kent and London. Our team include
plumbers, carpenters, bathroom fitters, tilers, electricians,
plasterers, painters and decorators. All our staff are vetted and have
vast experience in there chosen fields.
</Text>
<Text>
We specialise in bathroom refurbishments and floor tiling. Our
stonemasons and tilers are specialists in ceramic, natural stone,
marble, quartz, porcelain and mosaic tiles.
</Text>
<Text>
Customer satisfaction is of paramount importance to us this and is
reflected in our many five star reviews on Rated People and Bark. We
strive to maximise our relationship with our customers by being honest
and fair.
</Text>
<Text>
We are fully insured and all work undertaken is guaranteed. Pricing is
something we take extremely seriously and we aim to be ultra
competitive.
</Text>
</Section>
</Layout>
);
}

30
pages/area-covered.js Normal file
View File

@@ -0,0 +1,30 @@
import React from "react";
import { Header, Layout, Link, Map, Section, Text } from "@components/index";
import { getGoogleAPIKey } from "../lib/env";
export default function AreaCovered({ apikey }) {
return (
<Layout title="Area covered">
<Header map={<Map apikey={apikey} showRegion fullHeight />} />
<Section title="Area covered">
<Text>
Our services are available, in London, Hertfordshire, Cambridgeshire,
Essex and Kent.
</Text>
<Text>
The area highlighted in the map is a rough guideline, if you are just
outside the area then please do feel free to{" "}
<Link href="/contact">get in touch</Link>.
</Text>
</Section>
</Layout>
);
}
export async function getStaticProps() {
return {
props: {
apikey: getGoogleAPIKey(),
},
};
}

254
pages/contact.js Normal file
View File

@@ -0,0 +1,254 @@
import React, { useRef, useState } from "react";
import {
Button,
ContactButton,
Grid,
Header,
Icon,
IconWithText,
InputField,
Interrupt,
Label,
Layout,
Link,
Map,
Section,
Select,
Text,
} from "@components/index";
import { getGoogleAPIKey } from "../lib/env";
import { CheckCircleSvg, EnvelopeSvg, MobileSvg, TeamSvg } from "../icons";
import bannerImg from "../images/banner_bathroom.jpg";
export default function About({ apikey }) {
const formRef = useRef();
const [formState, setFormState] = useState();
const handleSubmit = (e) => {
e.preventDefault();
setFormState("submitting");
const body = new FormData(formRef.current);
fetch("/contact", { method: "POST", body })
.then((res) => {
if (res.status !== 200) {
setFormState("error");
} else {
setFormState("success");
}
})
.catch(() => setFormState("error"));
};
return (
<Layout title="Contact us">
<Header image={bannerImg} position="br">
<Text size="xl" weight="bold" noMargin>
<em>Get in</em> touch
</Text>
</Header>
<Section>
<Text size="xl">
Are you planning a new bathroom? Are you looking for inspiration? Our
team are ready to help you through every step of the journey.
</Text>
<Text>
A typical bathroom refurbishment starts from £3,500, increasing up to
£20,000. Our quotes include stripping out the old bathroom, disposal
of rubbish, fitting the new bathroom, labour and building materials
for tiling, plastering, painting and decorating. It does not include
bathroom suites or tiles.
</Text>
<Grid md={2}>
<div style={{ position: "relative" }}>
{formState === "success" && (
<>
<IconWithText
icon={
<Icon color="dark" size="lg">
<CheckCircleSvg />
</Icon>
}
>
<Text size="lg" color="dark" noMargin>
Thank you for contacting us!
</Text>
</IconWithText>
<Text>
We will get back to you in the next two working days.
</Text>
</>
)}
{formState !== "success" && (
<>
{formState === "submitting" && <Interrupt />}
<IconWithText
icon={
<Icon size="lg" color="dark">
<EnvelopeSvg />
</Icon>
}
>
<Text size="lg" color="dark" noMargin>
Contact us
</Text>
</IconWithText>
{formState === "error" && (
<>
<Text size="lg" color="primary" weight="bold">
There was an error submitting the form, please try again
later.
</Text>
<Text color="primary">
Alternatively, please feel free to email us at{" "}
<Link href="mailto:quotations@abcprojectdesign.com">
quotations@abcprojectdesign.com
</Link>
.
</Text>
</>
)}
<form
name="contact"
method="POST"
action="/contact"
onSubmit={(e) => handleSubmit(e, scroll)}
data-netlify="true"
data-netlify-honeypot="bot-field"
ref={formRef}
>
<input type="hidden" name="form-name" value="contact" />
<Label htmlFor="contact-name">Name</Label>
<InputField id="contact-name" name="name" />
<Label htmlFor="contact-email">Email</Label>
<InputField id="contact-email" name="email" />
<Label htmlFor="contact-telephone">Telephone</Label>
<InputField id="contact-telephone" name="telephone" />
<Label htmlFor="contact-stage">
What stage of planning are you at?
</Label>
<Select
id="contact-stage"
name="stage"
options={[
{ value: "", label: "" },
{ value: "ready to hire", label: "I'm ready to hire" },
{
value: "budgeting and planning",
label: "I'm planning and budgeting",
},
{
value: "quote for insurance",
label: "I need a quote for insurance",
},
]}
/>
<Label htmlFor="contact-start">
When would you like the job to start?
</Label>
<Select
id="contact-start"
name="start"
options={[
{ value: "", label: "" },
{ value: "urgently", label: "Urgently" },
{ value: "within 1 week", label: "Within 1 week" },
{ value: "within 2 weeks", label: "Within 2 weeks" },
{ value: "within 1 month", label: "Within 1 month" },
{ value: "within 2 months", label: "Within 2 months" },
{ value: "not sure", label: "Not sure" },
]}
/>
<Label htmlFor="contact-status">
Are you the owner of the property?
</Label>
<Select
id="contact-status"
name="status"
options={[
{ value: "", label: "" },
{ value: "owner", label: "I own the property" },
{ value: "landlord", label: "I am the landlord" },
{ value: "tenant", label: "I am a tenant" },
{
value: "council property",
label: "It's a council property",
},
]}
/>
<Label htmlFor="contact-budget">What is your budget?</Label>
<Select
id="contact-budget"
name="budget"
options={[
{ value: "under £2,000", label: "Under £2,000" },
{ value: "under £3,000", label: "Under £3,000" },
{ value: "under £4,000", label: "Under £4,000" },
{ value: "under £5,000", label: "Under £5,000" },
{ value: "under £6,000", label: "Under £6,000" },
{ value: "under £7,000", label: "Under £7,000" },
{ value: "under £8,000", label: "Under £8,000" },
{ value: "under £9,000", label: "Under £9,000" },
{ value: "under £10,000", label: "Under £10,000" },
{ value: "under £15,000", label: "Under £15,000" },
{ value: "under £20,000", label: "Under £20,000" },
]}
/>
<Label htmlFor="contact-message">
Describe what needs to be done
</Label>
<InputField id="contact-message" name="message" textArea />
<Button type="submit">
{formState === "submitting" ? "Submitting..." : "Submit"}
</Button>
</form>
</>
)}
</div>
<div>
<IconWithText
icon={
<Icon color="dark" size="lg">
<TeamSvg />
</Icon>
}
>
<Text size="lg" color="dark" noMargin>
The Team
</Text>
</IconWithText>
<div>
<Text noMargin>
<strong>Daniel Costea</strong> &ndash; Project Director
</Text>
<ContactButton href="tel:+447378839358" size="sm">
<Icon size="sm">
<MobileSvg />
</Icon>
07378839358
</ContactButton>
<ContactButton
href="mailto:quotations@abcprojectdesign.com"
size="sm"
>
<Icon size="sm">
<EnvelopeSvg />
</Icon>
quotations@abcprojectdesign.com
</ContactButton>
</div>
</div>
</Grid>
</Section>
<Map apikey={apikey} zoom={10} showMarker />
</Layout>
);
}
export async function getStaticProps() {
return {
props: {
apikey: getGoogleAPIKey(),
},
};
}

180
pages/index.js Normal file
View File

@@ -0,0 +1,180 @@
import React from "react";
import Image from "next/image";
import {
Button,
Layout,
Header,
HeaderLogo,
Heading,
Section,
Card,
Grid,
Text,
Tile,
Icon,
Review,
} from "@components/index";
import {
CheckCircleSvg,
CalendarSvg,
HammerSvg,
PoundSvg,
SmileSvg,
SpySvg,
} from "../icons";
import bannerImg from "../images/banner_bathroom.jpg";
import bathroomImg from "../images/bathroom.jpg";
import tilingImg from "../images/tiling.jpg";
import victorianImg from "../images/victorian_plumbing_logo.png";
export default function Home() {
return (
<Layout>
<Header image={bannerImg}>
<HeaderLogo transition />
</Header>
<Section title="What we do">
<Grid sm={2}>
<Card
heading={
<Heading el="h3" size="md">
Bathrooms
</Heading>
}
image={bathroomImg}
href="/services/bathrooms"
>
Fully accredited bathroom refurbishment service
</Card>
<Card
heading={
<Heading el="h3" size="md">
Tiling
</Heading>
}
image={tilingImg}
href="/services/tiling"
>
We can install many different styles
</Card>
</Grid>
</Section>
<Section variant="secondary" title="Products">
<Grid sm={2}>
<div>
<Image src={victorianImg} width={320} height={98} />
</div>
<div>
<Text>
Victorian Plumbing is a leading retailer of bathrooms online and
our preferred supplier of bathroom suites.
</Text>
<Button href="https://www.victorianplumbing.co.uk/bathroom-suites">
View products
</Button>
</div>
</Grid>
</Section>
<Section title="All of our work is guaranteed!">
<Text>
If you are looking for a one-stop shop for your new bathroom, look no
further. We can take care of all jobs required to complete your new
bathroom, including plumbing, tiling and electrical works.
</Text>
<Grid sm={2} md={3}>
<Tile>
<Icon size="xl">
<CheckCircleSvg />
</Icon>
<Heading el="h3" size="lg">
100% Guaranteed
</Heading>
<Text>
We guarantee all of our work. If you have any issues, we will fix
it at no additional cost.
</Text>
</Tile>
<Tile>
<Icon size="xl">
<PoundSvg />
</Icon>
<Heading el="h3" size="lg">
Competitive Fees
</Heading>
<Text>
We have affordable pricing and we strive to be as competitive as
possible.
</Text>
</Tile>
<Tile>
<Icon size="xl">
<SpySvg />
</Icon>
<Heading el="h3" size="lg">
No hidden charges
</Heading>
<Text>
All costs will be clearly stated up front in the contact.
</Text>
</Tile>
<Tile>
<Icon size="xl">
<HammerSvg />
</Icon>
<Heading el="h3" size="lg">
High Quality Craftmanship
</Heading>
<Text>
Our skilled tradesmen have many years of experience in their craft
and will ensure full compliance with industry standards and
guidelines.
</Text>
</Tile>
<Tile>
<Icon size="xl">
<CalendarSvg />
</Icon>
<Heading el="h3" size="lg">
Transparent Deadlines
</Heading>
<Text>
We will provide you with a start and finish date with your
contract.
</Text>
</Tile>
<Tile>
<Icon size="xl">
<SmileSvg />
</Icon>
<Heading el="h3" size="lg">
Friendly Team
</Heading>
<Text>
We will be friendly, respectful and curtious from start to finish.
</Text>
</Tile>
</Grid>
</Section>
<Section variant="secondary" title="What our clients think of us">
<Review
type="Checkatrade"
title="Full redecoration schedule bungalow"
author="Mrs Ford"
date="February 2021"
>
<Text italic>
I have pleasure in providing this reference for Daniel. For the last
7 weeks he has been working on the bungalow belonging to my aged
uncle for whom I have Power of Attorney, to prepare the property,
which was formerly a small holding, for the market. The house had to
be cleared,of furniture, repairs carried out with a full
redecoration schedule. In addition there were numerous outbuildings
to clear and a 4 acre site, which was completely overgrown, to be
brought up to standard. It was a huge undertaking but Daniel and his
team took it on willingly.
</Text>
</Review>
</Section>
</Layout>
);
}

View File

@@ -0,0 +1,81 @@
import React, { useState } from "react";
import {
CaseStudy,
Content,
GalleryOverlay,
GalleryThumb,
Grid,
Header,
Heading,
Layout,
Section,
Text,
} from "@components/index";
import { getAllCaseStudyIds, getCaseStudyData } from "../../../lib/case-study";
export default function CaseStudyTemplate({ caseStudyData }) {
const [openImage, setOpenImage] = useState(-1);
const images = Array.from(new Array(caseStudyData.images)).map((_, i) => ({
thumb: `/case-studies/${caseStudyData.id}/thumbs/${i}.jpg`,
src: `/case-studies/${caseStudyData.id}/${i}.jpg`,
}));
const handleThumbClick = (i) => setOpenImage(i);
const handlePrevClick = () =>
setOpenImage(openImage === 0 ? images.length - 1 : openImage - 1);
const handleNextClick = () =>
setOpenImage(openImage === images.length - 1 ? 0 : openImage + 1);
return (
<Layout title={caseStudyData.title}>
<Header
image={`/case-studies/${caseStudyData.id}/${caseStudyData.image}.jpg`}
>
<Heading>{caseStudyData.title}</Heading>
<Text>{caseStudyData.location}</Text>
</Header>
<CaseStudy data={caseStudyData} />
<Section>
<Content>
<div dangerouslySetInnerHTML={{ __html: caseStudyData.content }} />
</Content>
</Section>
<Section variant="secondary" title="Gallery">
<Grid d={2} sm={3} md={4}>
{images.map((img, i) => (
<GalleryThumb
key={img.thumb}
image={img.thumb}
label={`Show full picture from ${caseStudyData.title}`}
onClick={() => handleThumbClick(i)}
/>
))}
</Grid>
{openImage > -1 && (
<GalleryOverlay
onClose={() => setOpenImage(-1)}
onNext={handleNextClick}
onPrev={handlePrevClick}
image={images[openImage].src}
desc={`Picture from ${caseStudyData.title}`}
/>
)}
</Section>
</Layout>
);
}
export async function getStaticPaths() {
const paths = getAllCaseStudyIds({});
return {
paths,
fallback: false,
};
}
export async function getStaticProps({ params }) {
const caseStudyData = getCaseStudyData({ ...params });
return {
props: {
caseStudyData,
},
};
}

View File

@@ -0,0 +1,73 @@
import React from "react";
import {
Card,
Grid,
Header,
Heading,
Layout,
Section,
Text,
} from "@components/index";
import { getAllCaseStudyIds } from "../../lib/case-study";
import bannerImg from "../../images/banner_bathroom.jpg";
export default function Bathrooms({ caseStudies }) {
return (
<Layout title="Bathrooms">
<Header title="Bathrooms" image={bannerImg} />
<Section title="We build bespoke bathrooms">
<Text>
It's more than likely the most important room in your house and one of
the biggest investments you will ever make. We offer a professional
design service and an expert installation service. All our tradesman
are vetted and handpicked based on their skills within their chosen
fields.
</Text>
<Text>
With over 30 years experience in bathroom installation we will help
you choose the perfect bathroom for your home. We can complete your
whole bathroom installation including electrics, plastering, plumbing
and paint and decorating.
</Text>
<Text>
If you want a high quality bathroom you have come to the right place.
</Text>
<Text>
We provide an initial consultation followed by a competitive quote.
</Text>
<Text>
To ensure complete satisfaction we insist on managing the entire
installation process. All of our quotations are for a fully inclusive
installation service, one price to deliver a fully functioning and
completed bathroom.
</Text>
</Section>
<Section variant="secondary" title="Case studies">
<Grid sm={2} md={3}>
{caseStudies.map((study) => (
<Card
heading={
<Heading el="h3" size="md">
{study.params.title}
</Heading>
}
image={`/case-studies/${study.params.id}/thumbs/${study.params.image}.jpg`}
href={`/services/bathrooms/${study.params.slug}`}
key={study.params.id}
>
{study.params.location}
</Card>
))}
</Grid>
</Section>
</Layout>
);
}
export const getStaticProps = async () => {
const caseStudies = getAllCaseStudyIds({ service: "bathrooms" });
return {
props: { caseStudies },
};
};

38
pages/services/index.js Normal file
View File

@@ -0,0 +1,38 @@
import React from "react";
import {
Card,
Grid,
Header,
Heading,
Layout,
Section,
} from "@components/index";
import bannerImg from "../../images/banner_bathroom.jpg";
import bathroomImg from "../../images/bathroom.jpg";
import tilingImg from "../../images/tiling.jpg";
export default function Services() {
return (
<Layout title="Services">
<Header title="Services" image={bannerImg} />
<Section title="Our services">
<Grid sm={2}>
<Card
heading={<Heading el="h3">Bathrooms</Heading>}
image={bathroomImg}
href="/services/bathrooms"
>
Fully accredited bathroom refurbishment service
</Card>
<Card
heading={<Heading el="h3">Tiling</Heading>}
image={tilingImg}
href="/services/tiling"
>
We can install many different styles
</Card>
</Grid>
</Section>
</Layout>
);
}

56
pages/services/tiling.js Normal file
View File

@@ -0,0 +1,56 @@
import React from "react";
import {
Card,
Grid,
Header,
Heading,
Layout,
Section,
Text,
} from "@components/index";
import { getAllCaseStudyIds } from "../../lib/case-study";
import tilingImg from "../../images/tiling.jpg";
export default function Tiling({ caseStudies }) {
return (
<Layout title="Tiling">
<Header title="Tiling" image={tilingImg} light />
<Section title="We specialise in floor tiling">
<Text>
We can install both floor and wall tiles, including ceramic, natural
stone, marble, quartz, porcelain and mosaic tiles.
</Text>
<Text>
Our elite team of 3 stonemasons and 3 tilers has a combined total of
112 years of experience within the industry.
</Text>
</Section>
<Section variant="secondary" title="Case studies">
<Grid sm={2} md={3}>
{caseStudies.map((study) => (
<Card
heading={
<Heading el="h3" size="md">
{study.params.title}
</Heading>
}
image={`/case-studies/${study.params.id}/thumbs/${study.params.image}.jpg`}
href={`/services/tiling/${study.params.slug}`}
key={study.params.id}
>
{study.params.location}
</Card>
))}
</Grid>
</Section>
</Layout>
);
}
export const getStaticProps = async () => {
const caseStudies = getAllCaseStudyIds({ service: "tiling" });
return {
props: { caseStudies },
};
};