Skip to content
Draft
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
115 changes: 106 additions & 9 deletions packages/website/components/netlifyPartial.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,119 @@
import { MDXRemote } from 'next-mdx-remote'
import { useState, useEffect } from 'react'
import React, { useState, useEffect } from 'react'
import Loading from './loading'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'

/*
* There are two ways we can load content from the CMS as a partial
*
* Compiled Content
* This takes compiled JSX from the CMS and plugs it into the <MDXRemote/> component as is.
*
* Templates with Metadata and Compiled Content
* For more complex content that needs more control and styling, we can use a template while passing in
* metadata from the frontmatter section of the CMS markdown into a custom React component.
*
* Template Naming Convention
* The template name corresponds to the content type from the CMS. For the image-grids content
* found at the api URI of https://blog.nft.storage/api/partials/image-grids/my-md-content,
* the template name would be 'image-grids' and should be added to the templates object
* as templates['image-grids']. Other content type examples could be
* templates['faq'], templates['my-new-type']
*
* All data from the frontmatter can be found in the meta property as well as the
* main body content that can be found in meta.body. The body content can be
* rendered like <MDXRemote {...meta.body} />
*/

/**
* Templates
* @template {Object<string,any>} T
* @param {T} obj
*/

/** @type {any} */
const templates = {}
/**
* Image Grid Template
* @param {Object} meta
*/
templates['image-grids'] = function (
/** @type {{
description: String | undefined;
images: [];
footer: String | undefined
}} */ meta
) {
return (
<div className="max-w-4xl mx-auto py-8 px-6 sm:px-16">
{meta.description && (
<ReactMarkdown
children={meta.description}
remarkPlugins={[remarkGfm]}
className="text-center mt-0 chicagoflf"
/>
)}
<div className="grid grid-cols-2 sm:grid-cols-[repeat(auto-fit,_minmax(150px,_1fr))] gap-4 p-5 justify-center mx-auto">
{meta.images.map(
(/** @type {{ src: string; alt: string | undefined; }} */ image) => (
<img
className="w-full h-[80px] object-contain object-center !border !border-solid !border-gray-200 rounded !py-4 !px-6 select-none mx-auto"
src={`${image.src}`}
alt={image.alt}
width="100%"
height={80}
/>
)
)}
</div>
{meta.footer && (
<ReactMarkdown
children={meta.footer}
remarkPlugins={[remarkGfm]}
className="text-center chicagoflf"
/>
)}
{/* For future reference, you can render main body content like so */}
{/*
{meta.body &&
<MDXRemote {...meta.body} />
}
*/}
</div>
)
}

/**
* @typedef {Object} NetlifyPartialProps
* @prop {string} [route]
* @prop {string} [template]
* @prop {string} [className]
* @prop {JSX.Element} [fallback]
*/

/**
*
* @param {NetlifyPartialProps} props
* @returns {JSX.Element}
*/
export default function NetlifyPartial({ route, className, fallback }) {
export default function NetlifyPartial({
route,
template,
className,
fallback,
}) {
/** @type [any, null | any] */
const [content, setContent] = useState()
/** @type [any, null | any] */
const [meta, setMeta] = useState()
const [error, setError] = useState(false)
useEffect(() => {
// TODO: Update fallback when we have the blog in production.
const host =
process.env.NEXT_PUBLIC_NETLIFY_CMS_ENDPOINT || 'https://blog.nft.storage'
const host = process.env.NEXT_PUBLIC_NETLIFY_CMS_ENDPOINT
fetch(`${host}/api/partials/${route}`)
.then(async (response) => {
return await response.text()
})
.then((text) => {
const obj = JSON.parse(text)
setMeta(obj.props.partial.meta)
setContent(obj.props.partial.content)
})
.catch((e) => {
Expand All @@ -41,7 +127,7 @@ export default function NetlifyPartial({ route, className, fallback }) {
}
return (
<div className={className}>
<p>An unexpected error occured.</p>
<p>An unexpected error occurred.</p>
</div>
)
}
Expand All @@ -54,6 +140,17 @@ export default function NetlifyPartial({ route, className, fallback }) {
)
}

{
if (meta && template && templates[template]) {
let TemplateComponent = templates[template]
return (
<div className={className}>
<TemplateComponent {...meta} body={content} />
</div>
)
}
}

return (
content && (
<div className={className}>
Expand Down
1 change: 1 addition & 0 deletions packages/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"react-dom": "17.0.2",
"react-icons": "^4.3.1",
"react-if": "4.0.1",
"react-markdown": "^8.0.4",
"react-query": "^3.34.15",
"react-tiny-popover": "^7.0.1",
"swagger-ui-react": "^4.1.3",
Expand Down
6 changes: 6 additions & 0 deletions packages/website/pages/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,12 @@ export default function Stats({ logos }) {
className="netlify-partial-trusted-by-stats-page max-w-4xl mx-auto py-8 px-6 sm:px-16 text-center chicagoflf"
fallback={<TrustedBy logos={logos} />}
/>
{/* <NetlifyPartial
route="image-grids/trusted-by-home-page"
template="image-grids"
className="netlify-partial-trusted-by-stats-page max-w-4xl mx-auto py-8 px-6 sm:px-16 text-center chicagoflf"
fallback={<TrustedBy logos={logos} />}
/> */}
</div>
</div>
</div>
Expand Down
37 changes: 24 additions & 13 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4875,7 +4875,7 @@
resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601"
integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==

"@types/prop-types@*":
"@types/prop-types@*", "@types/prop-types@^15.0.0":
version "15.7.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
Expand Down Expand Up @@ -16834,16 +16834,11 @@ prettier-linter-helpers@^1.0.0:
dependencies:
fast-diff "^1.1.2"

prettier@2.5.1, prettier@^2.5.1:
prettier@2.5.1, "prettier@>=2.2.1 <=2.3.0", prettier@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a"
integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==

"prettier@>=2.2.1 <=2.3.0":
version "2.3.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18"
integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==

pretty-error@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6"
Expand Down Expand Up @@ -17384,6 +17379,27 @@ react-is@^18.0.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==

react-markdown@^8.0.4:
version "8.0.4"
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.4.tgz#b5ff1f0f29ead71a7a6f98815eb1a70bcc2a036e"
integrity sha512-2oxHa6oDxc1apg/Gnc1Goh06t3B617xeywqI/92wmDV9FELI6ayRkwge7w7DoEqM0gRpZGTNU6xQG+YpJISnVg==
dependencies:
"@types/hast" "^2.0.0"
"@types/prop-types" "^15.0.0"
"@types/unist" "^2.0.0"
comma-separated-tokens "^2.0.0"
hast-util-whitespace "^2.0.0"
prop-types "^15.0.0"
property-information "^6.0.0"
react-is "^18.0.0"
remark-parse "^10.0.0"
remark-rehype "^10.0.0"
space-separated-tokens "^2.0.0"
style-to-object "^0.3.0"
unified "^10.0.0"
unist-util-visit "^4.0.0"
vfile "^5.0.0"

react-merge-refs@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06"
Expand Down Expand Up @@ -20016,12 +20032,7 @@ typedoc@^0.22.14:
minimatch "^5.1.0"
shiki "^0.10.1"

typescript@4.4.4:
version "4.4.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==

typescript@4.5.3:
typescript@4.4.4, typescript@4.5.3:
version "4.5.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c"
integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==
Expand Down