From 5bc55ac0a801cbe82c41a10f7e680612be4deaf8 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 13 Dec 2021 16:42:50 +0100 Subject: chore: create homepage with graphql data --- .env.example | 9 +++ .gitignore | 4 ++ src/config/seo.ts | 8 +++ src/pages/index.tsx | 80 +++++---------------------- src/services/graphql/client.ts | 12 ++++ src/services/graphql/homepage.ts | 36 ++++++++++++ src/styles/Home.module.css | 116 --------------------------------------- src/styles/base/_typography.scss | 9 +++ src/ts/types/app.ts | 2 +- src/ts/types/homepage.ts | 19 +++++++ 10 files changed, 113 insertions(+), 182 deletions(-) create mode 100644 .env.example create mode 100644 src/config/seo.ts create mode 100644 src/services/graphql/client.ts create mode 100644 src/services/graphql/homepage.ts delete mode 100644 src/styles/Home.module.css create mode 100644 src/ts/types/homepage.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c4ddb0e --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +BACKEND_URL="https://www.backend.com" +GRAPHQL_ENDPOINT="/graphql" + +NEXT_PUBLIC_GRAPHQL_API="$BACKEND_URL$GRAPHQL_ENDPOINT" + +# Use this only in development mode. It prevents "unable to verify the first +# certificate" error when using a local domain with mkcert certificate for +# backend. +#NODE_TLS_REJECT_UNAUTHORIZED=0 diff --git a/.gitignore b/.gitignore index fc8c4cd..d4504c5 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,7 @@ yarn-error.log* # cache .eslintcache + +# dotenv +.env* +!.env.example diff --git a/src/config/seo.ts b/src/config/seo.ts new file mode 100644 index 0000000..afccfe5 --- /dev/null +++ b/src/config/seo.ts @@ -0,0 +1,8 @@ +import { t } from '@lingui/macro'; + +export const seo = { + homepage: { + title: t`Armand Philippot | Front-end developer`, + description: t`Armand Philippot is a front-end developer located in France. He codes, he writes and he plays. Discover is website.`, + }, +}; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 615fe0a..6654617 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,75 +1,22 @@ +import type { ReactElement } from 'react'; +import { GetStaticProps } from 'next'; +import Head from 'next/head'; import Layout from '@components/Layouts/Layout'; +import { seo } from '@config/seo'; +import { getHomePage } from '@services/graphql/homepage'; import { NextPageWithLayout } from '@ts/types/app'; +import { HomePage, HomePageProps } from '@ts/types/homepage'; import { loadTranslation } from '@utils/helpers/i18n'; -import { GetStaticProps } from 'next'; -import Head from 'next/head'; -import Image from 'next/image'; -import type { ReactElement } from 'react'; -import styles from '../styles/Home.module.css'; -const Home: NextPageWithLayout = () => { +const Home: NextPageWithLayout = ({ data }) => { return ( -
+ <> - Create Next App - - + {seo.homepage.title} + - -
-

- Welcome to Next.js! -

- -

- Get started by editing{' '} - pages/index.tsx -

- -
- -

Documentation →

-

Find in-depth information about Next.js features and API.

-
- - -

Learn →

-

Learn about Next.js in an interactive course with quizzes!

-
- - -

Examples →

-

Discover and deploy boilerplate example Next.js projects.

-
- - -

Deploy →

-

- Instantly deploy your Next.js site to a public URL with Vercel. -

-
-
-
- - -
+
+ ); }; @@ -83,8 +30,11 @@ export const getStaticProps: GetStaticProps = async (ctx) => { process.env.NODE_ENV === 'production' ); + const data: HomePage = await getHomePage(); + return { props: { + data, translation, }, }; diff --git a/src/services/graphql/client.ts b/src/services/graphql/client.ts new file mode 100644 index 0000000..160021b --- /dev/null +++ b/src/services/graphql/client.ts @@ -0,0 +1,12 @@ +import { GraphQLClient } from 'graphql-request'; + +export const getGraphQLClient = () => { + const apiUrl: string = process.env.NEXT_PUBLIC_GRAPHQL_API || ''; + console.log(apiUrl); + + if (!apiUrl) throw new Error('API URL not defined.'); + + const graphQLClient = new GraphQLClient(apiUrl); + + return graphQLClient; +}; diff --git a/src/services/graphql/homepage.ts b/src/services/graphql/homepage.ts new file mode 100644 index 0000000..6ea71ac --- /dev/null +++ b/src/services/graphql/homepage.ts @@ -0,0 +1,36 @@ +import { gql } from 'graphql-request'; +import { + fetchHomePageReturn, + getHomePageReturn, + HomePage, + HomePageResponse, +} from '@ts/types/homepage'; +import { getGraphQLClient } from './client'; + +export const fetchHomepage: fetchHomePageReturn = async () => { + const client = getGraphQLClient(); + const query = gql` + query HomePage { + nodeByUri(uri: "/") { + ... on Page { + id + content + } + } + } + `; + + try { + const response: HomePageResponse = await client.request(query); + return response; + } catch (error) { + console.error(JSON.stringify(error, undefined, 2)); + process.exit(1); + } +}; + +export const getHomePage: getHomePageReturn = async () => { + const rawHomePage = await fetchHomepage(); + const homePage: HomePage = rawHomePage.nodeByUri; + return homePage; +}; diff --git a/src/styles/Home.module.css b/src/styles/Home.module.css deleted file mode 100644 index eb806ad..0000000 --- a/src/styles/Home.module.css +++ /dev/null @@ -1,116 +0,0 @@ -.container { - padding: 0 2rem; -} - -.main { - min-height: 100vh; - padding: 4rem 0; - flex: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.footer { - display: flex; - flex: 1; - padding: 2rem 0; - border-top: 1px solid #eaeaea; - justify-content: center; - align-items: center; -} - -.footer a { - display: flex; - justify-content: center; - align-items: center; - flex-grow: 1; -} - -.title a { - color: #0070f3; - text-decoration: none; -} - -.title a:hover, -.title a:focus, -.title a:active { - text-decoration: underline; -} - -.title { - margin: 0; - line-height: 1.15; - font-size: 4rem; -} - -.title, -.description { - text-align: center; -} - -.description { - margin: 4rem 0; - line-height: 1.5; - font-size: 1.5rem; -} - -.code { - background: #fafafa; - border-radius: 5px; - padding: 0.75rem; - font-size: 1.1rem; - font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, - Bitstream Vera Sans Mono, Courier New, monospace; -} - -.grid { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - max-width: 800px; -} - -.card { - margin: 1rem; - padding: 1.5rem; - text-align: left; - color: inherit; - text-decoration: none; - border: 1px solid #eaeaea; - border-radius: 10px; - transition: color 0.15s ease, border-color 0.15s ease; - max-width: 300px; -} - -.card:hover, -.card:focus, -.card:active { - color: #0070f3; - border-color: #0070f3; -} - -.card h2 { - margin: 0 0 1rem; - font-size: 1.5rem; -} - -.card p { - margin: 0; - font-size: 1.25rem; - line-height: 1.5; -} - -.logo { - height: 1em; - margin-left: 0.5rem; -} - -@media (max-width: 600px) { - .grid { - width: 100%; - flex-direction: column; - } -} diff --git a/src/styles/base/_typography.scss b/src/styles/base/_typography.scss index 61d7616..39f0bfa 100644 --- a/src/styles/base/_typography.scss +++ b/src/styles/base/_typography.scss @@ -1,3 +1,4 @@ +.greetings, h1 { font-size: var(--font-size-3xl); } @@ -23,6 +24,7 @@ h6 { font-size: var(--font-size-md); } +.greetings, h1, h2, h3, @@ -33,7 +35,14 @@ h6 { font-family: var(--font-family-secondary); font-weight: 500; margin: 0 0 var(--spacing-sm); +} +h1, +h2, +h3, +h4, +h5, +h6 { * + { h2, h3, diff --git a/src/ts/types/app.ts b/src/ts/types/app.ts index b663812..488fe6e 100644 --- a/src/ts/types/app.ts +++ b/src/ts/types/app.ts @@ -2,7 +2,7 @@ import { NextPage } from 'next'; import { AppProps } from 'next/app'; import { ReactElement, ReactNode } from 'react'; -export type NextPageWithLayout = NextPage & { +export type NextPageWithLayout

= NextPage

& { getLayout?: (page: ReactElement) => ReactNode; }; diff --git a/src/ts/types/homepage.ts b/src/ts/types/homepage.ts new file mode 100644 index 0000000..404aa38 --- /dev/null +++ b/src/ts/types/homepage.ts @@ -0,0 +1,19 @@ +export type fetchHomePageReturn = () => Promise; + +export type HomePageResponse = { + nodeByUri: { + id: string; + content: string; + }; +}; + +export type getHomePageReturn = () => Promise; + +export type HomePage = { + id: string; + content: string; +}; + +export type HomePageProps = { + data: HomePage; +}; -- cgit v1.2.3