media upload
This commit is contained in:
parent
1ab9c10548
commit
239b67719a
BIN
media/pigeon-400x300.jpg
Normal file
BIN
media/pigeon-400x300.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
media/pigeon-768x1024.jpg
Normal file
BIN
media/pigeon-768x1024.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
BIN
media/pigeon.jpg
Normal file
BIN
media/pigeon.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 150 KiB |
@ -28,6 +28,7 @@
|
|||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
|
"prettier": "^3.5.3",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
},
|
},
|
||||||
|
|||||||
267
payload-types.ts
267
payload-types.ts
@ -67,7 +67,11 @@ export interface Config {
|
|||||||
};
|
};
|
||||||
blocks: {};
|
blocks: {};
|
||||||
collections: {
|
collections: {
|
||||||
|
projects: Project;
|
||||||
news: News;
|
news: News;
|
||||||
|
media: Media;
|
||||||
|
documents: Document;
|
||||||
|
data: Datum;
|
||||||
users: User;
|
users: User;
|
||||||
'payload-locked-documents': PayloadLockedDocument;
|
'payload-locked-documents': PayloadLockedDocument;
|
||||||
'payload-preferences': PayloadPreference;
|
'payload-preferences': PayloadPreference;
|
||||||
@ -75,7 +79,11 @@ export interface Config {
|
|||||||
};
|
};
|
||||||
collectionsJoins: {};
|
collectionsJoins: {};
|
||||||
collectionsSelect: {
|
collectionsSelect: {
|
||||||
|
projects: ProjectsSelect<false> | ProjectsSelect<true>;
|
||||||
news: NewsSelect<false> | NewsSelect<true>;
|
news: NewsSelect<false> | NewsSelect<true>;
|
||||||
|
media: MediaSelect<false> | MediaSelect<true>;
|
||||||
|
documents: DocumentsSelect<false> | DocumentsSelect<true>;
|
||||||
|
data: DataSelect<false> | DataSelect<true>;
|
||||||
users: UsersSelect<false> | UsersSelect<true>;
|
users: UsersSelect<false> | UsersSelect<true>;
|
||||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||||
@ -117,6 +125,50 @@ export interface UserAuthOperations {
|
|||||||
password: string;
|
password: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "projects".
|
||||||
|
*/
|
||||||
|
export interface Project {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
/**
|
||||||
|
* The slug is used to identify the news item in the URL.
|
||||||
|
*/
|
||||||
|
slug: string;
|
||||||
|
content: {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Show this project on the homepage.
|
||||||
|
*/
|
||||||
|
featured?: boolean | null;
|
||||||
|
links?:
|
||||||
|
| {
|
||||||
|
link: string;
|
||||||
|
description?: string | null;
|
||||||
|
/**
|
||||||
|
* Optional: organise link under this heading
|
||||||
|
*/
|
||||||
|
group?: string | null;
|
||||||
|
id?: string | null;
|
||||||
|
}[]
|
||||||
|
| null;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "news".
|
* via the `definition` "news".
|
||||||
@ -147,6 +199,93 @@ export interface News {
|
|||||||
createdAt: string;
|
createdAt: string;
|
||||||
_status?: ('draft' | 'published') | null;
|
_status?: ('draft' | 'published') | null;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "media".
|
||||||
|
*/
|
||||||
|
export interface Media {
|
||||||
|
id: number;
|
||||||
|
alt?: string | null;
|
||||||
|
description?: string | null;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
url?: string | null;
|
||||||
|
thumbnailURL?: string | null;
|
||||||
|
filename?: string | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
focalX?: number | null;
|
||||||
|
focalY?: number | null;
|
||||||
|
sizes?: {
|
||||||
|
thumbnail?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
card?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
tablet?: {
|
||||||
|
url?: string | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
filename?: string | null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "documents".
|
||||||
|
*/
|
||||||
|
export interface Document {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description?: string | null;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
url?: string | null;
|
||||||
|
thumbnailURL?: string | null;
|
||||||
|
filename?: string | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
focalX?: number | null;
|
||||||
|
focalY?: number | null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "data".
|
||||||
|
*/
|
||||||
|
export interface Datum {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description?: string | null;
|
||||||
|
source: string;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
url?: string | null;
|
||||||
|
thumbnailURL?: string | null;
|
||||||
|
filename?: string | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
width?: number | null;
|
||||||
|
height?: number | null;
|
||||||
|
focalX?: number | null;
|
||||||
|
focalY?: number | null;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "users".
|
* via the `definition` "users".
|
||||||
@ -171,10 +310,26 @@ export interface User {
|
|||||||
export interface PayloadLockedDocument {
|
export interface PayloadLockedDocument {
|
||||||
id: number;
|
id: number;
|
||||||
document?:
|
document?:
|
||||||
|
| ({
|
||||||
|
relationTo: 'projects';
|
||||||
|
value: number | Project;
|
||||||
|
} | null)
|
||||||
| ({
|
| ({
|
||||||
relationTo: 'news';
|
relationTo: 'news';
|
||||||
value: number | News;
|
value: number | News;
|
||||||
} | null)
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'media';
|
||||||
|
value: number | Media;
|
||||||
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'documents';
|
||||||
|
value: number | Document;
|
||||||
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'data';
|
||||||
|
value: number | Datum;
|
||||||
|
} | null)
|
||||||
| ({
|
| ({
|
||||||
relationTo: 'users';
|
relationTo: 'users';
|
||||||
value: number | User;
|
value: number | User;
|
||||||
@ -221,6 +376,26 @@ export interface PayloadMigration {
|
|||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "projects_select".
|
||||||
|
*/
|
||||||
|
export interface ProjectsSelect<T extends boolean = true> {
|
||||||
|
title?: T;
|
||||||
|
slug?: T;
|
||||||
|
content?: T;
|
||||||
|
featured?: T;
|
||||||
|
links?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
link?: T;
|
||||||
|
description?: T;
|
||||||
|
group?: 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` "news_select".
|
* via the `definition` "news_select".
|
||||||
@ -233,6 +408,98 @@ export interface NewsSelect<T extends boolean = true> {
|
|||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
_status?: T;
|
_status?: T;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "media_select".
|
||||||
|
*/
|
||||||
|
export interface MediaSelect<T extends boolean = true> {
|
||||||
|
alt?: T;
|
||||||
|
description?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
url?: T;
|
||||||
|
thumbnailURL?: T;
|
||||||
|
filename?: T;
|
||||||
|
mimeType?: T;
|
||||||
|
filesize?: T;
|
||||||
|
width?: T;
|
||||||
|
height?: T;
|
||||||
|
focalX?: T;
|
||||||
|
focalY?: T;
|
||||||
|
sizes?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
thumbnail?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
url?: T;
|
||||||
|
width?: T;
|
||||||
|
height?: T;
|
||||||
|
mimeType?: T;
|
||||||
|
filesize?: T;
|
||||||
|
filename?: T;
|
||||||
|
};
|
||||||
|
card?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
url?: T;
|
||||||
|
width?: T;
|
||||||
|
height?: T;
|
||||||
|
mimeType?: T;
|
||||||
|
filesize?: T;
|
||||||
|
filename?: T;
|
||||||
|
};
|
||||||
|
tablet?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
url?: T;
|
||||||
|
width?: T;
|
||||||
|
height?: T;
|
||||||
|
mimeType?: T;
|
||||||
|
filesize?: T;
|
||||||
|
filename?: T;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "documents_select".
|
||||||
|
*/
|
||||||
|
export interface DocumentsSelect<T extends boolean = true> {
|
||||||
|
title?: T;
|
||||||
|
description?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
url?: T;
|
||||||
|
thumbnailURL?: T;
|
||||||
|
filename?: T;
|
||||||
|
mimeType?: T;
|
||||||
|
filesize?: T;
|
||||||
|
width?: T;
|
||||||
|
height?: T;
|
||||||
|
focalX?: T;
|
||||||
|
focalY?: T;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "data_select".
|
||||||
|
*/
|
||||||
|
export interface DataSelect<T extends boolean = true> {
|
||||||
|
title?: T;
|
||||||
|
description?: T;
|
||||||
|
source?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
url?: T;
|
||||||
|
thumbnailURL?: T;
|
||||||
|
filename?: T;
|
||||||
|
mimeType?: T;
|
||||||
|
filesize?: T;
|
||||||
|
width?: T;
|
||||||
|
height?: T;
|
||||||
|
focalX?: T;
|
||||||
|
focalY?: T;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "users_select".
|
* via the `definition` "users_select".
|
||||||
|
|||||||
@ -1,20 +1,29 @@
|
|||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
import { FixedToolbarFeature, lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||||
import { postgresAdapter } from '@payloadcms/db-postgres'
|
import { postgresAdapter } from '@payloadcms/db-postgres'
|
||||||
import { buildConfig } from 'payload'
|
import { buildConfig } from 'payload'
|
||||||
import { News } from './src/collections/News'
|
|
||||||
import { Home } from '@/globals/Home'
|
import { Home } from '@/globals/Home'
|
||||||
|
|
||||||
|
import { News } from './src/collections/News'
|
||||||
|
import { Projects } from '@/collections/Projects'
|
||||||
|
import { Data, Documents, Media } from '@/collections/Files'
|
||||||
|
|
||||||
export default buildConfig({
|
export default buildConfig({
|
||||||
// If you'd like to use Rich Text, pass your editor here
|
// If you'd like to use Rich Text, pass your editor here
|
||||||
editor: lexicalEditor(),
|
editor: lexicalEditor({
|
||||||
|
features: ({ defaultFeatures }) => [
|
||||||
|
...defaultFeatures,
|
||||||
|
FixedToolbarFeature(),
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
|
||||||
serverURL: process.env.SERVER_URL || 'http://localhost:3000',
|
serverURL: process.env.SERVER_URL || 'http://localhost:3000',
|
||||||
|
|
||||||
globals: [Home],
|
globals: [Home],
|
||||||
|
|
||||||
// Define and configure your collections in this array
|
// Define and configure your collections in this array
|
||||||
collections: [News],
|
collections: [Projects, News, Media, Documents, Data],
|
||||||
|
|
||||||
// Your Payload secret - should be a complex and secure string, unguessable
|
// Your Payload secret - should be a complex and secure string, unguessable
|
||||||
secret: process.env.PAYLOAD_SECRET || '',
|
secret: process.env.PAYLOAD_SECRET || '',
|
||||||
|
|||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -54,6 +54,9 @@ importers:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^19
|
specifier: ^19
|
||||||
version: 19.0.4(@types/react@19.0.12)
|
version: 19.0.4(@types/react@19.0.12)
|
||||||
|
prettier:
|
||||||
|
specifier: ^3.5.3
|
||||||
|
version: 3.5.3
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^4
|
specifier: ^4
|
||||||
version: 4.0.17
|
version: 4.0.17
|
||||||
|
|||||||
53
src/app/(frontend)/projects/[slug]/page.tsx
Normal file
53
src/app/(frontend)/projects/[slug]/page.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import configPromise from "@payload-config";
|
||||||
|
import { getPayload } from "payload";
|
||||||
|
import { notFound } from "next/navigation";
|
||||||
|
import { RichText } from "@payloadcms/richtext-lexical/react";
|
||||||
|
|
||||||
|
export default async function Page({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ slug: string }>;
|
||||||
|
}) {
|
||||||
|
const payload = await getPayload({ config: configPromise });
|
||||||
|
const { slug } = await params;
|
||||||
|
|
||||||
|
const result = await payload.find({
|
||||||
|
collection: "projects",
|
||||||
|
where: {
|
||||||
|
slug: {
|
||||||
|
equals: slug,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
depth: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const item = result.docs[0];
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>{item.title}</h1>
|
||||||
|
<RichText data={item.content} className="prose bg-gray-50 p-2" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function generateStaticParams() {
|
||||||
|
const payload = await getPayload({ config: configPromise });
|
||||||
|
|
||||||
|
const projectItems = await payload.find({
|
||||||
|
collection: "projects",
|
||||||
|
depth: 1,
|
||||||
|
limit: 5,
|
||||||
|
select: {
|
||||||
|
slug: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return projectItems.docs.map((item) => ({
|
||||||
|
slug: item.slug,
|
||||||
|
}));
|
||||||
|
}
|
||||||
39
src/app/(frontend)/projects/page.tsx
Normal file
39
src/app/(frontend)/projects/page.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import configPromise from "@payload-config";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { getPayload } from "payload";
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
const payload = await getPayload({ config: configPromise });
|
||||||
|
|
||||||
|
const projectItems = await payload.find({
|
||||||
|
collection: "projects",
|
||||||
|
depth: 1,
|
||||||
|
limit: 5,
|
||||||
|
select: {
|
||||||
|
title: true,
|
||||||
|
slug: true,
|
||||||
|
},
|
||||||
|
sort: "-created_at",
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Projects</h1>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{projectItems.docs.map((projectItem) => (
|
||||||
|
<li key={projectItem.id} className="p-4">
|
||||||
|
<h3 className="text-lg">
|
||||||
|
<Link
|
||||||
|
href={`
|
||||||
|
/projects/${projectItem.slug}`}
|
||||||
|
>
|
||||||
|
{projectItem.title}
|
||||||
|
</Link>
|
||||||
|
</h3>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||||
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||||
|
import { FixedToolbarFeatureClient as FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
@ -24,6 +25,7 @@ import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0
|
|||||||
export const importMap = {
|
export const importMap = {
|
||||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
|
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
|
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
|
"@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient": FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
"@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
"@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
|||||||
1
src/collections/Documents.ts
Normal file
1
src/collections/Documents.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
import type { CollectionConfig } from "payload";
|
||||||
90
src/collections/Files.ts
Normal file
90
src/collections/Files.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import type { CollectionConfig } from "payload";
|
||||||
|
|
||||||
|
export const Media: CollectionConfig = {
|
||||||
|
slug: 'media',
|
||||||
|
upload: {
|
||||||
|
staticDir: 'media',
|
||||||
|
imageSizes: [
|
||||||
|
{
|
||||||
|
name: 'thumbnail',
|
||||||
|
width: 400,
|
||||||
|
height: 300,
|
||||||
|
position: 'centre',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'card',
|
||||||
|
width: 768,
|
||||||
|
height: 1024,
|
||||||
|
position: 'centre',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tablet',
|
||||||
|
width: 1024,
|
||||||
|
height: undefined,
|
||||||
|
position: 'centre',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
adminThumbnail: 'thumbnail',
|
||||||
|
mimeTypes: ['image/*'],
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'alt',
|
||||||
|
label: 'Alt Text',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
type: 'textarea',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Documents: CollectionConfig = {
|
||||||
|
slug: 'documents',
|
||||||
|
upload: {
|
||||||
|
staticDir: 'documents',
|
||||||
|
mimeTypes: ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
label: 'Title',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
type: 'textarea',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Data: CollectionConfig = {
|
||||||
|
slug: 'data',
|
||||||
|
upload: {
|
||||||
|
staticDir: 'data',
|
||||||
|
mimeTypes: ['application/json', 'text/csv', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/plain'],
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
label: 'Title',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
type: 'textarea',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'source',
|
||||||
|
label: 'Source',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
@ -1,11 +1,6 @@
|
|||||||
|
import { formatSlug } from "@/lib/slugs";
|
||||||
import { CollectionConfig } from "payload";
|
import { CollectionConfig } from "payload";
|
||||||
|
|
||||||
export const formatSlug = (val: string): string =>
|
|
||||||
val
|
|
||||||
.replace(/ /g, '-')
|
|
||||||
.replace(/[^\w-]+/g, '')
|
|
||||||
.toLowerCase()
|
|
||||||
|
|
||||||
export const News: CollectionConfig = {
|
export const News: CollectionConfig = {
|
||||||
slug: 'news',
|
slug: 'news',
|
||||||
fields: [
|
fields: [
|
||||||
@ -28,18 +23,7 @@ export const News: CollectionConfig = {
|
|||||||
},
|
},
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeValidate: [
|
beforeValidate: [
|
||||||
({data, operation, value}) => {
|
formatSlug('title'),
|
||||||
if (typeof value === 'string') {
|
|
||||||
return formatSlug(value);
|
|
||||||
}
|
|
||||||
if (operation === 'create' || !data?.slug) {
|
|
||||||
const fallbackData = data?.title;
|
|
||||||
if (fallbackData && typeof fallbackData === 'string') {
|
|
||||||
return formatSlug(fallbackData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
84
src/collections/Projects.ts
Normal file
84
src/collections/Projects.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { formatSlug } from "@/lib/slugs";
|
||||||
|
import { CollectionConfig } from "payload";
|
||||||
|
|
||||||
|
export const Projects: CollectionConfig = {
|
||||||
|
slug: 'projects',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
label: 'Title',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'slug',
|
||||||
|
label: 'Slug',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
description: 'The slug is used to identify the news item in the URL.',
|
||||||
|
// readOnly: true,
|
||||||
|
},
|
||||||
|
hooks: {
|
||||||
|
beforeValidate: [
|
||||||
|
formatSlug('title'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'content',
|
||||||
|
label: 'Content',
|
||||||
|
type: 'richText',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
// list of files
|
||||||
|
// gallery
|
||||||
|
// keywords
|
||||||
|
// is featured?
|
||||||
|
{
|
||||||
|
name: 'featured',
|
||||||
|
label: 'Featured',
|
||||||
|
type: 'checkbox',
|
||||||
|
defaultValue: false,
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
description: 'Show this project on the homepage.',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// links
|
||||||
|
{
|
||||||
|
name: 'links',
|
||||||
|
label: 'Links',
|
||||||
|
type: 'array',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'link',
|
||||||
|
label: 'Link',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
type: 'text',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'group',
|
||||||
|
label: 'Group',
|
||||||
|
type: 'text',
|
||||||
|
required: false,
|
||||||
|
admin: {
|
||||||
|
description: 'Optional: organise link under this heading',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
21
src/lib/slugs.ts
Normal file
21
src/lib/slugs.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { FieldHook } from "payload";
|
||||||
|
|
||||||
|
export const format = (val: string): string =>
|
||||||
|
val
|
||||||
|
.replace(/ /g, '-')
|
||||||
|
.replace(/[^\w-]+/g, '')
|
||||||
|
.toLowerCase()
|
||||||
|
|
||||||
|
export const formatSlug = (name: string): FieldHook =>
|
||||||
|
({data, operation, value}) => {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return format(value);
|
||||||
|
}
|
||||||
|
if (operation === 'create' || !data?.[name]) {
|
||||||
|
const fallbackData = data?.[name];
|
||||||
|
if (fallbackData && typeof fallbackData === 'string') {
|
||||||
|
return format(fallbackData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user