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

feat(Press room): use the latest press release in the Press Room landing page #432

Merged
merged 9 commits into from
Sep 24, 2024
2 changes: 1 addition & 1 deletion src/components/Blog/BlogHome/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const BlogHome = ({ blogHome, allPosts }: BlogHomeProps) => {
</Grid>
</Grid>

{isEntryTypePost(featured) && <FeaturedPost {...featured} />}
{isEntryTypePost(featured) && <FeaturedPost post={featured} />}

<Typography variant="h2" mt={{ xs: '60px', md: '100px' }}>
Trending
Expand Down
4 changes: 2 additions & 2 deletions src/components/Blog/FeaturedPost/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import CategoryIcon from '@/public/images/Blog/category-icon.svg'
import { AppRoutes } from '@/config/routes'
import { containsTag, PRESS_RELEASE_TAG } from '@/lib/containsTag'

const FeaturedPost = (props: BlogPostEntry) => {
const { slug, coverImage, category, date, title, excerpt, tags, content } = props.fields
const FeaturedPost = ({ post }: { post: BlogPostEntry }) => {
const { slug, coverImage, category, date, title, excerpt, tags, content } = post.fields

const isPressRelease = containsTag(tags, PRESS_RELEASE_TAG)

Expand Down
2 changes: 1 addition & 1 deletion src/components/Blog/SearchFilterResults/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ShowMoreButton from '@/components/common/ShowMoreButton'
import CategoryFilter from '@/components/common/CategoryFilter'
import { getPage } from '@/lib/getPage'
import { useAllPosts } from '@/hooks/useAllPosts'
import { isPressReleasePost } from '@/lib/containsTag'
import { isPressReleasePost } from '@/lib/contentful/isPressRelease'
import { isDraft } from '@/lib/contentful/isDraft'
import { isSelectedCategory } from '@/lib/contentful/isSelectedCategory'
import type { PostEntryCollection } from '@/config/types'
Expand Down
5 changes: 3 additions & 2 deletions src/components/Pressroom/PressReleases/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import ShowMoreButton from '@/components/common/ShowMoreButton'
import SearchIcon from '@/public/images/search.svg'
import CategoryFilter from '@/components/common/CategoryFilter'
import { PressroomIds } from '@/components/Pressroom/ContentsNavigation'
import { containsTag, isPressReleasePost } from '@/lib/containsTag'
import { containsTag } from '@/lib/containsTag'
import { getPage } from '@/lib/getPage'
import { useAllPosts } from '@/hooks/useAllPosts'
import type { PostEntryCollection } from '@/config/types'
import { isPublishedPressRelease } from '@/lib/contentful/isPressRelease'

const categories = ['Safe{Core}', 'Safe{Wallet}', 'Safe{DAO}', 'Ecosystem', 'Institutional', 'Internal']

Expand All @@ -23,7 +24,7 @@ const PressReleases = ({ allPosts }: { allPosts: PostEntryCollection }) => {
const { localAllPosts } = useAllPosts(allPosts)

const filteredPosts = useMemo(() => {
const pressPosts = localAllPosts.items.filter(isPressReleasePost)
const pressPosts = localAllPosts.items.filter(isPublishedPressRelease)

return !selectedTag ? pressPosts : pressPosts.filter((post) => containsTag(post.fields.tags, selectedTag))
}, [localAllPosts.items, selectedTag])
Expand Down
11 changes: 8 additions & 3 deletions src/components/Pressroom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ import {
isEntryType,
isEntryTypeBaseBlock,
isEntryTypeExternalURL,
isEntryTypePost,
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 { isPublishedPressRelease } from '@/lib/contentful/isPressRelease'
import { useAllPosts } from '@/hooks/useAllPosts'

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

Expand All @@ -36,8 +37,9 @@ export type PressRoomProps = {

const PressRoom = ({ pressRoom, allPosts, totalAssets }: PressRoomProps) => {
const { data: localPressRoom } = useClientEntry<TypePressRoomSkeleton, PressRoomEntry>(pressRoom.sys.id, pressRoom)
const { localAllPosts } = useAllPosts(allPosts)

const { metaTags, featured, numbers, investors, timeline, news, podcasts, videos } = localPressRoom.fields
const { metaTags, numbers, investors, timeline, news, podcasts, videos } = localPressRoom.fields

const numbersList = numbers.filter(isEntryTypeBaseBlock)
const investorsList = investors.filter(isAsset)
Expand All @@ -46,12 +48,15 @@ const PressRoom = ({ pressRoom, allPosts, totalAssets }: PressRoomProps) => {
const podcastsList = podcasts.filter(isEntryTypeExternalURL)
const videosList = videos.filter(isEntryTypeExternalURL)

// Get the most recent press release that is not a draft
const latestPressRelease = localAllPosts.items.find(isPublishedPressRelease)

return (
<>
{isEntryType(metaTags) && <MetaTags {...metaTags} />}
<Container>
<Hero />
{isEntryTypePost(featured) && <FeaturedPost {...featured} />}
{latestPressRelease && <FeaturedPost post={latestPressRelease} />}
<ContentsNavigation />
<AboutUs totalAssets={totalAssets} />
<Marquee items={numbersList} />
Expand Down
2 changes: 0 additions & 2 deletions src/contentful/types/TypePressRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import type { ChainModifiers, Entry, EntryFieldTypes, EntrySkeletonType, LocaleC
import type { TypeBaseBlockSkeleton } from './TypeBaseBlock'
import type { TypeExternalUrlSkeleton } from './TypeExternalUrl'
import type { TypeMetaTagsSkeleton } from './TypeMetaTags'
import type { TypePostSkeleton } from './TypePost'
import type { TypeSimpleBaseBlockSkeleton } from './TypeSimpleBaseBlock'

export interface TypePressRoomFields {
metaTags: EntryFieldTypes.EntryLink<TypeMetaTagsSkeleton>
featured: EntryFieldTypes.EntryLink<TypePostSkeleton>
numbers: EntryFieldTypes.Array<EntryFieldTypes.EntryLink<TypeBaseBlockSkeleton>>
investors: EntryFieldTypes.Array<EntryFieldTypes.AssetLink>
timeline: EntryFieldTypes.Array<EntryFieldTypes.EntryLink<TypeSimpleBaseBlockSkeleton>>
Expand Down
5 changes: 1 addition & 4 deletions src/lib/containsTag.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { type BlogPostEntry } from '@/components/Blog/Post'
import { type TagsType } from '@/components/Blog/Tags'
import { isEntryTypeTag } from '@/lib/typeGuards'
import type { TagsType } from '@/components/Blog/Tags'

export const PRESS_RELEASE_TAG = 'Press'

export const containsTag = (tags: TagsType, targetTag: string) => {
return !!tags?.filter(isEntryTypeTag)?.some((item) => item.fields.name === targetTag)
}

export const isPressReleasePost = (post: BlogPostEntry) => containsTag(post.fields.tags, PRESS_RELEASE_TAG)
115 changes: 115 additions & 0 deletions src/lib/contentful/__test__/isPressRelease.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { isPressReleasePost, isPublishedPressRelease } from '@/lib/contentful/isPressRelease'
import type { BlogPostEntry } from '@/components/Blog/Post'
import type { TypePostFields } from '@/contentful/types'

describe('isPressReleasePost', () => {
it('should return true if the post contains the press release tag', () => {
const post = {
fields: {
tags: [
{
fields: { name: 'Press' },
sys: {
contentType: {
sys: {
id: 'tag',
},
},
},
},
] as unknown as TypePostFields['tags'],
},
} as BlogPostEntry

expect(isPressReleasePost(post)).toBe(true)
})

it('should return false if the post does not contain the press release tag', () => {
const post = {
fields: {
tags: [
{
fields: { name: 'Dummy' },
sys: {
contentType: {
sys: {
id: 'tag',
},
},
},
},
] as unknown as TypePostFields['tags'],
},
} as BlogPostEntry

expect(isPressReleasePost(post)).toBe(false)
})
})

describe('isPublishedPressRelease', () => {
it('should return true if the post is a press release and is not a draft', () => {
const post = {
fields: {
isDraft: false,
tags: [
{
fields: { name: 'Press' },
sys: {
contentType: {
sys: {
id: 'tag',
},
},
},
},
] as unknown as TypePostFields['tags'],
},
} as BlogPostEntry

expect(isPublishedPressRelease(post)).toBe(true)
})

it('should return false if the post is a press release but is a draft', () => {
const post = {
fields: {
isDraft: true,
tags: [
{
fields: { name: 'Press' },
sys: {
contentType: {
sys: {
id: 'tag',
},
},
},
},
] as unknown as TypePostFields['tags'],
},
} as BlogPostEntry

expect(isPublishedPressRelease(post)).toBe(false)
})

it('should return false if the post is not a press release', () => {
const post = {
fields: {
isDraft: false,
tags: [
{
fields: { name: 'Safe{Wallet}' },
sys: {
contentType: {
sys: {
id: 'tag',
},
},
},
},
] as unknown as TypePostFields['tags'],
},
} as BlogPostEntry

expect(isPublishedPressRelease(post)).toBe(false)
})
})
7 changes: 7 additions & 0 deletions src/lib/contentful/isPressRelease.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { containsTag, PRESS_RELEASE_TAG } from '@/lib/containsTag'
import { isDraft } from '@/lib/contentful/isDraft'
import type { BlogPostEntry } from '@/components/Blog/Post'

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

export const isPublishedPressRelease = (post: BlogPostEntry) => isPressReleasePost(post) && !isDraft(post)
9 changes: 5 additions & 4 deletions src/pages/blog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ const Blog = (props: BlogHomeProps) => {
}

export const getStaticProps = async () => {
const postsEntries = await client.getEntries<TypePostSkeleton>({
const allPosts = await client.getEntries<TypePostSkeleton>({
content_type: 'post',
// order by date, most recent first
order: ['-fields.date'],
limit: 150,
})

const blogHomeEntries = await client.getEntries<TypeBlogHomeSkeleton>({
Expand All @@ -21,7 +22,7 @@ export const getStaticProps = async () => {

const blogHome = blogHomeEntries.items[0]

if (!blogHome || !postsEntries) {
if (!blogHome || !allPosts) {
return {
notFound: true,
}
Expand All @@ -32,12 +33,12 @@ export const getStaticProps = async () => {
delete blogHome.fields.featured.fields.relatedPosts
}
blogHome.fields.mostPopular.forEach((item: any) => delete item.fields.relatedPosts)
postsEntries.items.forEach((item: any) => delete item.fields.relatedPosts)
allPosts.items.forEach((item: any) => delete item.fields.relatedPosts)

return {
props: {
blogHome,
allPosts: postsEntries,
allPosts,
},
}
}
Expand Down
1 change: 1 addition & 0 deletions src/pages/press.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const getStaticProps = async () => {
content_type: 'post',
// order by date, most recent first
order: ['-fields.date'],
limit: 150,
})

const pressRoomEntries = await client.getEntries<TypePressRoomSkeleton>({
Expand Down
Loading