feat: article schema

Signed-off-by: Filipe Medeiros <hello@filipesm.eu>
This commit is contained in:
Filipe Medeiros 2023-04-09 19:37:04 +01:00
parent 9125f2af24
commit 4a5a08906a
Signed by: filipe
GPG key ID: 9533BD5467CC1E78
6 changed files with 73 additions and 18 deletions

6
studio/.prettierrc Normal file
View file

@ -0,0 +1,6 @@
{
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "all",
"semi": false
}

View file

@ -0,0 +1,40 @@
import {useEffect, useState} from 'react'
import {
DocumentActionComponent,
DocumentActionProps,
PortableTextBlock,
useDocumentOperation,
} from 'sanity'
import {toPlainText} from '@portabletext/toolkit'
export function blogPostPublishAction(originalPublishAction: DocumentActionComponent) {
const BetterAction = (props: DocumentActionProps) => {
const {patch, publish} = useDocumentOperation(props.id, props.type)
const [isPublishing, setIsPublishing] = useState(false)
useEffect(() => {
if (isPublishing && !props.draft) {
setIsPublishing(false)
}
}, [props.draft, isPublishing])
if (props.type !== 'blogPost') return originalPublishAction(props)
const content = (props.draft?.content ?? props.published?.content) as
| PortableTextBlock[]
| undefined
const readTimeInMinutes = content ? Math.ceil(toPlainText(content).length / 5 / 180) : 0
return {
disabled: publish.disabled,
label: isPublishing ? 'Publishing…' : 'Update & Publish',
onHandle: () => {
setIsPublishing(true)
props.type === 'blogPost' && patch.execute([{set: {readTime: `${readTimeInMinutes} min`}}])
publish.execute()
props.onComplete()
},
}
}
return BetterAction
}

View file

@ -15,6 +15,7 @@
"sanity"
],
"dependencies": {
"@portabletext/toolkit": "^2.0.1",
"@sanity/icons": "^2.2.2",
"@sanity/vision": "^3.0.0",
"react": "^18.2.0",

View file

@ -1,6 +1,9 @@
lockfileVersion: '6.0'
dependencies:
'@portabletext/toolkit':
specifier: ^2.0.1
version: 2.0.1
'@sanity/icons':
specifier: ^2.2.2
version: 2.2.2(react@18.2.0)
@ -2064,6 +2067,13 @@ packages:
'@portabletext/types': 2.0.2
dev: false
/@portabletext/toolkit@2.0.1:
resolution: {integrity: sha512-vr2SeDFUFV+VmRIyYsHBMimZLiiN0S7qIridt/YLJs3Wm1dI4jsfUam82AQwheSMjvWdBiBZ+Wsjq5HZBG4htw==}
engines: {node: ^14.13.1 || >=16.0.0}
dependencies:
'@portabletext/types': 2.0.2
dev: false
/@portabletext/types@1.0.3:
resolution: {integrity: sha512-SDDsdury2SaTI2D5Ea6o+Y39SSZMYHRMWJHxkxYl3yzFP0n/0EknOhoXcoaV+bxGr2dTTqZi2TOEj+uWYuavSw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}

View file

@ -2,10 +2,11 @@ import {defineConfig} from 'sanity'
import {deskTool} from 'sanity/desk'
import {visionTool} from '@sanity/vision'
import {schemaTypes} from './schemas'
import {blogPostPublishAction} from './documentActions/blogPostPublishAction'
export default defineConfig({
name: 'default',
title: 'personal-website',
name: 'personal-webiste',
title: 'Personal website',
projectId: 'tzamgyrm',
dataset: 'production',
@ -15,4 +16,12 @@ export default defineConfig({
schema: {
types: schemaTypes,
},
document: {
// @ts-expect-error
actions: (originalActions) =>
originalActions.map((originalAction) =>
originalAction.action === 'publish' ? blogPostPublishAction(originalAction) : originalAction
),
},
})

View file

@ -35,20 +35,6 @@ const blogPost = defineType({
'This image will be used as the header image in the article page, on the article list/blog page and also eventually on social previews and other websites.',
validation: (r) => r.required(),
},
{
name: 'department',
title: 'Department',
type: 'string',
description:
'The department which this article belongs to. If it belongs to no specific department, please leave this field empty.',
options: {
list: [
{value: 'capital', title: 'Capital'},
{value: 'labs', title: 'Labs'},
{value: 'research', title: 'Research'},
],
},
},
{
name: 'content',
title: 'Content',
@ -88,8 +74,11 @@ const blogPost = defineType({
name: 'readTime',
title: 'Read time',
type: 'string',
description:
"E.g. '3 min' or '420 seconds'. If you don't specify this, we fall back to calculating it for you.",
description: 'Calculated automatically for you.',
readOnly: true,
options: {
hotspot: true,
},
},
{
name: 'publishDate',