Skip to content

Commit

Permalink
refactor: let a component define a page layout to overwrite the default
Browse files Browse the repository at this point in the history
  • Loading branch information
DiogoSoaress committed Oct 16, 2024
1 parent 448ea7e commit 239318d
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 34 deletions.
9 changes: 6 additions & 3 deletions src/components/Blog/Post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ import css from '../styles.module.css'
import { PRESS_RELEASE_TAG, containsTag } from '@/lib/containsTag'
import { COMMS_EMAIL } from '@/config/constants'
import { useBlogPost } from '@/hooks/useBlogPost'
import type { InferGetStaticPropsType } from 'next'
import type { getStaticProps } from '@/pages/blog/[slug]'
import type { BlogPostEntry } from '@/config/types'

const BlogPost = ({ blogPost }: InferGetStaticPropsType<typeof getStaticProps>) => {
export type BlogPostProps = {
blogPost: BlogPostEntry
}

const BlogPost = ({ blogPost }: BlogPostProps) => {
const { data: post } = useBlogPost(blogPost.sys.id, blogPost)

const { title, excerpt, content, coverImage, authors, tags, category, date, relatedPosts, metaTags } = post.fields
Expand Down
6 changes: 5 additions & 1 deletion src/components/common/Page/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { isEntryType, isEntryTypeBaseBlock } from '@/lib/typeGuards'
import MetaTags from '@/components/common/MetaTagsContentful'
import { type LandingPageEntry } from '@/config/types'

const Page = ({ landingPage }: { landingPage: LandingPageEntry }) => {
export type LandingPageProps = {
landingPage: LandingPageEntry
}

const Page = ({ landingPage }: LandingPageProps) => {
const { metaTags, content } = landingPage.fields

return (
Expand Down
12 changes: 1 addition & 11 deletions src/components/common/PageLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
import { type ReactElement } from 'react'
import Header from '@/components/common/Header'
import HeaderCampaigns from '@/components/common/HeaderCampaigns'
import Footer from '@/components/common/Footer'
import css from './styles.module.css'
import { useRouter } from 'next/router'

const PageLayout = ({ children }: { children: ReactElement }): ReactElement => {
const router = useRouter()

const selectHeader = () => {
const isCampaignsPage = router.pathname.startsWith('/campaigns')

return isCampaignsPage ? <HeaderCampaigns /> : <Header />
}

return (
<div className={css.container}>
{selectHeader()}
<Header />

{children}

Expand Down
9 changes: 4 additions & 5 deletions src/pages/[slug].tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import type { GetStaticPaths, GetStaticProps } from 'next'
import type { GetStaticPaths, GetStaticProps, InferGetStaticPropsType, NextPage } from 'next'
import client from '@/lib/contentful'
import { type TypeLandingPageSkeleton } from '@/contentful/types'
import Page from '@/components/common/Page'
import { type LandingPageEntry } from '@/config/types'
import Page, { type LandingPageProps } from '@/components/common/Page'

const LandingPage = (props: { landingPage: LandingPageEntry }) => {
const LandingPage: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
if (!props.landingPage) return null

return <Page {...props} />
}

export const getStaticProps: GetStaticProps = async ({ params }) => {
export const getStaticProps: GetStaticProps<LandingPageProps> = async ({ params }) => {
const slug = params?.slug as string

const landingPageEntries = await client.getEntries<TypeLandingPageSkeleton>({
Expand Down
17 changes: 11 additions & 6 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { CssBaseline } from '@mui/material'
import { CacheProvider } from '@emotion/react'
import type { EmotionCache } from '@emotion/react'
import type { AppProps } from 'next/app'
import type { ReactElement } from 'react'
import type { ReactElement, ReactNode } from 'react'
import type { NextPage } from 'next'

import { createEmotionCache } from '@/styles/emotion'
import { CookieBannerContextProvider } from '@/contexts/CookieBannerContext'
Expand Down Expand Up @@ -42,13 +43,21 @@ const InitHooks = () => {
return null
}

export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode
}

const App = ({
Component,
pageProps,
emotionCache = clientSideEmotionCache,
}: AppProps & {
Component: NextPageWithLayout
emotionCache?: EmotionCache
}): ReactElement => {
// Use the layout defined at the page level, if available or the default layout
const getLayout = Component.getLayout ?? ((page) => <PageLayout>{page}</PageLayout>)

return (
<CacheProvider value={emotionCache}>
<CssVarsProvider theme={cssVarsTheme}>
Expand All @@ -57,11 +66,7 @@ const App = ({
<CookieBannerContextProvider>
<InitHooks />

<SearchParamsContextProvider>
<PageLayout>
<Component {...pageProps} />
</PageLayout>
</SearchParamsContextProvider>
<SearchParamsContextProvider>{getLayout(<Component {...pageProps} />)}</SearchParamsContextProvider>

<CookieBanner />
</CookieBannerContextProvider>
Expand Down
8 changes: 4 additions & 4 deletions src/pages/blog/[slug].tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import BlogPost, { type BlogPostEntry } from '@/components/Blog/Post'
import BlogPost, { type BlogPostProps } from '@/components/Blog/Post'
import { type TypePostSkeleton } from '@/contentful/types'
import client from '@/lib/contentful'
import type { GetStaticProps } from 'next'
import type { GetStaticProps, InferGetStaticPropsType, NextPage } from 'next'

const Page = (props: { blogPost: BlogPostEntry }) => {
const Page: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
if (!props.blogPost) return null

return <BlogPost {...props} />
}

export const getStaticProps: GetStaticProps = async ({ params }) => {
export const getStaticProps: GetStaticProps<BlogPostProps> = async ({ params }) => {
const slug = params?.slug as string

const content = await client.getEntries<TypePostSkeleton>({
Expand Down
5 changes: 3 additions & 2 deletions src/pages/blog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import client from '@/lib/contentful'
import BlogHome, { type BlogHomeProps } from '@/components/Blog/BlogHome'
import type { TypeBlogHomeSkeleton, TypePostSkeleton } from '@/contentful/types'
import { isEntryTypePost } from '@/lib/typeGuards'
import type { GetStaticProps, InferGetStaticPropsType, NextPage } from 'next'

const Blog = (props: BlogHomeProps) => {
const Blog: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
return <BlogHome {...props} />
}

export const getStaticProps = async () => {
export const getStaticProps: GetStaticProps<BlogHomeProps> = async () => {
const allPosts = await client.getEntries<TypePostSkeleton>({
content_type: 'post',
// order by date, most recent first
Expand Down
5 changes: 3 additions & 2 deletions src/pages/press.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import client from '@/lib/contentful'
import PressRoom, { type PressRoomProps } from '@/components/Pressroom'
import type { TypePressRoomSkeleton, TypePostSkeleton } from '@/contentful/types'
import { fetchTotalAssets } from '@/hooks/useSafeStats'
import type { GetStaticProps, InferGetStaticPropsType, NextPage } from 'next'

const PressroomPage = (props: PressRoomProps) => {
const PressroomPage: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
return <PressRoom {...props} />
}

export const getStaticProps = async () => {
export const getStaticProps: GetStaticProps<PressRoomProps> = async () => {
const allPosts = await client.getEntries<TypePostSkeleton>({
content_type: 'post',
// order by date, most recent first
Expand Down

0 comments on commit 239318d

Please sign in to comment.