diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..b58b603
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,5 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..5331ad8
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..79ee123
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dave-dmg.iml b/.idea/dave-dmg.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.idea/dave-dmg.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..03d9549
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..36ef6f3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/prettier.xml b/.idea/prettier.xml
new file mode 100644
index 0000000..b0c1c68
--- /dev/null
+++ b/.idea/prettier.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/keystatic/components/general/index.ts b/src/keystatic/components/general/index.ts
new file mode 100644
index 0000000..281b513
--- /dev/null
+++ b/src/keystatic/components/general/index.ts
@@ -0,0 +1 @@
+export const generalComponents = {};
diff --git a/src/keystatic/fields/general/article.ts b/src/keystatic/fields/general/article.ts
new file mode 100644
index 0000000..4851f90
--- /dev/null
+++ b/src/keystatic/fields/general/article.ts
@@ -0,0 +1,35 @@
+import { ComponentSchema, fields } from '@keystatic/core';
+
+import { createContentField } from './content';
+import { createPathField } from './path';
+import { createMetaField } from './meta';
+
+export const createArticleField = (
+ imageSubfolder: string,
+ defaultPath: string = ''
+) => ({
+ title: fields.slug({ name: { label: 'Title' } }),
+ summary: fields.text({
+ label: 'Summary',
+ multiline: true,
+ }),
+ path: createPathField(defaultPath),
+ cover: fields.object({
+ src: fields.image({
+ label: 'Cover Image',
+ directory: `public/images/covers/${imageSubfolder}`,
+ publicPath: `/image/covers/${imageSubfolder}`,
+ }),
+ alt: fields.text({ label: 'Alt' }),
+ caption: fields.text({
+ label: 'Caption',
+ multiline: true,
+ }),
+ showInHeader: fields.checkbox({
+ label: 'Show in Header',
+ defaultValue: false,
+ }),
+ }),
+ meta: createMetaField(),
+ content: createContentField(imageSubfolder),
+});
diff --git a/src/keystatic/fields/general/content.ts b/src/keystatic/fields/general/content.ts
new file mode 100644
index 0000000..24c89ef
--- /dev/null
+++ b/src/keystatic/fields/general/content.ts
@@ -0,0 +1,22 @@
+import { fields } from '@keystatic/core';
+import { ContentComponent } from '@keystatic/core/content-components';
+
+import { generalComponents } from '@/keystatic/components/general';
+
+export const createContentField = (
+ imageSubfolder: string,
+ additionalComponents?: Record
+) =>
+ fields.markdoc({
+ label: 'Content',
+ options: {
+ image: {
+ directory: `public/images/content/${imageSubfolder}`,
+ publicPath: `/images/content/${imageSubfolder}`,
+ },
+ },
+ components: {
+ ...generalComponents,
+ ...additionalComponents,
+ },
+ });
diff --git a/src/keystatic/fields/general/meta.ts b/src/keystatic/fields/general/meta.ts
new file mode 100644
index 0000000..aeb8cb8
--- /dev/null
+++ b/src/keystatic/fields/general/meta.ts
@@ -0,0 +1,31 @@
+import { ComponentSchema, fields } from '@keystatic/core';
+
+export const createMetaField = (): ComponentSchema =>
+ fields.object(
+ {
+ publicationDate: fields.datetime({
+ label: 'Publication Date',
+ defaultValue: { kind: 'now' },
+ }),
+ updateDate: fields.datetime({
+ label: 'Update Date',
+ }),
+ tags: fields.array(
+ fields.relationship({
+ label: 'Tags',
+ collection: 'tags',
+ }),
+ {
+ label: 'Tags',
+ itemLabel: (props): string => props.value || 'Select Tag',
+ }
+ ),
+ author: fields.relationship({
+ label: 'Author',
+ collection: 'authors',
+ }),
+ },
+ {
+ label: 'Meta Information',
+ }
+ );
diff --git a/src/keystatic/fields/general/operators.ts b/src/keystatic/fields/general/operators.ts
new file mode 100644
index 0000000..8599451
--- /dev/null
+++ b/src/keystatic/fields/general/operators.ts
@@ -0,0 +1,29 @@
+import { ComponentSchema, fields } from '@keystatic/core';
+
+export const createNumOperatorField = (): ComponentSchema =>
+ fields.select({
+ label: 'Operator',
+ options: [
+ {
+ label: '>=',
+ value: 'gte',
+ },
+ {
+ label: '>',
+ value: 'gt',
+ },
+ {
+ label: '=',
+ value: 'eq',
+ },
+ {
+ label: '<',
+ value: 'lt',
+ },
+ {
+ label: '<=',
+ value: 'lte',
+ },
+ ],
+ defaultValue: 'eq',
+ });
diff --git a/src/keystatic/fields/general/path.ts b/src/keystatic/fields/general/path.ts
new file mode 100644
index 0000000..cb0a06e
--- /dev/null
+++ b/src/keystatic/fields/general/path.ts
@@ -0,0 +1,8 @@
+import { ComponentSchema, fields } from '@keystatic/core';
+
+export const createPathField = (defaultValue: string): ComponentSchema =>
+ fields.text({
+ label: 'Path',
+ description: 'Path on the Website',
+ defaultValue: defaultValue,
+ });