feat: Initial sanity setup
This commit is contained in:
parent
9f0ca820ad
commit
c2a7cb4494
25 changed files with 5675 additions and 94 deletions
3
sites/sanity/.eslintrc
Normal file
3
sites/sanity/.eslintrc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"extends": "@sanity/eslint-config-studio"
|
||||||
|
}
|
12
sites/sanity/.npmignore
Normal file
12
sites/sanity/.npmignore
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Logs
|
||||||
|
/logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Compiled sanity studio
|
||||||
|
/dist
|
9
sites/sanity/README.md
Normal file
9
sites/sanity/README.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Sanity Clean Content Studio
|
||||||
|
|
||||||
|
Congratulations, you have now installed the Sanity Content Studio, an open source real-time content editing environment connected to the Sanity backend.
|
||||||
|
|
||||||
|
Now you can do the following things:
|
||||||
|
|
||||||
|
- [Read “getting started” in the docs](https://www.sanity.io/docs/introduction/getting-started?utm_source=readme)
|
||||||
|
- [Join the community Slack](https://slack.sanity.io/?utm_source=readme)
|
||||||
|
- [Extend and build plugins](https://www.sanity.io/docs/content-studio/extending?utm_source=readme)
|
8
sites/sanity/config/.checksums
Normal file
8
sites/sanity/config/.checksums
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"#": "Used by Sanity to keep track of configuration file checksums, do not delete or modify!",
|
||||||
|
"@sanity/default-layout": "bb034f391ba508a6ca8cd971967cbedeb131c4d19b17b28a0895f32db5d568ea",
|
||||||
|
"@sanity/default-login": "e2ed4e51e97331c0699ba7cf9f67cbf76f1c6a5f806d6eabf8259b2bcb5f1002",
|
||||||
|
"@sanity/form-builder": "b38478227ba5e22c91981da4b53436df22e48ff25238a55a973ed620be5068aa",
|
||||||
|
"@sanity/data-aspects": "d199e2c199b3e26cd28b68dc84d7fc01c9186bf5089580f2e2446994d36b3cb6",
|
||||||
|
"@sanity/vision": "da5b6ed712703ecd04bf4df560570c668aa95252c6bc1c41d6df1bda9b8b8f60"
|
||||||
|
}
|
3
sites/sanity/config/@sanity/data-aspects.json
Normal file
3
sites/sanity/config/@sanity/data-aspects.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"listOptions": {}
|
||||||
|
}
|
6
sites/sanity/config/@sanity/default-layout.json
Normal file
6
sites/sanity/config/@sanity/default-layout.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"toolSwitcher": {
|
||||||
|
"order": [],
|
||||||
|
"hidden": []
|
||||||
|
}
|
||||||
|
}
|
8
sites/sanity/config/@sanity/default-login.json
Normal file
8
sites/sanity/config/@sanity/default-login.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"providers": {
|
||||||
|
"mode": "append",
|
||||||
|
"redirectOnSingle": false,
|
||||||
|
"entries": []
|
||||||
|
},
|
||||||
|
"loginMethod": "dual"
|
||||||
|
}
|
5
sites/sanity/config/@sanity/form-builder.json
Normal file
5
sites/sanity/config/@sanity/form-builder.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"images": {
|
||||||
|
"directUploads": true
|
||||||
|
}
|
||||||
|
}
|
3
sites/sanity/config/@sanity/vision.json
Normal file
3
sites/sanity/config/@sanity/vision.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"defaultApiVersion": "2021-10-21"
|
||||||
|
}
|
31
sites/sanity/package.json
Normal file
31
sites/sanity/package.json
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "FreeSewing",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "package.json",
|
||||||
|
"author": "Joost De Cock <joost@joost.at>",
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"scripts": {
|
||||||
|
"start": "sanity start",
|
||||||
|
"build": "sanity build"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"sanity"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@sanity/base": "^2.35.0",
|
||||||
|
"@sanity/core": "^2.35.0",
|
||||||
|
"@sanity/default-layout": "^2.35.0",
|
||||||
|
"@sanity/default-login": "^2.35.0",
|
||||||
|
"@sanity/desk-tool": "^2.35.0",
|
||||||
|
"@sanity/eslint-config-studio": "^2.0.0",
|
||||||
|
"@sanity/vision": "^2.35.0",
|
||||||
|
"eslint": "^8.6.0",
|
||||||
|
"prop-types": "^15.7",
|
||||||
|
"react": "^17.0",
|
||||||
|
"react-dom": "^17.0",
|
||||||
|
"styled-components": "^5.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {}
|
||||||
|
}
|
1
sites/sanity/plugins/.gitkeep
Normal file
1
sites/sanity/plugins/.gitkeep
Normal file
|
@ -0,0 +1 @@
|
||||||
|
User-specific packages can be placed here
|
|
@ -0,0 +1,17 @@
|
||||||
|
import React from 'react'
|
||||||
|
import StudioRoot from 'part:@sanity/default-layout/root'
|
||||||
|
import {useCurrentUser} from '@sanity/base/hooks'
|
||||||
|
import GetStartedTutorial from './GetStartedTutorial'
|
||||||
|
|
||||||
|
export default function CustomDefaultLayout() {
|
||||||
|
const {value} = useCurrentUser()
|
||||||
|
|
||||||
|
const showTutorial = (value?.roles || []).length > 0
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{showTutorial && <GetStartedTutorial />}
|
||||||
|
<StudioRoot />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
import React, {useState} from 'react'
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
Container,
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
Label,
|
||||||
|
Heading,
|
||||||
|
Text,
|
||||||
|
Stack,
|
||||||
|
useElementRect,
|
||||||
|
useTheme,
|
||||||
|
} from '@sanity/ui'
|
||||||
|
import {CloseIcon} from '@sanity/icons'
|
||||||
|
import styled, {css} from 'styled-components'
|
||||||
|
|
||||||
|
const BlueColor = css`
|
||||||
|
color: ${({theme}) => theme.sanity.color.muted.primary.enabled.fg};
|
||||||
|
`
|
||||||
|
|
||||||
|
const LabelContainer = styled(Label)`
|
||||||
|
${BlueColor}
|
||||||
|
`
|
||||||
|
|
||||||
|
const TextContainer = styled(Text)`
|
||||||
|
${BlueColor}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const GetStartedTutorial = () => {
|
||||||
|
const [hideTutorial, setShowTutorial] = useState(
|
||||||
|
window.localStorage.getItem('getstarted_closedTutorial') !== null
|
||||||
|
)
|
||||||
|
|
||||||
|
const {sanity} = useTheme()
|
||||||
|
const [rootElement, setRootElement] = useState()
|
||||||
|
const rect = useElementRect(rootElement)
|
||||||
|
const isSmallScreen = rect?.width < sanity.media[1]
|
||||||
|
const isProdEnv = process.env.NODE_ENV !== 'development'
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
window.localStorage.setItem('getstarted_closedTutorial', 'true')
|
||||||
|
setShowTutorial(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hideTutorial || isProdEnv) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={setRootElement}>
|
||||||
|
<Card tone="primary" padding={isSmallScreen ? 3 : 5} paddingBottom={isSmallScreen ? 4 : 6}>
|
||||||
|
<Flex justify={isSmallScreen ? 'space-between' : 'flex-end'} align="center">
|
||||||
|
{isSmallScreen && (
|
||||||
|
<LabelContainer forwardedAs="p">Your Sanity Studio is all set up!</LabelContainer>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Button
|
||||||
|
aria-label="Close dialog"
|
||||||
|
icon={CloseIcon}
|
||||||
|
mode="bleed"
|
||||||
|
onClick={onClose}
|
||||||
|
padding={isSmallScreen ? undefined : 3}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
<Stack space={5}>
|
||||||
|
{!isSmallScreen && (
|
||||||
|
<>
|
||||||
|
<LabelContainer forwardedAs="p" align="center">
|
||||||
|
Get started with sanity
|
||||||
|
</LabelContainer>
|
||||||
|
|
||||||
|
<Heading as="h1" size={4} align="center">
|
||||||
|
Your Sanity Studio is all set up!
|
||||||
|
</Heading>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Container width={1}>
|
||||||
|
<TextContainer
|
||||||
|
forwardedAs="p"
|
||||||
|
size={isSmallScreen ? 1 : undefined}
|
||||||
|
align={isSmallScreen ? 'start' : 'center'}
|
||||||
|
>
|
||||||
|
Next, our docs will guide you through building schemas, adding content, and connecting
|
||||||
|
a frontend. You’ll see updates reflected in your Studio below.
|
||||||
|
</TextContainer>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Flex justify={isSmallScreen ? 'start' : 'center'}>
|
||||||
|
<Button
|
||||||
|
as="a"
|
||||||
|
href="https://www.sanity.io/docs/create-a-schema-and-configure-sanity-studio"
|
||||||
|
target="_blank"
|
||||||
|
padding={isSmallScreen ? undefined : 4}
|
||||||
|
tone="primary"
|
||||||
|
text="Build a schema"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GetStartedTutorial
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Couple of things to note:
|
||||||
|
* - width and height is set to 1em
|
||||||
|
* - fill is `currentColor` - this will ensure that the icon looks uniform and
|
||||||
|
* that the hover/active state works. You can of course render anything you
|
||||||
|
* would like here, but for plugins that are to be used in more than one
|
||||||
|
* studio, we suggest these rules are followed
|
||||||
|
**/
|
||||||
|
export default () => (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 250 250">
|
||||||
|
<path fill="none" stroke="currentColor" strokeWidth="40" d="M5 5h240v240H5z" />
|
||||||
|
</svg>
|
||||||
|
)
|
9
sites/sanity/plugins/sanity-plugin-tutorial/index.js
Normal file
9
sites/sanity/plugins/sanity-plugin-tutorial/index.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import GetStartedTutorial from './GetStartedTutorial'
|
||||||
|
import GetStartedTutorialIcon from './GetStartedTutorialIcon'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'GetStartedTutorial',
|
||||||
|
name: 'GetStartedtutorial',
|
||||||
|
icon: GetStartedTutorialIcon,
|
||||||
|
component: GetStartedTutorial,
|
||||||
|
}
|
8
sites/sanity/plugins/sanity-plugin-tutorial/sanity.json
Normal file
8
sites/sanity/plugins/sanity-plugin-tutorial/sanity.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"implements": "part:@sanity/base/tool",
|
||||||
|
"path": "./index.js"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
33
sites/sanity/sanity.json
Normal file
33
sites/sanity/sanity.json
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"project": {
|
||||||
|
"name": "white-opossum"
|
||||||
|
},
|
||||||
|
"api": {
|
||||||
|
"projectId": "hl5bw8cj",
|
||||||
|
"dataset": "production"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"@sanity/base",
|
||||||
|
"@sanity/default-layout",
|
||||||
|
"@sanity/default-login",
|
||||||
|
"@sanity/desk-tool"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"development": {
|
||||||
|
"plugins": [
|
||||||
|
"@sanity/vision"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"name": "part:@sanity/base/schema",
|
||||||
|
"path": "./schemas/schema"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"implements": "part:@sanity/base/root",
|
||||||
|
"path": "plugins/sanity-plugin-tutorial/CustomDefaultLayout"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
48
sites/sanity/schemas/blog.js
Normal file
48
sites/sanity/schemas/blog.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
export const blogSchemaBuilder = (lang) => ({
|
||||||
|
name: `blog${lang}`,
|
||||||
|
type: 'document',
|
||||||
|
title: `Blog ${lang.toUpperCase()}`,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
title: 'Title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'linktitle',
|
||||||
|
type: 'string',
|
||||||
|
title: 'Link Title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'slug',
|
||||||
|
type: 'slug',
|
||||||
|
title: 'Slug',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'date',
|
||||||
|
type: 'date',
|
||||||
|
title: 'Date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'image',
|
||||||
|
title: 'Image',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'caption',
|
||||||
|
type: 'string',
|
||||||
|
title: 'Caption',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'body',
|
||||||
|
title: 'Body',
|
||||||
|
type: 'array',
|
||||||
|
of: [{type: 'block'}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'author',
|
||||||
|
title: 'Author',
|
||||||
|
type: 'string',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
23
sites/sanity/schemas/newsletter.js
Normal file
23
sites/sanity/schemas/newsletter.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export const newsletter = {
|
||||||
|
name: 'newsletter',
|
||||||
|
type: 'document',
|
||||||
|
title: 'Newsletter',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
title: 'Title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'slug',
|
||||||
|
type: 'slug',
|
||||||
|
title: 'Slug',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'body',
|
||||||
|
title: 'Body',
|
||||||
|
type: 'array',
|
||||||
|
of: [{type: 'block'}]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
16
sites/sanity/schemas/schema.js
Normal file
16
sites/sanity/schemas/schema.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import createSchema from 'part:@sanity/base/schema-creator'
|
||||||
|
import schemaTypes from 'all:part:@sanity/base/schema-type'
|
||||||
|
import { blogSchemaBuilder } from './blog.js'
|
||||||
|
import { showcaseSchemaBuilder } from './showcase.js'
|
||||||
|
import { newsletter } from './newsletter.js'
|
||||||
|
|
||||||
|
const languages = ['en', 'nl', 'de', 'es', 'fr']
|
||||||
|
|
||||||
|
export default createSchema({
|
||||||
|
name: 'default',
|
||||||
|
types: schemaTypes.concat([
|
||||||
|
...languages.map(lang => blogSchemaBuilder(lang)),
|
||||||
|
...languages.map(lang => showcaseSchemaBuilder(lang)),
|
||||||
|
newsletter,
|
||||||
|
]),
|
||||||
|
})
|
44
sites/sanity/schemas/showcase.js
Normal file
44
sites/sanity/schemas/showcase.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
export const showcaseSchemaBuilder = (lang) => ({
|
||||||
|
name: `showcase${lang}`,
|
||||||
|
type: 'document',
|
||||||
|
title: `Showcase ${lang.toUpperCase()}`,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
title: 'Title',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'slug',
|
||||||
|
type: 'slug',
|
||||||
|
title: 'Slug',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'date',
|
||||||
|
type: 'date',
|
||||||
|
title: 'Date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'body',
|
||||||
|
title: 'Body',
|
||||||
|
type: 'array',
|
||||||
|
of: [{type: 'block'}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
title: 'Image',
|
||||||
|
type: 'array',
|
||||||
|
of: [{type: 'image'}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'caption',
|
||||||
|
type: 'string',
|
||||||
|
title: 'Main (first) image caption',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'maker',
|
||||||
|
title: 'Maker',
|
||||||
|
type: 'string',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
1
sites/sanity/static/.gitkeep
Normal file
1
sites/sanity/static/.gitkeep
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Files placed here will be served by the Sanity server under the `/static`-prefix
|
BIN
sites/sanity/static/favicon.ico
Normal file
BIN
sites/sanity/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
6
sites/sanity/tsconfig.json
Normal file
6
sites/sanity/tsconfig.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
// Note: This config is only used to help editors like VS Code understand/resolve
|
||||||
|
// parts, the actual transpilation is done by babel. Any compiler configuration in
|
||||||
|
// here will be ignored.
|
||||||
|
"include": ["./node_modules/@sanity/base/types/**/*.ts", "./**/*.ts", "./**/*.tsx"]
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue