-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
289 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import RichText from './RichText'; | ||
|
||
export default function Banner({ className, block }) { | ||
const { heading, imagePosition, backgroundColor, style, content, image } = block; | ||
|
||
const bgClass = style == 'light' ? `bg-${backgroundColor}-200` : `bg-${backgroundColor}-800`; | ||
const textColorClass = style == 'light' ? 'text-slate-800' : 'text-slate-200'; | ||
|
||
const bannerImg = ( | ||
<div> | ||
<img src={`${image?.url}?w=750`} alt={image?.description} /> | ||
</div> | ||
); | ||
|
||
return ( | ||
<div className={`${className} rounded-2xl p-12 md:grid md:grid-cols-2 md:gap-8 ${bgClass}`}> | ||
{imagePosition === 'left' && bannerImg} | ||
<div className={`${textColorClass}`}> | ||
<h3 className="mb-8 text-3xl font-bold">{heading}</h3> | ||
<RichText className={`text-xl ${textColorClass}`} content={content} /> | ||
</div> | ||
{imagePosition === 'right' && bannerImg} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import ContentBlock from 'components/cms/ContentBlock'; | ||
|
||
export default function CmsContent({ blocks, className = '' }) { | ||
return ( | ||
<div className={`${className} grid grid-cols-6 gap-6`}> | ||
{blocks.map((block) => ( | ||
<ContentBlock key={block.sys.id} block={block} /> | ||
))} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Banner from 'components/cms/Banner'; | ||
import ImageBlock from 'components/cms/ImageBlock'; | ||
import RichText from 'components/cms/RichText'; | ||
import SimpleText from 'components/cms/SimpleText'; | ||
|
||
const BLOCK_TYPE_BANNER = 'BlockBanner'; | ||
const BLOCK_TYPE_RICHTEXT = 'BlockRichText'; | ||
const BLOCK_TYPE_SIMPLETEXT = 'BlockSimpleText'; | ||
const BLOCK_TYPE_IMG = 'BlockImage'; | ||
|
||
export default function ContentBlock({ block }) { | ||
switch (block['__typename']) { | ||
case BLOCK_TYPE_BANNER: | ||
return <Banner className="col-span-6 mx-auto my-6 max-w-screen-lg" block={block} />; | ||
|
||
case BLOCK_TYPE_RICHTEXT: | ||
return ( | ||
<RichText className="col-span-6 mx-auto my-6 max-w-screen-md" content={block.content} /> | ||
); | ||
|
||
case BLOCK_TYPE_SIMPLETEXT: | ||
return <SimpleText className="my-6 max-w-screen-md" block={block} />; | ||
|
||
case BLOCK_TYPE_IMG: | ||
return <ImageBlock className="my-6" block={block} />; | ||
|
||
default: | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
export default function ImageBlock({ className, block }) { | ||
let sizeClass, imgSize; | ||
switch (block.size) { | ||
case 'full': | ||
sizeClass = 'col-span-6'; | ||
imgSize = 1000; | ||
break; | ||
|
||
case 'two-thirds': | ||
sizeClass = 'col-span-4'; | ||
imgSize = 700; | ||
break; | ||
|
||
case 'half': | ||
sizeClass = 'col-span-3'; | ||
imgSize = 500; | ||
break; | ||
|
||
case 'third': | ||
sizeClass = 'col-span-2'; | ||
imgSize = 400; | ||
break; | ||
|
||
default: | ||
sizeClass = null; | ||
} | ||
|
||
return ( | ||
<div className={`${className} ${sizeClass} mx-auto block`}> | ||
<img src={`${block.image?.url}?w=${imgSize}`} alt={block.image?.description} /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'; | ||
import { BLOCKS } from '@contentful/rich-text-types'; | ||
|
||
function RichTextAsset({ id, content }) { | ||
const assetLinks = content?.links?.assets?.block ?? []; | ||
|
||
const asset = assetLinks.find((asset) => asset.sys.id === id); | ||
|
||
return asset?.url ? ( | ||
<img className="mx-auto block" src={asset.url} alt={asset.description} /> | ||
) : null; | ||
} | ||
|
||
export default function RichText({ content, className }) { | ||
return ( | ||
<div className={`${className} prose dark:prose-invert`}> | ||
{documentToReactComponents(content.json, { | ||
renderNode: { | ||
[BLOCKS.EMBEDDED_ASSET]: (node) => ( | ||
<RichTextAsset id={node.data.target.sys.id} content={content} /> | ||
) | ||
} | ||
})} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import RichText from './RichText'; | ||
|
||
export default function SimpleText({ className, block }) { | ||
let sizeClass; | ||
switch (block.size) { | ||
case 'full': | ||
sizeClass = 'col-span-6'; | ||
break; | ||
|
||
case 'two-thirds': | ||
sizeClass = 'col-span-4'; | ||
break; | ||
|
||
case 'half': | ||
sizeClass = 'col-span-3'; | ||
break; | ||
|
||
case 'third': | ||
sizeClass = 'col-span-2'; | ||
break; | ||
|
||
default: | ||
sizeClass = null; | ||
} | ||
|
||
return <RichText content={block.content} className={`${className} ${sizeClass}`} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
const QUERY_CONTENT = ` | ||
query ContentCollection( | ||
$type: String | ||
$slug: String | ||
) { | ||
categoryContentCollection( | ||
where: {slug: $slug, type: $type}, | ||
limit: 1 | ||
) { | ||
items { | ||
contentCollection(limit: 10) { | ||
items { | ||
__typename | ||
... on BlockBanner { | ||
sys { | ||
id | ||
} | ||
heading | ||
imagePosition | ||
backgroundColor | ||
style | ||
content { | ||
json | ||
} | ||
image { | ||
title | ||
description | ||
url | ||
} | ||
} | ||
... on BlockRichText { | ||
sys { | ||
id | ||
} | ||
content { | ||
json | ||
links { | ||
assets { | ||
block { | ||
title | ||
description | ||
url | ||
sys { | ||
id | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
... on BlockSimpleText { | ||
sys { | ||
id | ||
} | ||
size | ||
content { | ||
json | ||
} | ||
} | ||
... on BlockImage { | ||
sys { | ||
id | ||
} | ||
size | ||
image { | ||
title | ||
description | ||
url | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
`; | ||
|
||
const extractCategoryContent = (responseData) => { | ||
return responseData?.data?.categoryContentCollection?.items?.[0]?.contentCollection?.items; | ||
}; | ||
|
||
async function fetchGraphQL(query, variables, cache = 'force-cache') { | ||
const fetchOpts = { | ||
method: 'POST', | ||
headers: { | ||
Accept: 'application/json', | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${process.env.CONTENTFUL_ACCESS_TOKEN}` | ||
}, | ||
body: JSON.stringify({ | ||
...(query && { query }), | ||
...(variables && { variables }) | ||
}) | ||
}; | ||
if (cache !== 'no-store') { | ||
fetchOpts.next = { | ||
revalidate: parseInt(process.env.FETCH_REVALIDATE_TIME) | ||
}; | ||
} else { | ||
fetchOpts.cache = cache; | ||
} | ||
|
||
return fetch( | ||
`https://graphql.contentful.com/content/v1/spaces/${process.env.CONTENTFUL_SPACE_ID}`, | ||
fetchOpts | ||
).then((response) => response.json()); | ||
} | ||
|
||
export async function getContentBlocks(type, slug) { | ||
const blocks = await fetchGraphQL(QUERY_CONTENT, { type, slug }); | ||
return extractCategoryContent(blocks); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.