feat: article schema
Signed-off-by: Filipe Medeiros <hello@filipesm.eu>
This commit is contained in:
parent
9125f2af24
commit
4a5a08906a
6
studio/.prettierrc
Normal file
6
studio/.prettierrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"semi": false
|
||||
}
|
40
studio/documentActions/blogPostPublishAction.ts
Normal file
40
studio/documentActions/blogPostPublishAction.ts
Normal 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
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
),
|
||||
},
|
||||
})
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in a new issue