Add Portfolio collection with 7 fields
Create Portfolio collection for managing website portfolio items. Includes title, slug, url, image, description, websiteType, and tags fields. Configured access control for authenticated create/ update/delete operations with public read access.
This commit is contained in:
@@ -0,0 +1,60 @@
|
|||||||
|
import { Portfolio } from '../index'
|
||||||
|
|
||||||
|
describe('Portfolio Collection', () => {
|
||||||
|
it('should have correct slug', () => {
|
||||||
|
expect(Portfolio.slug).toBe('portfolio')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should have all required fields', () => {
|
||||||
|
const fieldNames = Portfolio.fields.map((f) => ('name' in f ? f.name : null))
|
||||||
|
expect(fieldNames).toContain('title')
|
||||||
|
expect(fieldNames).toContain('slug')
|
||||||
|
expect(fieldNames).toContain('url')
|
||||||
|
expect(fieldNames).toContain('image')
|
||||||
|
expect(fieldNames).toContain('description')
|
||||||
|
expect(fieldNames).toContain('websiteType')
|
||||||
|
expect(fieldNames).toContain('tags')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should have correct access control', () => {
|
||||||
|
expect(Portfolio.access.read).toBeDefined()
|
||||||
|
expect(Portfolio.access.create).toBeDefined()
|
||||||
|
expect(Portfolio.access.update).toBeDefined()
|
||||||
|
expect(Portfolio.access.delete).toBeDefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should have admin configuration', () => {
|
||||||
|
expect(Portfolio.admin).toBeDefined()
|
||||||
|
expect(Portfolio.admin?.useAsTitle).toBe('title')
|
||||||
|
expect(Portfolio.admin?.defaultColumns).toEqual(['title', 'websiteType', 'updatedAt'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should have websiteType field with correct options', () => {
|
||||||
|
const websiteTypeField = Portfolio.fields.find((f) => f.name === 'websiteType')
|
||||||
|
expect(websiteTypeField).toBeDefined()
|
||||||
|
expect(websiteTypeField?.type).toBe('select')
|
||||||
|
if (websiteTypeField?.type === 'select') {
|
||||||
|
const optionValues = websiteTypeField.options.map((o) => o.value)
|
||||||
|
expect(optionValues).toContain('corporate')
|
||||||
|
expect(optionValues).toContain('ecommerce')
|
||||||
|
expect(optionValues).toContain('landing')
|
||||||
|
expect(optionValues).toContain('brand')
|
||||||
|
expect(optionValues).toContain('other')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should have tags field as array', () => {
|
||||||
|
const tagsField = Portfolio.fields.find((f) => f.name === 'tags')
|
||||||
|
expect(tagsField).toBeDefined()
|
||||||
|
expect(tagsField?.type).toBe('array')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should have image field with relation to media', () => {
|
||||||
|
const imageField = Portfolio.fields.find((f) => f.name === 'image')
|
||||||
|
expect(imageField).toBeDefined()
|
||||||
|
expect(imageField?.type).toBe('upload')
|
||||||
|
if (imageField?.type === 'upload') {
|
||||||
|
expect(imageField.relationTo).toBe('media')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
75
apps/backend/src/collections/Portfolio/index.ts
Normal file
75
apps/backend/src/collections/Portfolio/index.ts
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import type { CollectionConfig } from 'payload'
|
||||||
|
|
||||||
|
import { authenticated } from '../../access/authenticated'
|
||||||
|
import { anyone } from '../../access/anyone'
|
||||||
|
import { slugField } from '@/fields/slug'
|
||||||
|
|
||||||
|
export const Portfolio: CollectionConfig = {
|
||||||
|
slug: 'portfolio',
|
||||||
|
access: {
|
||||||
|
create: authenticated,
|
||||||
|
read: anyone,
|
||||||
|
update: authenticated,
|
||||||
|
delete: authenticated,
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
useAsTitle: 'title',
|
||||||
|
defaultColumns: ['title', 'websiteType', 'updatedAt'],
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'url',
|
||||||
|
type: 'text',
|
||||||
|
admin: {
|
||||||
|
description: 'Website URL (e.g., https://example.com)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'upload',
|
||||||
|
relationTo: 'media',
|
||||||
|
required: true,
|
||||||
|
admin: {
|
||||||
|
description: 'Preview image stored in R2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'textarea',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'websiteType',
|
||||||
|
type: 'select',
|
||||||
|
options: [
|
||||||
|
{ label: '企業官網', value: 'corporate' },
|
||||||
|
{ label: '電商網站', value: 'ecommerce' },
|
||||||
|
{ label: '活動頁面', value: 'landing' },
|
||||||
|
{ label: '品牌網站', value: 'brand' },
|
||||||
|
{ label: '其他', value: 'other' },
|
||||||
|
],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tags',
|
||||||
|
type: 'array',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'tag',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
...slugField(),
|
||||||
|
],
|
||||||
|
versions: {
|
||||||
|
drafts: {
|
||||||
|
autosave: true,
|
||||||
|
},
|
||||||
|
maxPerDoc: 10,
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -72,9 +72,8 @@ export interface Config {
|
|||||||
media: Media;
|
media: Media;
|
||||||
categories: Category;
|
categories: Category;
|
||||||
users: User;
|
users: User;
|
||||||
|
portfolio: Portfolio;
|
||||||
redirects: Redirect;
|
redirects: Redirect;
|
||||||
forms: Form;
|
|
||||||
'form-submissions': FormSubmission;
|
|
||||||
search: Search;
|
search: Search;
|
||||||
'payload-jobs': PayloadJob;
|
'payload-jobs': PayloadJob;
|
||||||
'payload-locked-documents': PayloadLockedDocument;
|
'payload-locked-documents': PayloadLockedDocument;
|
||||||
@@ -88,9 +87,8 @@ export interface Config {
|
|||||||
media: MediaSelect<false> | MediaSelect<true>;
|
media: MediaSelect<false> | MediaSelect<true>;
|
||||||
categories: CategoriesSelect<false> | CategoriesSelect<true>;
|
categories: CategoriesSelect<false> | CategoriesSelect<true>;
|
||||||
users: UsersSelect<false> | UsersSelect<true>;
|
users: UsersSelect<false> | UsersSelect<true>;
|
||||||
|
portfolio: PortfolioSelect<false> | PortfolioSelect<true>;
|
||||||
redirects: RedirectsSelect<false> | RedirectsSelect<true>;
|
redirects: RedirectsSelect<false> | RedirectsSelect<true>;
|
||||||
forms: FormsSelect<false> | FormsSelect<true>;
|
|
||||||
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
|
|
||||||
search: SearchSelect<false> | SearchSelect<true>;
|
search: SearchSelect<false> | SearchSelect<true>;
|
||||||
'payload-jobs': PayloadJobsSelect<false> | PayloadJobsSelect<true>;
|
'payload-jobs': PayloadJobsSelect<false> | PayloadJobsSelect<true>;
|
||||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||||
@@ -154,7 +152,7 @@ export interface Page {
|
|||||||
root: {
|
root: {
|
||||||
type: string;
|
type: string;
|
||||||
children: {
|
children: {
|
||||||
type: string;
|
type: any;
|
||||||
version: number;
|
version: number;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
@@ -191,7 +189,7 @@ export interface Page {
|
|||||||
| null;
|
| null;
|
||||||
media?: (string | null) | Media;
|
media?: (string | null) | Media;
|
||||||
};
|
};
|
||||||
layout: (CallToActionBlock | ContentBlock | MediaBlock | ArchiveBlock | FormBlock)[];
|
layout: (CallToActionBlock | ContentBlock | MediaBlock | ArchiveBlock)[];
|
||||||
meta?: {
|
meta?: {
|
||||||
title?: string | null;
|
title?: string | null;
|
||||||
/**
|
/**
|
||||||
@@ -219,7 +217,7 @@ export interface Post {
|
|||||||
root: {
|
root: {
|
||||||
type: string;
|
type: string;
|
||||||
children: {
|
children: {
|
||||||
type: string;
|
type: any;
|
||||||
version: number;
|
version: number;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
@@ -265,7 +263,7 @@ export interface Media {
|
|||||||
root: {
|
root: {
|
||||||
type: string;
|
type: string;
|
||||||
children: {
|
children: {
|
||||||
type: string;
|
type: any;
|
||||||
version: number;
|
version: number;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
@@ -401,7 +399,7 @@ export interface CallToActionBlock {
|
|||||||
root: {
|
root: {
|
||||||
type: string;
|
type: string;
|
||||||
children: {
|
children: {
|
||||||
type: string;
|
type: any;
|
||||||
version: number;
|
version: number;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
@@ -452,7 +450,7 @@ export interface ContentBlock {
|
|||||||
root: {
|
root: {
|
||||||
type: string;
|
type: string;
|
||||||
children: {
|
children: {
|
||||||
type: string;
|
type: any;
|
||||||
version: number;
|
version: number;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
@@ -509,7 +507,7 @@ export interface ArchiveBlock {
|
|||||||
root: {
|
root: {
|
||||||
type: string;
|
type: string;
|
||||||
children: {
|
children: {
|
||||||
type: string;
|
type: any;
|
||||||
version: number;
|
version: number;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
@@ -536,203 +534,32 @@ export interface ArchiveBlock {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "FormBlock".
|
* via the `definition` "portfolio".
|
||||||
*/
|
*/
|
||||||
export interface FormBlock {
|
export interface Portfolio {
|
||||||
form: string | Form;
|
|
||||||
enableIntro?: boolean | null;
|
|
||||||
introContent?: {
|
|
||||||
root: {
|
|
||||||
type: string;
|
|
||||||
children: {
|
|
||||||
type: string;
|
|
||||||
version: number;
|
|
||||||
[k: string]: unknown;
|
|
||||||
}[];
|
|
||||||
direction: ('ltr' | 'rtl') | null;
|
|
||||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
|
||||||
indent: number;
|
|
||||||
version: number;
|
|
||||||
};
|
|
||||||
[k: string]: unknown;
|
|
||||||
} | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'formBlock';
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "forms".
|
|
||||||
*/
|
|
||||||
export interface Form {
|
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
fields?:
|
|
||||||
| (
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
required?: boolean | null;
|
|
||||||
defaultValue?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'checkbox';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
required?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'country';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
required?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'email';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
message?: {
|
|
||||||
root: {
|
|
||||||
type: string;
|
|
||||||
children: {
|
|
||||||
type: string;
|
|
||||||
version: number;
|
|
||||||
[k: string]: unknown;
|
|
||||||
}[];
|
|
||||||
direction: ('ltr' | 'rtl') | null;
|
|
||||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
|
||||||
indent: number;
|
|
||||||
version: number;
|
|
||||||
};
|
|
||||||
[k: string]: unknown;
|
|
||||||
} | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'message';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
defaultValue?: number | null;
|
|
||||||
required?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'number';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
defaultValue?: string | null;
|
|
||||||
placeholder?: string | null;
|
|
||||||
options?:
|
|
||||||
| {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
id?: string | null;
|
|
||||||
}[]
|
|
||||||
| null;
|
|
||||||
required?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'select';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
required?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'state';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
defaultValue?: string | null;
|
|
||||||
required?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'text';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
name: string;
|
|
||||||
label?: string | null;
|
|
||||||
width?: number | null;
|
|
||||||
defaultValue?: string | null;
|
|
||||||
required?: boolean | null;
|
|
||||||
id?: string | null;
|
|
||||||
blockName?: string | null;
|
|
||||||
blockType: 'textarea';
|
|
||||||
}
|
|
||||||
)[]
|
|
||||||
| null;
|
|
||||||
submitButtonLabel?: string | null;
|
|
||||||
/**
|
/**
|
||||||
* Choose whether to display an on-page message or redirect to a different page after they submit the form.
|
* Website URL (e.g., https://example.com)
|
||||||
*/
|
*/
|
||||||
confirmationType?: ('message' | 'redirect') | null;
|
url?: string | null;
|
||||||
confirmationMessage?: {
|
|
||||||
root: {
|
|
||||||
type: string;
|
|
||||||
children: {
|
|
||||||
type: string;
|
|
||||||
version: number;
|
|
||||||
[k: string]: unknown;
|
|
||||||
}[];
|
|
||||||
direction: ('ltr' | 'rtl') | null;
|
|
||||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
|
||||||
indent: number;
|
|
||||||
version: number;
|
|
||||||
};
|
|
||||||
[k: string]: unknown;
|
|
||||||
} | null;
|
|
||||||
redirect?: {
|
|
||||||
url: string;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Send custom emails when the form submits. Use comma separated lists to send the same email to multiple recipients. To reference a value from this form, wrap that field's name with double curly brackets, i.e. {{firstName}}. You can use a wildcard {{*}} to output all data and {{*:table}} to format it as an HTML table in the email.
|
* Preview image stored in R2
|
||||||
*/
|
*/
|
||||||
emails?:
|
image: string | Media;
|
||||||
|
description?: string | null;
|
||||||
|
websiteType: 'corporate' | 'ecommerce' | 'landing' | 'brand' | 'other';
|
||||||
|
tags?:
|
||||||
| {
|
| {
|
||||||
emailTo?: string | null;
|
tag?: string | null;
|
||||||
cc?: string | null;
|
|
||||||
bcc?: string | null;
|
|
||||||
replyTo?: string | null;
|
|
||||||
emailFrom?: string | null;
|
|
||||||
subject: string;
|
|
||||||
/**
|
|
||||||
* Enter the message that should be sent in this email.
|
|
||||||
*/
|
|
||||||
message?: {
|
|
||||||
root: {
|
|
||||||
type: string;
|
|
||||||
children: {
|
|
||||||
type: string;
|
|
||||||
version: number;
|
|
||||||
[k: string]: unknown;
|
|
||||||
}[];
|
|
||||||
direction: ('ltr' | 'rtl') | null;
|
|
||||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
|
||||||
indent: number;
|
|
||||||
version: number;
|
|
||||||
};
|
|
||||||
[k: string]: unknown;
|
|
||||||
} | null;
|
|
||||||
id?: string | null;
|
id?: string | null;
|
||||||
}[]
|
}[]
|
||||||
| null;
|
| null;
|
||||||
|
slug?: string | null;
|
||||||
|
slugLock?: boolean | null;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
_status?: ('draft' | 'published') | null;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
@@ -760,23 +587,6 @@ export interface Redirect {
|
|||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "form-submissions".
|
|
||||||
*/
|
|
||||||
export interface FormSubmission {
|
|
||||||
id: string;
|
|
||||||
form: string | Form;
|
|
||||||
submissionData?:
|
|
||||||
| {
|
|
||||||
field: string;
|
|
||||||
value: string;
|
|
||||||
id?: string | null;
|
|
||||||
}[]
|
|
||||||
| null;
|
|
||||||
updatedAt: string;
|
|
||||||
createdAt: string;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* This is a collection of automatically created search results. These results are used by the global site search and will be updated automatically as documents in the CMS are created or updated.
|
* This is a collection of automatically created search results. These results are used by the global site search and will be updated automatically as documents in the CMS are created or updated.
|
||||||
*
|
*
|
||||||
@@ -927,18 +737,14 @@ export interface PayloadLockedDocument {
|
|||||||
relationTo: 'users';
|
relationTo: 'users';
|
||||||
value: string | User;
|
value: string | User;
|
||||||
} | null)
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'portfolio';
|
||||||
|
value: string | Portfolio;
|
||||||
|
} | null)
|
||||||
| ({
|
| ({
|
||||||
relationTo: 'redirects';
|
relationTo: 'redirects';
|
||||||
value: string | Redirect;
|
value: string | Redirect;
|
||||||
} | null)
|
} | null)
|
||||||
| ({
|
|
||||||
relationTo: 'forms';
|
|
||||||
value: string | Form;
|
|
||||||
} | null)
|
|
||||||
| ({
|
|
||||||
relationTo: 'form-submissions';
|
|
||||||
value: string | FormSubmission;
|
|
||||||
} | null)
|
|
||||||
| ({
|
| ({
|
||||||
relationTo: 'search';
|
relationTo: 'search';
|
||||||
value: string | Search;
|
value: string | Search;
|
||||||
@@ -1024,7 +830,6 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
content?: T | ContentBlockSelect<T>;
|
content?: T | ContentBlockSelect<T>;
|
||||||
mediaBlock?: T | MediaBlockSelect<T>;
|
mediaBlock?: T | MediaBlockSelect<T>;
|
||||||
archive?: T | ArchiveBlockSelect<T>;
|
archive?: T | ArchiveBlockSelect<T>;
|
||||||
formBlock?: T | FormBlockSelect<T>;
|
|
||||||
};
|
};
|
||||||
meta?:
|
meta?:
|
||||||
| T
|
| T
|
||||||
@@ -1113,17 +918,6 @@ export interface ArchiveBlockSelect<T extends boolean = true> {
|
|||||||
id?: T;
|
id?: T;
|
||||||
blockName?: T;
|
blockName?: T;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "FormBlock_select".
|
|
||||||
*/
|
|
||||||
export interface FormBlockSelect<T extends boolean = true> {
|
|
||||||
form?: T;
|
|
||||||
enableIntro?: T;
|
|
||||||
introContent?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "posts_select".
|
* via the `definition` "posts_select".
|
||||||
@@ -1291,6 +1085,28 @@ export interface UsersSelect<T extends boolean = true> {
|
|||||||
expiresAt?: T;
|
expiresAt?: T;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "portfolio_select".
|
||||||
|
*/
|
||||||
|
export interface PortfolioSelect<T extends boolean = true> {
|
||||||
|
title?: T;
|
||||||
|
url?: T;
|
||||||
|
image?: T;
|
||||||
|
description?: T;
|
||||||
|
websiteType?: T;
|
||||||
|
tags?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
tag?: T;
|
||||||
|
id?: T;
|
||||||
|
};
|
||||||
|
slug?: T;
|
||||||
|
slugLock?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
_status?: T;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "redirects_select".
|
* via the `definition` "redirects_select".
|
||||||
@@ -1307,155 +1123,6 @@ export interface RedirectsSelect<T extends boolean = true> {
|
|||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "forms_select".
|
|
||||||
*/
|
|
||||||
export interface FormsSelect<T extends boolean = true> {
|
|
||||||
title?: T;
|
|
||||||
fields?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
checkbox?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
required?: T;
|
|
||||||
defaultValue?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
country?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
required?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
email?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
required?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
message?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
message?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
number?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
defaultValue?: T;
|
|
||||||
required?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
select?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
defaultValue?: T;
|
|
||||||
placeholder?: T;
|
|
||||||
options?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
label?: T;
|
|
||||||
value?: T;
|
|
||||||
id?: T;
|
|
||||||
};
|
|
||||||
required?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
state?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
required?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
text?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
defaultValue?: T;
|
|
||||||
required?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
textarea?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
name?: T;
|
|
||||||
label?: T;
|
|
||||||
width?: T;
|
|
||||||
defaultValue?: T;
|
|
||||||
required?: T;
|
|
||||||
id?: T;
|
|
||||||
blockName?: T;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
submitButtonLabel?: T;
|
|
||||||
confirmationType?: T;
|
|
||||||
confirmationMessage?: T;
|
|
||||||
redirect?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
url?: T;
|
|
||||||
};
|
|
||||||
emails?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
emailTo?: T;
|
|
||||||
cc?: T;
|
|
||||||
bcc?: T;
|
|
||||||
replyTo?: T;
|
|
||||||
emailFrom?: T;
|
|
||||||
subject?: T;
|
|
||||||
message?: T;
|
|
||||||
id?: T;
|
|
||||||
};
|
|
||||||
updatedAt?: T;
|
|
||||||
createdAt?: T;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "form-submissions_select".
|
|
||||||
*/
|
|
||||||
export interface FormSubmissionsSelect<T extends boolean = true> {
|
|
||||||
form?: T;
|
|
||||||
submissionData?:
|
|
||||||
| T
|
|
||||||
| {
|
|
||||||
field?: T;
|
|
||||||
value?: T;
|
|
||||||
id?: T;
|
|
||||||
};
|
|
||||||
updatedAt?: T;
|
|
||||||
createdAt?: T;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "search_select".
|
* via the `definition` "search_select".
|
||||||
@@ -1716,7 +1383,7 @@ export interface BannerBlock {
|
|||||||
root: {
|
root: {
|
||||||
type: string;
|
type: string;
|
||||||
children: {
|
children: {
|
||||||
type: string;
|
type: any;
|
||||||
version: number;
|
version: number;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}[];
|
}[];
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { fileURLToPath } from 'url'
|
|||||||
import { Categories } from './collections/Categories'
|
import { Categories } from './collections/Categories'
|
||||||
import { Media } from './collections/Media'
|
import { Media } from './collections/Media'
|
||||||
import { Pages } from './collections/Pages'
|
import { Pages } from './collections/Pages'
|
||||||
|
import { Portfolio } from './collections/Portfolio'
|
||||||
import { Posts } from './collections/Posts'
|
import { Posts } from './collections/Posts'
|
||||||
import { Users } from './collections/Users'
|
import { Users } from './collections/Users'
|
||||||
import { Footer } from './Footer/config'
|
import { Footer } from './Footer/config'
|
||||||
@@ -62,7 +63,7 @@ export default buildConfig({
|
|||||||
db: mongooseAdapter({
|
db: mongooseAdapter({
|
||||||
url: process.env.DATABASE_URI || '',
|
url: process.env.DATABASE_URI || '',
|
||||||
}),
|
}),
|
||||||
collections: [Pages, Posts, Media, Categories, Users],
|
collections: [Pages, Posts, Media, Categories, Users, Portfolio],
|
||||||
cors: [
|
cors: [
|
||||||
getServerSideURL(),
|
getServerSideURL(),
|
||||||
'http://localhost:4321', // Astro dev server
|
'http://localhost:4321', // Astro dev server
|
||||||
|
|||||||
Reference in New Issue
Block a user