Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: allow per-page layout #477

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/components/Blog/BlogHome/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import Card from '@/components/Blog/Card'
import FeaturedPost from '@/components/Blog/FeaturedPost'
import SearchFilterResults from '@/components/Blog/SearchFilterResults'
import type { TypeBlogHomeSkeleton } from '@/contentful/types'
import type { Entry } from 'contentful'
import { isEntryTypePost } from '@/lib/typeGuards'
import { useClientEntry } from '@/hooks/useClientEntry'
import type { PostEntryCollection } from '@/config/types'
import type { BlogHomeEntry, PostEntryCollection } from '@/config/types'

const categories = ['Announcements', 'Ecosystem', 'Community', 'Insights', 'Build']

const TRENDING_POSTS_COUNT = 3

export type BlogHomeEntry = Entry<TypeBlogHomeSkeleton, undefined, string>

export type BlogHomeProps = {
blogHome: BlogHomeEntry
allPosts: PostEntryCollection
Expand Down
2 changes: 1 addition & 1 deletion src/components/Blog/Card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { calculateReadingTimeInMin } from '@/components/Blog/utils/calculateRead
import Tags from '@/components/Blog/Tags'
import CategoryIcon from '@/public/images/Blog/category-icon.svg'
import { isAsset } from '@/lib/typeGuards'
import { type BlogPostEntry } from '@/components/Blog/Post'
import type { BlogPostEntry } from '@/config/types'
import { AppRoutes } from '@/config/routes'

const Card = (props: BlogPostEntry) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Blog/FeaturedPost/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Box, Grid, Link, Typography } from '@mui/material'
import css from './styles.module.css'
import { formatBlogDate } from '@/components/Blog/utils/formatBlogDate'
import { calculateReadingTimeInMin } from '@/components/Blog/utils/calculateReadingTime'
import { type BlogPostEntry } from '@/components/Blog/Post'
import type { BlogPostEntry } from '@/config/types'
import { isAsset } from '@/lib/typeGuards'
import CategoryIcon from '@/public/images/Blog/category-icon.svg'
import { AppRoutes } from '@/config/routes'
Expand Down
9 changes: 6 additions & 3 deletions src/components/Blog/Post/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Image from 'next/image'
import { Box, Button, Container, Divider, Grid, Typography } from '@mui/material'
import { type Entry } from 'contentful'
import type { TypeAuthorSkeleton, TypePostSkeleton } from '@/contentful/types'
import type { TypeAuthorSkeleton } from '@/contentful/types'
import { formatBlogDate } from '@/components/Blog/utils/formatBlogDate'
import { calculateReadingTimeInMin } from '@/components/Blog/utils/calculateReadingTime'
import { isAsset, isEntryTypeAuthor, isEntryTypePost } from '@/lib/typeGuards'
Expand All @@ -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 { BlogPostEntry } from '@/config/types'

export type BlogPostEntry = Entry<TypePostSkeleton, undefined, string>
export type BlogPostProps = {
blogPost: BlogPostEntry
}

const BlogPost = ({ blogPost }: { 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
2 changes: 1 addition & 1 deletion src/components/Pressroom/AboutUs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Box, Typography } from '@mui/material'
// const TOTAL_ASSETS_STORED = 'https://dune.com/queries/2893829/4821383'
const TOTAL_ASSETS_FALLBACK = '$100B+'

const AboutUs = ({ totalAssets }: { totalAssets: number }) => {
const AboutUs = ({ totalAssets }: { totalAssets: number | null }) => {
const totalAssetsStr = totalAssets ? `~$${formatValue(totalAssets)}` : TOTAL_ASSETS_FALLBACK
// const totalAssetsLink = (
// <a href={TOTAL_ASSETS_STORED} target="_blank" rel="noreferrer">
Expand Down
7 changes: 2 additions & 5 deletions src/components/Pressroom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,15 @@ import {
isEntryTypeSimpleBaseBlock,
} from '@/lib/typeGuards'
import { Container } from '@mui/material'
import type { Entry } from 'contentful'
import { useClientEntry } from '@/hooks/useClientEntry'
import type { PostEntryCollection } from '@/config/types'
import type { PostEntryCollection, PressRoomEntry } from '@/config/types'
import { isPublishedPressRelease } from '@/lib/contentful/isPressRelease'
import { useAllPosts } from '@/hooks/useAllPosts'

export type PressRoomEntry = Entry<TypePressRoomSkeleton, undefined, string>

export type PressRoomProps = {
pressRoom: PressRoomEntry
allPosts: PostEntryCollection
totalAssets: number
totalAssets: number | null
}

const PressRoom = ({ pressRoom, allPosts, totalAssets }: PressRoomProps) => {
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
5 changes: 5 additions & 0 deletions src/config/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import type {
TypeBaseBlockSkeleton,
TypeBlogHomeSkeleton,
TypeButtonSkeleton,
TypeLandingPageSkeleton,
TypePostSkeleton,
TypePressRoomSkeleton,
} from '@/contentful/types'
import type { Entry, EntryCollection } from 'contentful'

export type BaseBlockEntry = Entry<TypeBaseBlockSkeleton, undefined, string>
export type ButtonEntry = Entry<TypeButtonSkeleton, undefined, string>
export type LandingPageEntry = Entry<TypeLandingPageSkeleton, undefined, string>
export type PressRoomEntry = Entry<TypePressRoomSkeleton, undefined, string>
export type BlogHomeEntry = Entry<TypeBlogHomeSkeleton, undefined, string>
export type BlogPostEntry = Entry<TypePostSkeleton, undefined, string>
export type PostEntryCollection = EntryCollection<TypePostSkeleton, undefined, string>
2 changes: 1 addition & 1 deletion src/hooks/useBlogPost.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import useSWR from 'swr'
import client from '@/lib/contentful'
import { type BlogPostEntry } from '@/components/Blog/Post'
import type { BlogPostEntry } from '@/config/types'
import { type TypePostSkeleton } from '@/contentful/types'

const postFetcher = (id: string) => client.getEntry<TypePostSkeleton>(id)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/contentful/__test__/isPressRelease.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isPressReleasePost, isPublishedPressRelease } from '@/lib/contentful/isPressRelease'
import type { BlogPostEntry } from '@/components/Blog/Post'
import type { BlogPostEntry } from '@/config/types'
import type { TypePostFields } from '@/contentful/types'

describe('isPressReleasePost', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/contentful/isDraft.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import type { BlogPostEntry } from '@/components/Blog/Post'
import type { BlogPostEntry } from '@/config/types'

export const isDraft = (post: BlogPostEntry) => post.fields.isDraft
2 changes: 1 addition & 1 deletion src/lib/contentful/isPressRelease.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { containsTag, PRESS_RELEASE_TAG } from '@/lib/containsTag'
import { isDraft } from '@/lib/contentful/isDraft'
import type { BlogPostEntry } from '@/components/Blog/Post'
import type { BlogPostEntry } from '@/config/types'

export const isPressReleasePost = (post: BlogPostEntry) => containsTag(post.fields.tags, PRESS_RELEASE_TAG)

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
Loading