create-agntcms-app 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/dist/index.mjs +297 -0
- package/dist/template/.claude/settings.json +6 -0
- package/dist/template/.claude/skills/.gitkeep +0 -0
- package/dist/template/.claude-plugin/channel/server.mjs +254 -0
- package/dist/template/.claude-plugin/channel/server.ts +369 -0
- package/dist/template/.claude-plugin/plugin.json +17 -0
- package/dist/template/.mcp.json +8 -0
- package/dist/template/BRAND.md +49 -0
- package/dist/template/CLAUDE.md +157 -0
- package/dist/template/agntcms/config.ts +49 -0
- package/dist/template/agntcms/sections/ArticleBody/component.tsx +32 -0
- package/dist/template/agntcms/sections/ArticleBody/index.ts +10 -0
- package/dist/template/agntcms/sections/ArticleBody/schema.ts +5 -0
- package/dist/template/agntcms/sections/ArticleHero/component.tsx +87 -0
- package/dist/template/agntcms/sections/ArticleHero/index.ts +10 -0
- package/dist/template/agntcms/sections/ArticleHero/schema.ts +12 -0
- package/dist/template/agntcms/sections/Banner/component.tsx +83 -0
- package/dist/template/agntcms/sections/Banner/index.ts +10 -0
- package/dist/template/agntcms/sections/Banner/schema.ts +9 -0
- package/dist/template/agntcms/sections/BlogIndex/component.tsx +173 -0
- package/dist/template/agntcms/sections/BlogIndex/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogIndex/schema.ts +33 -0
- package/dist/template/agntcms/sections/BlogIndexHeader/component.tsx +44 -0
- package/dist/template/agntcms/sections/BlogIndexHeader/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogIndexHeader/schema.ts +8 -0
- package/dist/template/agntcms/sections/BlogPostBody/component.tsx +50 -0
- package/dist/template/agntcms/sections/BlogPostBody/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogPostBody/schema.ts +10 -0
- package/dist/template/agntcms/sections/BlogPostHero/component.tsx +88 -0
- package/dist/template/agntcms/sections/BlogPostHero/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogPostHero/schema.ts +35 -0
- package/dist/template/agntcms/sections/CaseStudies/component.tsx +92 -0
- package/dist/template/agntcms/sections/CaseStudies/index.ts +10 -0
- package/dist/template/agntcms/sections/CaseStudies/schema.ts +17 -0
- package/dist/template/agntcms/sections/ContactForm/component.tsx +119 -0
- package/dist/template/agntcms/sections/ContactForm/index.ts +10 -0
- package/dist/template/agntcms/sections/ContactForm/schema.ts +15 -0
- package/dist/template/agntcms/sections/DocsArticle/component.tsx +266 -0
- package/dist/template/agntcms/sections/DocsArticle/index.ts +10 -0
- package/dist/template/agntcms/sections/DocsArticle/schema.ts +33 -0
- package/dist/template/agntcms/sections/FAQ/component.tsx +57 -0
- package/dist/template/agntcms/sections/FAQ/index.ts +10 -0
- package/dist/template/agntcms/sections/FAQ/schema.ts +11 -0
- package/dist/template/agntcms/sections/FeatureGrid/component.tsx +117 -0
- package/dist/template/agntcms/sections/FeatureGrid/index.ts +10 -0
- package/dist/template/agntcms/sections/FeatureGrid/schema.ts +21 -0
- package/dist/template/agntcms/sections/FeaturedArticles/component.tsx +99 -0
- package/dist/template/agntcms/sections/FeaturedArticles/index.ts +10 -0
- package/dist/template/agntcms/sections/FeaturedArticles/schema.ts +17 -0
- package/dist/template/agntcms/sections/GettingStarted/component.tsx +116 -0
- package/dist/template/agntcms/sections/GettingStarted/index.ts +10 -0
- package/dist/template/agntcms/sections/GettingStarted/schema.ts +11 -0
- package/dist/template/agntcms/sections/Hero/component.tsx +148 -0
- package/dist/template/agntcms/sections/Hero/index.ts +10 -0
- package/dist/template/agntcms/sections/Hero/schema.ts +16 -0
- package/dist/template/agntcms/sections/HowItWorks/component.tsx +57 -0
- package/dist/template/agntcms/sections/HowItWorks/index.ts +10 -0
- package/dist/template/agntcms/sections/HowItWorks/schema.ts +11 -0
- package/dist/template/agntcms/sections/ImageText/component.tsx +110 -0
- package/dist/template/agntcms/sections/ImageText/index.ts +10 -0
- package/dist/template/agntcms/sections/ImageText/schema.ts +14 -0
- package/dist/template/agntcms/sections/LogoStrip/component.tsx +37 -0
- package/dist/template/agntcms/sections/LogoStrip/index.ts +10 -0
- package/dist/template/agntcms/sections/LogoStrip/schema.ts +6 -0
- package/dist/template/agntcms/sections/Newsletter/component.tsx +48 -0
- package/dist/template/agntcms/sections/Newsletter/index.ts +10 -0
- package/dist/template/agntcms/sections/Newsletter/schema.ts +8 -0
- package/dist/template/agntcms/sections/OpenSource/component.tsx +99 -0
- package/dist/template/agntcms/sections/OpenSource/index.ts +10 -0
- package/dist/template/agntcms/sections/OpenSource/schema.ts +13 -0
- package/dist/template/agntcms/sections/PainAnswer/component.tsx +81 -0
- package/dist/template/agntcms/sections/PainAnswer/index.ts +10 -0
- package/dist/template/agntcms/sections/PainAnswer/schema.ts +15 -0
- package/dist/template/agntcms/sections/PricingPlans/component.tsx +100 -0
- package/dist/template/agntcms/sections/PricingPlans/index.ts +10 -0
- package/dist/template/agntcms/sections/PricingPlans/schema.ts +13 -0
- package/dist/template/agntcms/sections/Problem/component.tsx +49 -0
- package/dist/template/agntcms/sections/Problem/index.ts +10 -0
- package/dist/template/agntcms/sections/Problem/schema.ts +12 -0
- package/dist/template/agntcms/sections/SiteFooter/component.tsx +88 -0
- package/dist/template/agntcms/sections/SiteFooter/index.ts +10 -0
- package/dist/template/agntcms/sections/SiteFooter/schema.ts +13 -0
- package/dist/template/agntcms/sections/SiteHeader/component.tsx +99 -0
- package/dist/template/agntcms/sections/SiteHeader/index.ts +10 -0
- package/dist/template/agntcms/sections/SiteHeader/schema.ts +14 -0
- package/dist/template/agntcms/sections/SiteMeta/component.tsx +26 -0
- package/dist/template/agntcms/sections/SiteMeta/index.ts +13 -0
- package/dist/template/agntcms/sections/SiteMeta/schema.ts +18 -0
- package/dist/template/agntcms/sections/TabbedFeatures/component.tsx +120 -0
- package/dist/template/agntcms/sections/TabbedFeatures/index.ts +10 -0
- package/dist/template/agntcms/sections/TabbedFeatures/schema.ts +13 -0
- package/dist/template/agntcms/sections/TeamGrid/component.tsx +77 -0
- package/dist/template/agntcms/sections/TeamGrid/index.ts +10 -0
- package/dist/template/agntcms/sections/TeamGrid/schema.ts +14 -0
- package/dist/template/agntcms/sections/Testimonials/component.tsx +76 -0
- package/dist/template/agntcms/sections/Testimonials/index.ts +10 -0
- package/dist/template/agntcms/sections/Testimonials/schema.ts +12 -0
- package/dist/template/agntcms/sections/WhatIsBuilt/component.tsx +86 -0
- package/dist/template/agntcms/sections/WhatIsBuilt/index.ts +10 -0
- package/dist/template/agntcms/sections/WhatIsBuilt/schema.ts +20 -0
- package/dist/template/agntcms/site-meta.ts +81 -0
- package/dist/template/app/[[...slug]]/page.tsx +123 -0
- package/dist/template/app/admin/AdminPageClient.tsx +77 -0
- package/dist/template/app/admin/AdminPageDynamic.tsx +24 -0
- package/dist/template/app/admin/page.tsx +14 -0
- package/dist/template/app/api/agntcms/_shared.ts +80 -0
- package/dist/template/app/api/agntcms/assets/route.ts +11 -0
- package/dist/template/app/api/agntcms/assets/upload/route.ts +11 -0
- package/dist/template/app/api/agntcms/draft/discard/route.ts +12 -0
- package/dist/template/app/api/agntcms/draft/list/route.ts +11 -0
- package/dist/template/app/api/agntcms/draft/publish/route.ts +11 -0
- package/dist/template/app/api/agntcms/draft/reorder/route.ts +10 -0
- package/dist/template/app/api/agntcms/draft/save/route.ts +11 -0
- package/dist/template/app/api/agntcms/events/route.ts +12 -0
- package/dist/template/app/api/agntcms/forms/delete/route.ts +17 -0
- package/dist/template/app/api/agntcms/forms/list/route.ts +24 -0
- package/dist/template/app/api/agntcms/forms/read/route.ts +23 -0
- package/dist/template/app/api/agntcms/forms/submit/route.ts +17 -0
- package/dist/template/app/api/agntcms/global/delete/route.ts +13 -0
- package/dist/template/app/api/agntcms/global/history/route.ts +10 -0
- package/dist/template/app/api/agntcms/global/list/route.ts +14 -0
- package/dist/template/app/api/agntcms/global/read/route.ts +11 -0
- package/dist/template/app/api/agntcms/global/rollback/route.ts +10 -0
- package/dist/template/app/api/agntcms/global/save/route.ts +14 -0
- package/dist/template/app/api/agntcms/mcp/route.ts +12 -0
- package/dist/template/app/api/agntcms/page/delete/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/duplicate/route.ts +11 -0
- package/dist/template/app/api/agntcms/page/history/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/list/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/read/route.ts +11 -0
- package/dist/template/app/api/agntcms/page/rename/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/rollback/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/unpublish/route.ts +11 -0
- package/dist/template/app/api/agntcms/preview/enter/route.ts +13 -0
- package/dist/template/app/api/agntcms/preview/exit/route.ts +10 -0
- package/dist/template/app/api/agntcms/preview/issue/route.ts +12 -0
- package/dist/template/app/api/agntcms/template/list/route.ts +15 -0
- package/dist/template/app/apple-icon.svg +9 -0
- package/dist/template/app/icon.svg +9 -0
- package/dist/template/app/layout.tsx +107 -0
- package/dist/template/app/not-found.tsx +75 -0
- package/dist/template/app/robots.ts +33 -0
- package/dist/template/app/sitemap.ts +49 -0
- package/dist/template/content/globals/site-footer.json +53 -0
- package/dist/template/content/globals/site-header.json +18 -0
- package/dist/template/content/globals/site-meta.json +13 -0
- package/dist/template/content/pages/404.json +34 -0
- package/dist/template/content/pages/about.json +307 -0
- package/dist/template/content/pages/article-editor.json +61 -0
- package/dist/template/content/pages/article-schemas.json +61 -0
- package/dist/template/content/pages/blog.json +162 -0
- package/dist/template/content/pages/contact.json +29 -0
- package/dist/template/content/pages/home.json +243 -0
- package/dist/template/content/pages/pricing.json +219 -0
- package/dist/template/content/pages/services.json +177 -0
- package/dist/template/fonts/Satoshi-Medium.woff2 +0 -0
- package/dist/template/fonts/Satoshi-Regular.woff2 +0 -0
- package/dist/template/next.config.ts +6 -0
- package/dist/template/package.json +36 -0
- package/dist/template/postcss.config.mjs +5 -0
- package/dist/template/public/assets/.gitkeep +0 -0
- package/dist/template/public/assets/0418d7ed21f57e7b9e0546725c92b8419daeaa355675d9070fab0c2013cf1524.jpg +0 -0
- package/dist/template/public/assets/0d0475f21aa96435a8ed3cdb2fddcc6278492e76ae842f569432454f4d33631a.jpg +0 -0
- package/dist/template/public/assets/27457a1adee2372030d9876b0d52c44d46be98843999935eaef2526b9b961f12.jpg +0 -0
- package/dist/template/public/assets/3855d91192f0c6120b01427b78ef84e52baa9f4b5a17d4271e41c1bfd95a5b0c.jpg +0 -0
- package/dist/template/public/assets/3b3b90c5084635b746be673ede92a328f002f5621a42c9a5cb89c5e2435652cb.jpg +0 -0
- package/dist/template/public/assets/3e76165a78fd3e7b8ed1e93dee50803ae11110c756c8c1c89229a2dec2bc0abf.jpg +0 -0
- package/dist/template/public/assets/4a3e28f85dc850c347ea0fd931696aa936a6bd45f193e7f1c9328b5896fb272c.jpg +0 -0
- package/dist/template/public/assets/579f67d5fd4c9106c6cdf2ef29f50df934ad0fc2b7849bac1e1cfb1e3f92303b.jpg +0 -0
- package/dist/template/public/assets/5b95209269661bb60fb250f1da682e05b9efa64dd42f350608b299e6bf1f2f35.jpg +0 -0
- package/dist/template/public/assets/5e04b46f8317ef95a7ddf85aedfe5c098a755f05056325d0251eccf95ce51172.jpg +0 -0
- package/dist/template/public/assets/6167a9164be2cf1183bdfdd4946bf9b908570e79e92a2380c25f0bb702422bbd.jpg +0 -0
- package/dist/template/public/assets/75e723ec316de28247924e5dfb73a4b266e10de605e749f150883d280ed8ed16.jpg +0 -0
- package/dist/template/public/assets/816a11e6a7245feaf51bbebf09d1bda3f125b334bc24fc3b8f47b5380a7b4294.jpg +0 -0
- package/dist/template/public/assets/81eba6f5654b8746a9b0cba1a9521a67f2b4afaaefc7c88d66dfab1461270d8f.jpg +0 -0
- package/dist/template/public/assets/82a2ce9e49361098f77a28755779dc5a7c026831cbd135175749c1304e21dacc.jpg +0 -0
- package/dist/template/public/assets/8d7b02ba277ba56bdafdbd47b01f7df6d993c714b4dc2305eb65a1307c09647d.jpg +0 -0
- package/dist/template/public/assets/b303185b471678e4d62f678a1549ee26022f4745407d08cae44ecb1c25352293.jpg +0 -0
- package/dist/template/public/assets/b69b49169c11546100d6dd5280073bc0d84cbbcc6d33fa01ecf6a5866fa42237.jpg +0 -0
- package/dist/template/public/assets/c4d2f0d1a310e457ac722a399693652e3c86c55b294243d5ffc679394e12f9d1.jpg +0 -0
- package/dist/template/public/assets/cae09f4729f8a348b67267c2f2a550be0f3bfa420689afe1a5cf8b7e2b146238.png +0 -0
- package/dist/template/public/assets/cb3acf58b57417a4b26474ba04c096af7103c4320ed2f4f3683f79d7670a055c.jpg +0 -0
- package/dist/template/public/assets/d5a0701b2d156284e0ce851cd2534ec632db34f91fbcbee3b8a7784d45ce78d2.jpg +0 -0
- package/dist/template/public/assets/d6ef1c3f48b0e488521794fb60701da1fd2c3a1621d6ac5f17ccfd4909d3be60.jpg +0 -0
- package/dist/template/public/assets/de249ff9be2539cf0d1ce092de3c57001839b6c3e14fcee3fc31a7b7673ae007.jpg +0 -0
- package/dist/template/public/assets/eac45438956be187b010e24b3289757aa00f227c190d49ee99fea510552dd2ba.jpg +0 -0
- package/dist/template/public/assets/f8b9200065b5436c6a88361839edc2b89be88d3037c84a80d3ee95c32891510b.jpg +0 -0
- package/dist/template/public/assets/placeholder.png +0 -0
- package/dist/template/public/brand/mark.svg +6 -0
- package/dist/template/public/brand/wordmark-light.svg +6 -0
- package/dist/template/public/brand/wordmark.svg +6 -0
- package/dist/template/styles/globals.css +69 -0
- package/dist/template/styles/theme.css +492 -0
- package/dist/template/styles/typography.css +469 -0
- package/dist/template/tsconfig.json +30 -0
- package/package.json +30 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { ArticleBodyComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const ArticleBody = defineSection({
|
|
6
|
+
name: 'ArticleBody',
|
|
7
|
+
category: 'Blog',
|
|
8
|
+
schema,
|
|
9
|
+
component: ArticleBodyComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { EditableText, EditableImage, EditableLink, read, isSlotInPreview } from '@agntcms/next/client'
|
|
4
|
+
import type { EditableSlot } from '@agntcms/next/client'
|
|
5
|
+
import { hrefOf, isExternalLink } from '@agntcms/next'
|
|
6
|
+
import type { ImageValue, LinkValue } from '@agntcms/next'
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
readonly backLink: EditableSlot<'link', LinkValue>
|
|
10
|
+
readonly category: EditableSlot<'text', string>
|
|
11
|
+
readonly title: EditableSlot<'text', string>
|
|
12
|
+
readonly authorName: EditableSlot<'text', string>
|
|
13
|
+
readonly authorPhoto: EditableSlot<'image', ImageValue>
|
|
14
|
+
readonly meta: EditableSlot<'text', string>
|
|
15
|
+
readonly coverImage: EditableSlot<'image', ImageValue>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function ArticleHeroComponent({
|
|
19
|
+
backLink,
|
|
20
|
+
category,
|
|
21
|
+
title,
|
|
22
|
+
authorName,
|
|
23
|
+
authorPhoto,
|
|
24
|
+
meta,
|
|
25
|
+
coverImage,
|
|
26
|
+
}: Props) {
|
|
27
|
+
const back = read(backLink)
|
|
28
|
+
const backHref = hrefOf(back)
|
|
29
|
+
const showBack = Boolean(backHref) || isSlotInPreview(backLink)
|
|
30
|
+
const cover = read(coverImage)
|
|
31
|
+
const hasCover = Boolean(cover?.filename) || isSlotInPreview(coverImage)
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<section className="bg-paper">
|
|
35
|
+
<div className="mx-auto w-full max-w-[720px] px-8 pt-16 pb-8">
|
|
36
|
+
{showBack && (
|
|
37
|
+
<a
|
|
38
|
+
href={backHref || '#'}
|
|
39
|
+
target={isExternalLink(back) ? '_blank' : undefined}
|
|
40
|
+
rel={isExternalLink(back) ? 'noreferrer' : undefined}
|
|
41
|
+
className="font-mono text-xs tracking-[0.04em] text-ink-3 no-underline"
|
|
42
|
+
>
|
|
43
|
+
←{' '}
|
|
44
|
+
<EditableLink field={backLink} className="text-ink-3 no-underline" />
|
|
45
|
+
</a>
|
|
46
|
+
)}
|
|
47
|
+
<div className="mt-6">
|
|
48
|
+
<EditableText
|
|
49
|
+
field={category}
|
|
50
|
+
as="span"
|
|
51
|
+
className="font-mono text-[11px] font-medium tracking-[0.07em] uppercase text-ink-3"
|
|
52
|
+
/>
|
|
53
|
+
<EditableText
|
|
54
|
+
field={title}
|
|
55
|
+
as="h1"
|
|
56
|
+
className="mt-3 font-display text-[56px] font-semibold leading-[1.05] tracking-[-0.03em] text-ink"
|
|
57
|
+
/>
|
|
58
|
+
<div className="mt-5 flex items-center gap-3">
|
|
59
|
+
<EditableImage
|
|
60
|
+
field={authorPhoto}
|
|
61
|
+
className="!block h-9 w-9 rounded-full object-cover grayscale [&_img]:h-9 [&_img]:w-9 [&_img]:rounded-full [&_img]:object-cover [&_img]:grayscale"
|
|
62
|
+
/>
|
|
63
|
+
<div className="text-sm text-ink-2">
|
|
64
|
+
<EditableText
|
|
65
|
+
field={authorName}
|
|
66
|
+
as="b"
|
|
67
|
+
className="font-semibold text-ink"
|
|
68
|
+
/>{' '}
|
|
69
|
+
·{' '}
|
|
70
|
+
<EditableText field={meta} as="span" />
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
{hasCover ? (
|
|
76
|
+
<div className="mx-auto mt-8 w-full max-w-[720px] px-8">
|
|
77
|
+
<div className="aspect-[16/9] overflow-hidden border border-hairline bg-paper-2">
|
|
78
|
+
<EditableImage
|
|
79
|
+
field={coverImage}
|
|
80
|
+
className="!block h-full w-full object-cover [&_img]:h-full [&_img]:w-full [&_img]:object-cover"
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
) : null}
|
|
85
|
+
</section>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { ArticleHeroComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const ArticleHero = defineSection({
|
|
6
|
+
name: 'ArticleHero',
|
|
7
|
+
category: 'Blog',
|
|
8
|
+
schema,
|
|
9
|
+
component: ArticleHeroComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TextField, LinkField, ImageField } from '@agntcms/next'
|
|
2
|
+
|
|
3
|
+
export const schema = {
|
|
4
|
+
// "Back to blog"-style link at the top of the article.
|
|
5
|
+
backLink: LinkField,
|
|
6
|
+
category: TextField,
|
|
7
|
+
title: TextField,
|
|
8
|
+
authorName: TextField,
|
|
9
|
+
authorPhoto: ImageField,
|
|
10
|
+
meta: TextField,
|
|
11
|
+
coverImage: ImageField,
|
|
12
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { EditableRichText, EditableImage, EditableLink, read, isSlotInPreview } from '@agntcms/next/client'
|
|
4
|
+
import type { EditableSlot } from '@agntcms/next/client'
|
|
5
|
+
import { hrefOf, isExternalLink } from '@agntcms/next'
|
|
6
|
+
import type { ImageValue, LinkValue } from '@agntcms/next'
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
readonly headline: EditableSlot<'richText', string>
|
|
10
|
+
readonly lead: EditableSlot<'richText', string>
|
|
11
|
+
readonly primaryCta: EditableSlot<'link', LinkValue>
|
|
12
|
+
readonly secondaryCta: EditableSlot<'link', LinkValue>
|
|
13
|
+
readonly image: EditableSlot<'image', ImageValue>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function Cta({
|
|
17
|
+
field,
|
|
18
|
+
variant,
|
|
19
|
+
}: {
|
|
20
|
+
field: EditableSlot<'link', LinkValue>
|
|
21
|
+
variant: 'primary' | 'secondary'
|
|
22
|
+
}) {
|
|
23
|
+
const link = read(field)
|
|
24
|
+
const href = hrefOf(link)
|
|
25
|
+
const show = Boolean(href) || isSlotInPreview(field)
|
|
26
|
+
if (!show) return null
|
|
27
|
+
const styles =
|
|
28
|
+
variant === 'primary'
|
|
29
|
+
? 'bg-paper text-ink border-paper hover:bg-paper-2 hover:border-paper-2'
|
|
30
|
+
: 'bg-transparent text-paper border-paper/25 hover:border-paper'
|
|
31
|
+
return (
|
|
32
|
+
<a
|
|
33
|
+
href={href || '#'}
|
|
34
|
+
target={isExternalLink(link) ? '_blank' : undefined}
|
|
35
|
+
rel={isExternalLink(link) ? 'noreferrer' : undefined}
|
|
36
|
+
>
|
|
37
|
+
<EditableLink
|
|
38
|
+
field={field}
|
|
39
|
+
className={`inline-flex items-center gap-2 whitespace-nowrap rounded-sm border px-[22px] py-[13px] text-[15px] font-medium no-underline transition-colors duration-200 ease-out ${styles}`}
|
|
40
|
+
/>
|
|
41
|
+
</a>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function BannerComponent({
|
|
46
|
+
headline,
|
|
47
|
+
lead,
|
|
48
|
+
primaryCta,
|
|
49
|
+
secondaryCta,
|
|
50
|
+
image,
|
|
51
|
+
}: Props) {
|
|
52
|
+
const img = read(image)
|
|
53
|
+
const hasImage = Boolean(img?.filename) || isSlotInPreview(image)
|
|
54
|
+
return (
|
|
55
|
+
<section className="relative overflow-hidden bg-ink text-paper">
|
|
56
|
+
{hasImage ? (
|
|
57
|
+
<div
|
|
58
|
+
aria-hidden="true"
|
|
59
|
+
className="pointer-events-none absolute inset-y-0 right-0 h-full w-[40%] opacity-90 grayscale"
|
|
60
|
+
>
|
|
61
|
+
<EditableImage
|
|
62
|
+
field={image}
|
|
63
|
+
className="!block h-full w-full object-cover [&_img]:h-full [&_img]:w-full [&_img]:object-cover"
|
|
64
|
+
/>
|
|
65
|
+
<div className="absolute inset-0 bg-gradient-to-r from-ink to-transparent" />
|
|
66
|
+
</div>
|
|
67
|
+
) : null}
|
|
68
|
+
<div className="relative mx-auto w-full max-w-[1280px] px-8 py-24 text-center">
|
|
69
|
+
<div className="mx-auto max-w-[820px] [&_h2]:m-0 [&_h2]:font-display [&_h2]:font-semibold [&_h2]:text-paper [&_h2]:text-[56px] [&_h2]:leading-[1.05] [&_h2]:tracking-[-0.03em] [&_p]:m-0 [&_p]:font-display [&_p]:font-semibold [&_p]:text-paper [&_p]:text-[56px] [&_p]:leading-[1.05] [&_p]:tracking-[-0.03em] [&_em]:not-italic [&_em]:text-paper/55 [&_em]:font-semibold">
|
|
70
|
+
<EditableRichText field={headline} />
|
|
71
|
+
</div>
|
|
72
|
+
<EditableRichText
|
|
73
|
+
field={lead}
|
|
74
|
+
className="mx-auto mt-4 max-w-[560px] [&_p]:text-[17px] [&_p]:leading-[1.55] [&_p]:text-paper/65 [&_p]:m-0"
|
|
75
|
+
/>
|
|
76
|
+
<div className="mt-8 flex flex-wrap justify-center gap-3">
|
|
77
|
+
<Cta field={primaryCta} variant="primary" />
|
|
78
|
+
<Cta field={secondaryCta} variant="secondary" />
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</section>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { BannerComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const Banner = defineSection({
|
|
6
|
+
name: 'Banner',
|
|
7
|
+
category: 'Calls to action',
|
|
8
|
+
schema,
|
|
9
|
+
component: BannerComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
EditableImage,
|
|
5
|
+
EditableList,
|
|
6
|
+
EditableRichText,
|
|
7
|
+
read,
|
|
8
|
+
} from '@agntcms/next/client'
|
|
9
|
+
import type { EditableSlot, SlotItem } from '@agntcms/next/client'
|
|
10
|
+
import { schema } from './schema'
|
|
11
|
+
|
|
12
|
+
type Post = SlotItem<typeof schema.posts.itemSchema>
|
|
13
|
+
|
|
14
|
+
interface PostMetaProps {
|
|
15
|
+
readonly category: EditableSlot<'richText', string>
|
|
16
|
+
readonly publishedAt: EditableSlot<'richText', string>
|
|
17
|
+
readonly readingTime: EditableSlot<'richText', string>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function PostMeta({ category, publishedAt, readingTime }: PostMetaProps) {
|
|
21
|
+
return (
|
|
22
|
+
<div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-[12px] text-text-tertiary">
|
|
23
|
+
<EditableRichText
|
|
24
|
+
field={category}
|
|
25
|
+
as="span"
|
|
26
|
+
className="text-[11px] font-medium uppercase tracking-[0.10em] text-text-brand-primary"
|
|
27
|
+
/>
|
|
28
|
+
<EditableRichText field={publishedAt} as="span" />
|
|
29
|
+
{read(readingTime) && (
|
|
30
|
+
<>
|
|
31
|
+
<span aria-hidden="true">·</span>
|
|
32
|
+
<EditableRichText field={readingTime} as="span" />
|
|
33
|
+
</>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface Props {
|
|
40
|
+
readonly eyebrow: EditableSlot<'richText', string>
|
|
41
|
+
readonly headline: EditableSlot<'richText', string>
|
|
42
|
+
readonly intro: EditableSlot<'richText', string>
|
|
43
|
+
readonly posts: EditableSlot<'list', ReadonlyArray<Post>>
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function BlogIndexComponent({ eyebrow, headline, intro, posts }: Props) {
|
|
47
|
+
return (
|
|
48
|
+
<section className="bg-bg-primary">
|
|
49
|
+
<div className="mx-auto w-full max-w-[1080px] px-8 pt-24 pb-24">
|
|
50
|
+
<EditableRichText
|
|
51
|
+
field={eyebrow}
|
|
52
|
+
as="div"
|
|
53
|
+
className="mb-4 text-[11px] font-medium uppercase tracking-[0.10em] text-text-brand-primary"
|
|
54
|
+
/>
|
|
55
|
+
<EditableRichText
|
|
56
|
+
field={headline}
|
|
57
|
+
className="
|
|
58
|
+
mb-6
|
|
59
|
+
[&_h1]:m-0 [&_h1]:font-display [&_h1]:font-medium [&_h1]:text-text-primary
|
|
60
|
+
[&_h1]:max-w-[18ch]
|
|
61
|
+
[&_h1]:!text-[clamp(40px,6vw,72px)] [&_h1]:!leading-[1.02] [&_h1]:!tracking-[-0.04em]
|
|
62
|
+
"
|
|
63
|
+
/>
|
|
64
|
+
<EditableRichText
|
|
65
|
+
field={intro}
|
|
66
|
+
className="
|
|
67
|
+
mb-16 max-w-[60ch]
|
|
68
|
+
[&_p]:m-0 [&_p]:text-[18px] [&_p]:leading-[1.6] [&_p]:text-text-secondary
|
|
69
|
+
"
|
|
70
|
+
/>
|
|
71
|
+
|
|
72
|
+
<EditableList
|
|
73
|
+
field={posts}
|
|
74
|
+
itemSchema={schema.posts.itemSchema}
|
|
75
|
+
renderItem={(post, index) => {
|
|
76
|
+
// Static helpers (PostMeta, the article href) need bare values;
|
|
77
|
+
// editable components receive the slot directly. `read()` is
|
|
78
|
+
// the canonical helper for the bare-value path (see
|
|
79
|
+
// EDITABILITY_DESIGN.md author migration).
|
|
80
|
+
const href = read(post.href) || '#'
|
|
81
|
+
if (index === 0) {
|
|
82
|
+
return (
|
|
83
|
+
<a href={href} className="group block mb-16 no-underline">
|
|
84
|
+
<div className="grid grid-cols-1 gap-8 md:grid-cols-2 md:gap-12 md:items-center">
|
|
85
|
+
<div className="overflow-hidden rounded-xl border-[0.5px] border-border-primary bg-bg-secondary">
|
|
86
|
+
<EditableImage
|
|
87
|
+
field={post.cover}
|
|
88
|
+
className="block aspect-[4/3] w-full object-cover"
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
<div>
|
|
92
|
+
<PostMeta
|
|
93
|
+
category={post.category}
|
|
94
|
+
publishedAt={post.publishedAt}
|
|
95
|
+
readingTime={post.readingTime}
|
|
96
|
+
/>
|
|
97
|
+
<EditableRichText
|
|
98
|
+
field={post.title}
|
|
99
|
+
className="
|
|
100
|
+
mt-4 mb-4 font-display font-medium text-text-primary
|
|
101
|
+
[&_h2]:m-0 [&_h2]:font-display [&_h2]:font-medium [&_h2]:text-text-primary
|
|
102
|
+
[&_h2]:text-[clamp(24px,3vw,32px)] [&_h2]:leading-[1.15] [&_h2]:tracking-[-0.02em]
|
|
103
|
+
[&_p]:m-0 [&_p]:font-display [&_p]:font-medium [&_p]:text-text-primary
|
|
104
|
+
[&_p]:text-[clamp(24px,3vw,32px)] [&_p]:leading-[1.15] [&_p]:tracking-[-0.02em]
|
|
105
|
+
group-hover:text-text-brand-primary transition-colors
|
|
106
|
+
"
|
|
107
|
+
/>
|
|
108
|
+
<EditableRichText
|
|
109
|
+
field={post.summary}
|
|
110
|
+
className="
|
|
111
|
+
mb-5 max-w-[52ch]
|
|
112
|
+
[&_p]:m-0 [&_p]:text-[16px] [&_p]:leading-[1.6] [&_p]:text-text-secondary
|
|
113
|
+
"
|
|
114
|
+
/>
|
|
115
|
+
<EditableRichText
|
|
116
|
+
field={post.author}
|
|
117
|
+
as="div"
|
|
118
|
+
className="text-[13px] text-text-tertiary"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</a>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const isFirstInGrid = index === 1
|
|
127
|
+
return (
|
|
128
|
+
<div
|
|
129
|
+
className={
|
|
130
|
+
isFirstInGrid
|
|
131
|
+
? 'border-t-[0.5px] border-border-primary pt-12'
|
|
132
|
+
: ''
|
|
133
|
+
}
|
|
134
|
+
>
|
|
135
|
+
<a href={href} className="group block no-underline">
|
|
136
|
+
<div className="mb-5 overflow-hidden rounded-lg border-[0.5px] border-border-primary bg-bg-secondary">
|
|
137
|
+
<EditableImage
|
|
138
|
+
field={post.cover}
|
|
139
|
+
className="block aspect-[16/9] w-full object-cover"
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
<PostMeta
|
|
143
|
+
category={post.category}
|
|
144
|
+
publishedAt={post.publishedAt}
|
|
145
|
+
readingTime={post.readingTime}
|
|
146
|
+
/>
|
|
147
|
+
<EditableRichText
|
|
148
|
+
field={post.title}
|
|
149
|
+
className="
|
|
150
|
+
mt-3 mb-3 font-display font-medium text-text-primary
|
|
151
|
+
[&_h3]:m-0 [&_h3]:font-display [&_h3]:font-medium [&_h3]:text-text-primary
|
|
152
|
+
[&_h3]:text-[22px] [&_h3]:leading-[1.2] [&_h3]:tracking-[-0.01em]
|
|
153
|
+
[&_p]:m-0 [&_p]:font-display [&_p]:font-medium [&_p]:text-text-primary
|
|
154
|
+
[&_p]:text-[22px] [&_p]:leading-[1.2] [&_p]:tracking-[-0.01em]
|
|
155
|
+
group-hover:text-text-brand-primary transition-colors
|
|
156
|
+
"
|
|
157
|
+
/>
|
|
158
|
+
<EditableRichText
|
|
159
|
+
field={post.summary}
|
|
160
|
+
className="
|
|
161
|
+
[&_p]:m-0 [&_p]:text-[15px] [&_p]:leading-[1.6] [&_p]:text-text-secondary
|
|
162
|
+
"
|
|
163
|
+
/>
|
|
164
|
+
</a>
|
|
165
|
+
</div>
|
|
166
|
+
)
|
|
167
|
+
}}
|
|
168
|
+
className="grid grid-cols-1 gap-x-8 gap-y-12 md:grid-cols-2 [&>*:first-child]:md:col-span-2"
|
|
169
|
+
/>
|
|
170
|
+
</div>
|
|
171
|
+
</section>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { BlogIndexComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const BlogIndex = defineSection({
|
|
6
|
+
name: 'BlogIndex',
|
|
7
|
+
category: 'Blog',
|
|
8
|
+
schema,
|
|
9
|
+
component: BlogIndexComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ImageField, ListField, RichTextField, TextField } from '@agntcms/next'
|
|
2
|
+
|
|
3
|
+
export const schema = {
|
|
4
|
+
// ALL CAPS section label.
|
|
5
|
+
eyebrow: { kind: 'richText' as const, default: 'Writing' },
|
|
6
|
+
|
|
7
|
+
// Page headline.
|
|
8
|
+
headline: {
|
|
9
|
+
kind: 'richText' as const,
|
|
10
|
+
default: '# Blog.',
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
// Standfirst under the headline.
|
|
14
|
+
intro: {
|
|
15
|
+
kind: 'richText' as const,
|
|
16
|
+
default:
|
|
17
|
+
'Notes on the product, the philosophy, and the open-source progress. ' +
|
|
18
|
+
'Short pieces, written in the open.',
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// List of posts. The first item is rendered as the large "featured" card
|
|
22
|
+
// at the top of the index. Remaining items render in a 2-up grid.
|
|
23
|
+
posts: ListField({
|
|
24
|
+
title: RichTextField,
|
|
25
|
+
summary: RichTextField,
|
|
26
|
+
href: TextField,
|
|
27
|
+
cover: ImageField,
|
|
28
|
+
category: RichTextField,
|
|
29
|
+
publishedAt: RichTextField,
|
|
30
|
+
author: RichTextField,
|
|
31
|
+
readingTime: RichTextField,
|
|
32
|
+
}),
|
|
33
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { EditableRichText, EditableText, EditableList } from '@agntcms/next/client'
|
|
4
|
+
import type { EditableSlot, SlotItem } from '@agntcms/next/client'
|
|
5
|
+
import { schema } from './schema'
|
|
6
|
+
|
|
7
|
+
type Category = SlotItem<typeof schema.categories.itemSchema>
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
readonly eyebrow: EditableSlot<'richText', string>
|
|
11
|
+
readonly headline: EditableSlot<'richText', string>
|
|
12
|
+
readonly lead: EditableSlot<'richText', string>
|
|
13
|
+
readonly categories: EditableSlot<'list', ReadonlyArray<Category>>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function BlogIndexHeaderComponent({ eyebrow, headline, lead, categories }: Props) {
|
|
17
|
+
return (
|
|
18
|
+
<section className="bg-paper-2 border-b border-hairline">
|
|
19
|
+
<div className="mx-auto w-full max-w-[1280px] px-8 pt-[88px] pb-8">
|
|
20
|
+
<EditableRichText
|
|
21
|
+
field={eyebrow}
|
|
22
|
+
className="[&_p]:font-mono [&_p]:font-medium [&_p]:text-[12px] [&_p]:tracking-[0.07em] [&_p]:uppercase [&_p]:text-ink-3 [&_p]:m-0"
|
|
23
|
+
/>
|
|
24
|
+
<div className="mt-3 max-w-[720px] [&_h1]:m-0 [&_h1]:font-display [&_h1]:font-semibold [&_h1]:text-ink [&_h1]:text-[72px] [&_h1]:leading-[1.05] [&_h1]:tracking-[-0.03em] [&_h2]:m-0 [&_h2]:font-display [&_h2]:font-semibold [&_h2]:text-ink [&_h2]:text-[72px] [&_h2]:leading-[1.05] [&_h2]:tracking-[-0.03em] [&_p]:m-0 [&_p]:font-display [&_p]:font-semibold [&_p]:text-ink [&_p]:text-[72px] [&_p]:leading-[1.05] [&_p]:tracking-[-0.03em] [&_em]:not-italic [&_em]:text-ink-3 [&_em]:font-semibold">
|
|
25
|
+
<EditableRichText field={headline} />
|
|
26
|
+
</div>
|
|
27
|
+
<EditableRichText
|
|
28
|
+
field={lead}
|
|
29
|
+
className="mt-5 max-w-[620px] [&_p]:m-0 [&_p]:text-[19px] [&_p]:leading-[1.55] [&_p]:text-ink-2"
|
|
30
|
+
/>
|
|
31
|
+
<EditableList
|
|
32
|
+
field={categories}
|
|
33
|
+
itemSchema={schema.categories.itemSchema}
|
|
34
|
+
className="mt-8 flex flex-wrap gap-2"
|
|
35
|
+
renderItem={(c) => (
|
|
36
|
+
<span className="inline-flex items-center border border-hairline bg-transparent px-3.5 py-[7px] font-mono text-[11px] font-medium tracking-[0.07em] uppercase text-ink-2">
|
|
37
|
+
<EditableText field={c.label} as="span" />
|
|
38
|
+
</span>
|
|
39
|
+
)}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
</section>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { BlogIndexHeaderComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const BlogIndexHeader = defineSection({
|
|
6
|
+
name: 'BlogIndexHeader',
|
|
7
|
+
category: 'Blog',
|
|
8
|
+
schema,
|
|
9
|
+
component: BlogIndexHeaderComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { EditableRichText } from '@agntcms/next/client'
|
|
4
|
+
import type { EditableSlot } from '@agntcms/next/client'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
readonly body: EditableSlot<'richText', string>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function BlogPostBodyComponent({ body }: Props) {
|
|
11
|
+
return (
|
|
12
|
+
<section className="bg-bg-primary">
|
|
13
|
+
<div className="mx-auto w-full max-w-[720px] px-8 pb-24">
|
|
14
|
+
<div
|
|
15
|
+
className="
|
|
16
|
+
[&_h2]:font-display [&_h2]:font-medium [&_h2]:text-text-primary
|
|
17
|
+
[&_h2]:!text-[26px] [&_h2]:!leading-[1.2] [&_h2]:!tracking-[-0.02em]
|
|
18
|
+
[&_h2]:mt-14 [&_h2]:mb-4
|
|
19
|
+
[&_h3]:font-display [&_h3]:font-medium [&_h3]:text-text-primary
|
|
20
|
+
[&_h3]:!text-[19px] [&_h3]:!leading-[1.3] [&_h3]:!tracking-[-0.01em]
|
|
21
|
+
[&_h3]:mt-10 [&_h3]:mb-3
|
|
22
|
+
[&_p]:my-4 [&_p]:text-[17px] [&_p]:leading-[1.7] [&_p]:text-text-primary
|
|
23
|
+
[&_a]:text-text-brand-primary [&_a]:underline [&_a]:underline-offset-[3px] hover:[&_a]:no-underline
|
|
24
|
+
[&_strong]:font-medium [&_strong]:text-text-primary
|
|
25
|
+
[&_em]:italic
|
|
26
|
+
[&_ul]:my-4 [&_ul]:list-disc [&_ul]:pl-6
|
|
27
|
+
[&_ol]:my-4 [&_ol]:list-decimal [&_ol]:pl-6
|
|
28
|
+
[&_li]:my-1.5 [&_li]:text-[17px] [&_li]:leading-[1.7] [&_li]:text-text-primary
|
|
29
|
+
[&_li_p]:my-1
|
|
30
|
+
[&_code]:font-mono [&_code]:text-[14px] [&_code]:font-normal
|
|
31
|
+
[&_code]:text-text-brand-primary [&_code]:bg-bg-brand-primary
|
|
32
|
+
[&_code]:px-[6px] [&_code]:py-[2px] [&_code]:rounded-sm
|
|
33
|
+
[&_pre]:my-6 [&_pre]:bg-bg-brand-primary [&_pre]:rounded-lg
|
|
34
|
+
[&_pre]:px-5 [&_pre]:py-4 [&_pre]:overflow-x-auto
|
|
35
|
+
[&_pre]:font-mono [&_pre]:text-[13px] [&_pre]:leading-[1.7]
|
|
36
|
+
[&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:text-text-primary [&_pre_code]:rounded-none
|
|
37
|
+
[&_blockquote]:my-8 [&_blockquote]:not-italic
|
|
38
|
+
[&_blockquote]:bg-bg-secondary [&_blockquote]:border-l-2 [&_blockquote]:border-border-brand
|
|
39
|
+
[&_blockquote]:rounded-r-lg [&_blockquote]:px-5 [&_blockquote]:py-4
|
|
40
|
+
[&_blockquote_p]:m-0 [&_blockquote_p]:text-[16px] [&_blockquote_p]:leading-[1.65] [&_blockquote_p]:text-text-primary
|
|
41
|
+
[&_hr]:my-12 [&_hr]:border-0 [&_hr]:border-t-[0.5px] [&_hr]:border-border-primary
|
|
42
|
+
[&_img]:my-8 [&_img]:rounded-lg [&_img]:border-[0.5px] [&_img]:border-border-primary
|
|
43
|
+
"
|
|
44
|
+
>
|
|
45
|
+
<EditableRichText field={body} />
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</section>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { BlogPostBodyComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const BlogPostBody = defineSection({
|
|
6
|
+
name: 'BlogPostBody',
|
|
7
|
+
category: 'Blog',
|
|
8
|
+
schema,
|
|
9
|
+
component: BlogPostBodyComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const schema = {
|
|
2
|
+
// The full article body. Headings (##, ###), paragraphs, lists,
|
|
3
|
+
// blockquotes, inline code, and code blocks are all supported.
|
|
4
|
+
body: {
|
|
5
|
+
kind: 'richText' as const,
|
|
6
|
+
default:
|
|
7
|
+
'## A heading\n\nWrite the article body here. Use `##` and `###` for sub-headings, ' +
|
|
8
|
+
'plain paragraphs for prose, and `> ` for pull quotes.\n',
|
|
9
|
+
},
|
|
10
|
+
}
|