diff --git a/docs/keystatic.config.tsx b/docs/keystatic.config.tsx index fb6d786f3..c32c2dc27 100644 --- a/docs/keystatic.config.tsx +++ b/docs/keystatic.config.tsx @@ -89,7 +89,7 @@ export default config({ name: 'Keystatic Docs', }, navigation: { - Pages: ['pages', 'blog', 'projects'], + Pages: ['pages', 'blog', 'projects', 'resources'], Config: ['authors', 'navigation'], Experimental: ['pagesWithMarkdocField'], }, @@ -261,6 +261,74 @@ export default config({ }, }), + // ------------------------------ + // Resources + // ------------------------------ + resources: collection({ + label: 'Resources', + path: 'src/content/resources/*', + slugField: 'title', + schema: { + title: fields.slug({ name: { label: 'Title' } }), + type: fields.conditional( + fields.select({ + label: 'Resource type', + options: [ + { label: 'YouTube video', value: 'youtube-video' }, + { label: 'Article', value: 'article' }, + ], + defaultValue: 'youtube-video', + }), + { + 'youtube-video': fields.object({ + videoId: fields.text({ + label: 'Video ID', + description: 'The ID of the video (not the URL!)', + validation: { length: { min: 1 } }, + }), + thumbnail: fields.cloudImage({ + label: 'Video thumbnail', + description: 'A 16/9 thumbnail image for the video.', + }), + kind: fields.select({ + label: 'Video kind', + options: [ + { label: 'Talk', value: 'talk' }, + { label: 'Screencast', value: 'screencast' }, + ], + defaultValue: 'screencast', + }), + description: fields.text({ + label: 'Video description', + multiline: true, + validation: { length: { min: 1 } }, + }), + }), + article: fields.object({ + url: fields.url({ + label: 'Article URL', + validation: { isRequired: true }, + }), + authorName: fields.text({ + label: 'Author name', + validation: { length: { min: 1 } }, + }), + description: fields.text({ + label: 'Article description', + multiline: true, + }), + }), + } + ), + sortIndex: fields.integer({ + label: 'Sort index', + description: + 'A number value to sort items (low to high) on the front end.', + defaultValue: 10, + }), + }, + }), + // ------------------------------ // For testing purposes only // ------------------------------ diff --git a/docs/src/app/(public)/resources/layout.tsx b/docs/src/app/(public)/resources/layout.tsx new file mode 100644 index 000000000..080aec45f --- /dev/null +++ b/docs/src/app/(public)/resources/layout.tsx @@ -0,0 +1,48 @@ +import { Main } from '../../../components/main'; +import Footer from '../../../components/footer'; + +export const metadata = { + title: { + template: '%s - Resources | Keystatic', + default: 'Resources', + }, + description: + 'A collection of videos, talks, articles and other resources to help you learn Keystatic and dig deeper.', + openGraph: { + title: 'Resources', + description: + 'A collection of videos, talks, articles and other resources to help you learn Keystatic and dig deeper.', + images: [ + { + url: '/og?title=Resources', + }, + ], + siteName: 'Keystatic', + type: 'website', + url: 'https://keystatic.com/resources', + }, + twitter: { + card: 'summary_large_image', + title: 'Resources', + description: + 'A collection of videos, talks, articles and other resources to help you learn Keystatic and dig deeper.', + site: '@thekeystatic', + }, +}; + +export default async function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> +
+
+
{children}
+
+
+