Clone starter
This commit is contained in:
128
apps/api/src/blocks/Menu.ts
Normal file
128
apps/api/src/blocks/Menu.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import payload from "payload";
|
||||
import { Block } from "payload/types";
|
||||
import Pages from "../collections/Pages";
|
||||
import linkField from "../fields/linkField";
|
||||
|
||||
export const Menu: Block = {
|
||||
slug: "menu",
|
||||
interfaceName: "Menu",
|
||||
fields: [
|
||||
{
|
||||
name: "type",
|
||||
type: "select",
|
||||
options: ["default"],
|
||||
required: true,
|
||||
defaultValue: "default",
|
||||
},
|
||||
{
|
||||
name: "menus",
|
||||
type: "array",
|
||||
fields: [
|
||||
{
|
||||
name: "mainMenu",
|
||||
type: "group",
|
||||
interfaceName: "MainMenu",
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
fields: [
|
||||
{
|
||||
name: "type",
|
||||
type: "radio",
|
||||
options: [
|
||||
{
|
||||
label: "Internal link",
|
||||
value: "reference",
|
||||
},
|
||||
{
|
||||
label: "Custom URL",
|
||||
value: "custom",
|
||||
},
|
||||
{
|
||||
label: "None",
|
||||
value: "none",
|
||||
},
|
||||
],
|
||||
defaultValue: "reference",
|
||||
admin: {
|
||||
layout: "horizontal",
|
||||
width: "50%",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "newTab",
|
||||
label: "Open in new tab",
|
||||
type: "checkbox",
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.type != "none",
|
||||
width: "50%",
|
||||
style: {
|
||||
alignSelf: "flex-end",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
label: "Document to link to",
|
||||
type: "relationship",
|
||||
relationTo: [Pages.slug],
|
||||
required: true,
|
||||
maxDepth: 0,
|
||||
admin: {
|
||||
condition: (_, siblingData) =>
|
||||
siblingData?.type === "reference",
|
||||
width: "50%",
|
||||
},
|
||||
hooks: {
|
||||
afterRead: [
|
||||
async ({ value, siblingData }) => {
|
||||
if (value && siblingData.type === "reference") {
|
||||
const id = value.value;
|
||||
const pages = await payload.find({
|
||||
collection: "pages",
|
||||
where: {
|
||||
id: { equals: id },
|
||||
},
|
||||
depth: 0,
|
||||
});
|
||||
|
||||
if (pages.docs[0]?.slug)
|
||||
siblingData.url = pages.docs[0].slug;
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "url",
|
||||
label: "Custom URL",
|
||||
type: "text",
|
||||
required: true,
|
||||
admin: {
|
||||
condition: (_, siblingData) =>
|
||||
siblingData?.type === "custom",
|
||||
width: "50%",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "label",
|
||||
label: "Label",
|
||||
type: "text",
|
||||
required: true,
|
||||
admin: {
|
||||
width: "50%",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "subMenu",
|
||||
type: "array",
|
||||
fields: [linkField()],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
17
apps/api/src/blocks/PageContent.ts
Normal file
17
apps/api/src/blocks/PageContent.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { Block } from "payload/types";
|
||||
|
||||
export const PageContent: Block = {
|
||||
slug: "pageContent",
|
||||
interfaceName: "PageContent",
|
||||
fields: [
|
||||
{
|
||||
name: "description",
|
||||
type: "textarea",
|
||||
defaultValue:
|
||||
"This block will display the content of the page (if any). Please edit the original page change the value.",
|
||||
admin: {
|
||||
readOnly: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
52
apps/api/src/blocks/PageList.ts
Normal file
52
apps/api/src/blocks/PageList.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { Block } from "payload/types";
|
||||
import Categories from "../collections/Categories";
|
||||
import { PagesField } from "../collections/Pages";
|
||||
import Tags from "../collections/Tags";
|
||||
|
||||
const PageListField = {
|
||||
numberOfItems: "numberOfItems",
|
||||
filterByCategories: "filterByCategories",
|
||||
filterByTags: "filterByTags",
|
||||
sortBy: "sortBy",
|
||||
pages: "pages",
|
||||
};
|
||||
|
||||
type PageListField = (typeof PageListField)[keyof typeof PageListField];
|
||||
|
||||
export const PageList: Block = {
|
||||
slug: "pageList",
|
||||
interfaceName: "PageList",
|
||||
fields: [
|
||||
{
|
||||
name: PageListField.numberOfItems,
|
||||
type: "number",
|
||||
defaultValue: 5,
|
||||
},
|
||||
{
|
||||
name: PageListField.filterByCategories,
|
||||
type: "relationship",
|
||||
relationTo: [Categories.slug],
|
||||
maxDepth: 0,
|
||||
hasMany: true,
|
||||
},
|
||||
{
|
||||
name: PageListField.filterByTags,
|
||||
type: "relationship",
|
||||
relationTo: [Tags.slug],
|
||||
hasMany: true,
|
||||
maxDepth: 0,
|
||||
},
|
||||
{
|
||||
name: PageListField.sortBy,
|
||||
type: "select",
|
||||
options: [
|
||||
PagesField.title,
|
||||
PagesField.createdAt,
|
||||
PagesField.updatedAt,
|
||||
`-${PagesField.title}`,
|
||||
`-${PagesField.createdAt}`,
|
||||
`-${PagesField.updatedAt}`,
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
15
apps/api/src/blocks/ReusableContent.ts
Normal file
15
apps/api/src/blocks/ReusableContent.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Block } from "payload/types";
|
||||
import Contents from "../collections/Contents";
|
||||
|
||||
export const ReusableContent: Block = {
|
||||
slug: "reusableContent",
|
||||
interfaceName: "ReusableContent",
|
||||
fields: [
|
||||
{
|
||||
name: "reference",
|
||||
type: "relationship",
|
||||
// maxDepth: 0,
|
||||
relationTo: [Contents.slug],
|
||||
},
|
||||
],
|
||||
};
|
||||
9
apps/api/src/blocks/SiteTitle.ts
Normal file
9
apps/api/src/blocks/SiteTitle.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Block } from "payload/types";
|
||||
|
||||
export const SiteTitle: Block = {
|
||||
slug: "siteTitle",
|
||||
interfaceName: "SiteTitle",
|
||||
fields: [
|
||||
{ name: "siteName", type: "text", required: true, admin: { width: "50%" } },
|
||||
],
|
||||
};
|
||||
37
apps/api/src/collections/Categories.ts
Normal file
37
apps/api/src/collections/Categories.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import type { CollectionConfig } from "payload/types";
|
||||
|
||||
const CategoriesField = {
|
||||
name: "name",
|
||||
slug: "slug",
|
||||
};
|
||||
|
||||
type CategoriesField = (typeof CategoriesField)[keyof typeof CategoriesField];
|
||||
|
||||
const Categories: CollectionConfig = {
|
||||
slug: "categories",
|
||||
admin: {
|
||||
useAsTitle: CategoriesField.name,
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: CategoriesField.name,
|
||||
type: "text",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: CategoriesField.slug,
|
||||
type: "text",
|
||||
required: true,
|
||||
unique: true,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
],
|
||||
timestamps: false,
|
||||
};
|
||||
|
||||
export default Categories;
|
||||
48
apps/api/src/collections/Contents.ts
Normal file
48
apps/api/src/collections/Contents.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { CollectionConfig } from "payload/types";
|
||||
import { Menu } from "../blocks/Menu";
|
||||
import { PageContent } from "../blocks/PageContent";
|
||||
import { PageList } from "../blocks/PageList";
|
||||
import { SiteTitle } from "../blocks/SiteTitle";
|
||||
|
||||
const ContentsField = {
|
||||
name: "name",
|
||||
slug: "slug",
|
||||
description: "description",
|
||||
};
|
||||
type ContentsField = (typeof ContentsField)[keyof typeof ContentsField];
|
||||
|
||||
const Contents: CollectionConfig = {
|
||||
slug: "contents",
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: ContentsField.name,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: ContentsField.name,
|
||||
type: "text",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: ContentsField.slug,
|
||||
type: "text",
|
||||
unique: true,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ContentsField.description,
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
name: "blocks",
|
||||
type: "blocks",
|
||||
blocks: [Menu, PageContent, PageList, SiteTitle],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default Contents;
|
||||
79
apps/api/src/collections/Layouts.ts
Normal file
79
apps/api/src/collections/Layouts.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import { CollectionConfig } from "payload/types";
|
||||
import { Menu } from "../blocks/Menu";
|
||||
import { PageContent } from "../blocks/PageContent";
|
||||
import { PageList } from "../blocks/PageList";
|
||||
import { ReusableContent } from "../blocks/ReusableContent";
|
||||
import { SiteTitle } from "../blocks/SiteTitle";
|
||||
|
||||
const LayoutsField = {
|
||||
name: "name",
|
||||
slug: "slug",
|
||||
description: "description",
|
||||
};
|
||||
type LayoutsField = (typeof LayoutsField)[keyof typeof LayoutsField];
|
||||
|
||||
const blocks = [ReusableContent];
|
||||
|
||||
const Layouts: CollectionConfig = {
|
||||
slug: "layouts",
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: LayoutsField.name,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: LayoutsField.name,
|
||||
type: "text",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: LayoutsField.slug,
|
||||
type: "text",
|
||||
unique: true,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: LayoutsField.description,
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
name: "header",
|
||||
type: "group",
|
||||
fields: [
|
||||
{
|
||||
name: "blocks",
|
||||
type: "blocks",
|
||||
blocks: [...blocks, Menu, SiteTitle],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "body",
|
||||
type: "group",
|
||||
fields: [
|
||||
{
|
||||
name: "blocks",
|
||||
type: "blocks",
|
||||
blocks: [...blocks, PageContent, PageList],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "footer",
|
||||
type: "group",
|
||||
fields: [
|
||||
{
|
||||
name: "blocks",
|
||||
type: "blocks",
|
||||
blocks: blocks,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default Layouts;
|
||||
29
apps/api/src/collections/Media.ts
Normal file
29
apps/api/src/collections/Media.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import type { CollectionConfig } from "payload/types";
|
||||
|
||||
const Media: CollectionConfig = {
|
||||
slug: "media",
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
upload: {
|
||||
disableLocalStorage: true,
|
||||
adminThumbnail: "thumbnail",
|
||||
imageSizes: [
|
||||
{
|
||||
height: 400,
|
||||
width: 400,
|
||||
crop: "center",
|
||||
name: "thumbnail",
|
||||
},
|
||||
{
|
||||
width: 900,
|
||||
height: 450,
|
||||
crop: "center",
|
||||
name: "sixteenByNineMedium",
|
||||
},
|
||||
],
|
||||
},
|
||||
fields: [],
|
||||
};
|
||||
|
||||
export default Media;
|
||||
113
apps/api/src/collections/Pages.ts
Normal file
113
apps/api/src/collections/Pages.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import type { CollectionConfig } from "payload/types";
|
||||
|
||||
export const PagesField = {
|
||||
title: "title",
|
||||
slug: "slug",
|
||||
author: "author",
|
||||
publishedDate: "publishedDate",
|
||||
categories: "categories",
|
||||
tags: "tags",
|
||||
content: "content",
|
||||
status: "status",
|
||||
layout: "layout",
|
||||
createdAt: "createdAt",
|
||||
updatedAt: "updatedAt",
|
||||
};
|
||||
|
||||
type PagesField = (typeof PagesField)[keyof typeof PagesField];
|
||||
|
||||
const PagesFieldStatus = {
|
||||
Draft: "Draft",
|
||||
Published: "Published",
|
||||
};
|
||||
|
||||
type PagesFieldStatus =
|
||||
(typeof PagesFieldStatus)[keyof typeof PagesFieldStatus];
|
||||
|
||||
const Pages: CollectionConfig = {
|
||||
slug: "pages",
|
||||
admin: {
|
||||
defaultColumns: [
|
||||
PagesField.title,
|
||||
PagesField.slug,
|
||||
PagesField.author,
|
||||
PagesField.categories,
|
||||
PagesField.tags,
|
||||
PagesField.status,
|
||||
],
|
||||
useAsTitle: PagesField.title,
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: PagesField.title,
|
||||
type: "text",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: PagesField.slug,
|
||||
type: "text",
|
||||
required: true,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: PagesField.author,
|
||||
type: "relationship",
|
||||
relationTo: "users",
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: PagesField.publishedDate,
|
||||
type: "date",
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: PagesField.categories,
|
||||
type: "relationship",
|
||||
relationTo: "categories",
|
||||
hasMany: true,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: PagesField.tags,
|
||||
type: "relationship",
|
||||
relationTo: "tags",
|
||||
hasMany: true,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: PagesField.status,
|
||||
type: "select",
|
||||
options: Object.entries(PagesFieldStatus).map((e) => {
|
||||
return { label: e[0], value: e[1] };
|
||||
}),
|
||||
defaultValue: PagesFieldStatus.Draft,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: PagesField.layout,
|
||||
type: "relationship",
|
||||
relationTo: "layouts",
|
||||
},
|
||||
{
|
||||
name: PagesField.content,
|
||||
type: "richText",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default Pages;
|
||||
37
apps/api/src/collections/Tags.ts
Normal file
37
apps/api/src/collections/Tags.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import type { CollectionConfig } from "payload/types";
|
||||
|
||||
const TagsField = {
|
||||
name: "name",
|
||||
slug: "slug",
|
||||
};
|
||||
|
||||
type TagsField = (typeof TagsField)[keyof typeof TagsField];
|
||||
|
||||
const Tags: CollectionConfig = {
|
||||
slug: "tags",
|
||||
admin: {
|
||||
useAsTitle: TagsField.name,
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: TagsField.name,
|
||||
type: "text",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: TagsField.slug,
|
||||
type: "text",
|
||||
required: true,
|
||||
unique: true,
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
},
|
||||
},
|
||||
],
|
||||
timestamps: false,
|
||||
};
|
||||
|
||||
export default Tags;
|
||||
18
apps/api/src/collections/Users.ts
Normal file
18
apps/api/src/collections/Users.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import type { CollectionConfig } from "payload/types";
|
||||
|
||||
const Users: CollectionConfig = {
|
||||
slug: "users",
|
||||
auth: true,
|
||||
admin: {
|
||||
useAsTitle: "email",
|
||||
},
|
||||
fields: [
|
||||
// Email added by default
|
||||
{
|
||||
name: "name",
|
||||
type: "text",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default Users;
|
||||
15
apps/api/src/fields/enableField.ts
Normal file
15
apps/api/src/fields/enableField.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { SelectField } from "payload/types";
|
||||
|
||||
function enableField(fieldOverrides?: Partial<SelectField>): SelectField {
|
||||
return {
|
||||
label: "Enable",
|
||||
name: "enable",
|
||||
type: "select",
|
||||
options: ["Yes", "No"],
|
||||
defaultValue: "Yes",
|
||||
required: true,
|
||||
...fieldOverrides,
|
||||
};
|
||||
}
|
||||
|
||||
export default enableField;
|
||||
100
apps/api/src/fields/linkField.ts
Normal file
100
apps/api/src/fields/linkField.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import payload from "payload";
|
||||
import { GroupField } from "payload/types";
|
||||
|
||||
function linkField(fieldOverrides?: Partial<GroupField>): GroupField {
|
||||
return {
|
||||
name: "link",
|
||||
type: "group",
|
||||
interfaceName: "Link",
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
fields: [
|
||||
{
|
||||
name: "type",
|
||||
type: "radio",
|
||||
options: [
|
||||
{
|
||||
label: "Internal link",
|
||||
value: "reference",
|
||||
},
|
||||
{
|
||||
label: "Custom URL",
|
||||
value: "custom",
|
||||
},
|
||||
],
|
||||
defaultValue: "reference",
|
||||
admin: {
|
||||
layout: "horizontal",
|
||||
width: "50%",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "newTab",
|
||||
label: "Open in new tab",
|
||||
type: "checkbox",
|
||||
admin: {
|
||||
width: "50%",
|
||||
style: {
|
||||
alignSelf: "flex-end",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
label: "Document to link to",
|
||||
type: "relationship",
|
||||
relationTo: ["pages"],
|
||||
required: true,
|
||||
maxDepth: 0,
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.type === "reference",
|
||||
width: "50%",
|
||||
},
|
||||
hooks: {
|
||||
afterRead: [
|
||||
async ({ value, siblingData }) => {
|
||||
if (value && siblingData.type === "reference") {
|
||||
const id = value.value;
|
||||
const pages = await payload.find({
|
||||
collection: "pages",
|
||||
where: {
|
||||
id: { equals: id },
|
||||
},
|
||||
depth: 0,
|
||||
});
|
||||
|
||||
if (pages.docs[0]?.slug)
|
||||
if (pages.docs[0]) siblingData.url = pages.docs[0].slug;
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "url",
|
||||
label: "Custom URL",
|
||||
type: "text",
|
||||
required: true,
|
||||
admin: {
|
||||
condition: (_, siblingData) => siblingData?.type === "custom",
|
||||
width: "50%",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "label",
|
||||
label: "Label",
|
||||
type: "text",
|
||||
required: true,
|
||||
admin: {
|
||||
width: "50%",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...fieldOverrides,
|
||||
};
|
||||
}
|
||||
|
||||
export default linkField;
|
||||
59
apps/api/src/payload.config.ts
Normal file
59
apps/api/src/payload.config.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { cloudStorage } from "@payloadcms/plugin-cloud-storage";
|
||||
import { s3Adapter } from "@payloadcms/plugin-cloud-storage/s3";
|
||||
import seo from "@payloadcms/plugin-seo";
|
||||
import { GenerateTitle } from "@payloadcms/plugin-seo/dist/types";
|
||||
import path from "path";
|
||||
import { buildConfig } from "payload/config";
|
||||
import Categories from "./collections/Categories";
|
||||
import Contents from "./collections/Contents";
|
||||
import Layouts from "./collections/Layouts";
|
||||
import Media from "./collections/Media";
|
||||
import Pages from "./collections/Pages";
|
||||
import Tags from "./collections/Tags";
|
||||
import Users from "./collections/Users";
|
||||
const generateTitle: GenerateTitle = ({ slug, doc }) => {
|
||||
let title = "TurboPress";
|
||||
if (slug == "pages") {
|
||||
const page = doc as any;
|
||||
return (title = `TurboPress - ${page?.title?.value}`);
|
||||
}
|
||||
return title;
|
||||
};
|
||||
|
||||
const adapter = s3Adapter({
|
||||
config: {
|
||||
credentials: {
|
||||
accessKeyId: process.env.S3_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
|
||||
},
|
||||
region: process.env.S3_REGION,
|
||||
endpoint: process.env.S3_ENDPOINT,
|
||||
},
|
||||
bucket: process.env.S3_BUCKET,
|
||||
});
|
||||
|
||||
export default buildConfig({
|
||||
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL ?? "http://localhost:3000",
|
||||
admin: {
|
||||
user: Users.slug,
|
||||
},
|
||||
collections: [Categories, Contents, Layouts, Media, Pages, Tags, Users],
|
||||
typescript: {
|
||||
outputFile: path.join(__dirname, "../types", "payload.ts"),
|
||||
},
|
||||
plugins: [
|
||||
seo({
|
||||
collections: ["pages"],
|
||||
uploadsCollection: "media",
|
||||
generateTitle: generateTitle,
|
||||
}),
|
||||
cloudStorage({
|
||||
collections: {
|
||||
media: {
|
||||
adapter: adapter,
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
cors: "*",
|
||||
});
|
||||
30
apps/api/src/server.ts
Normal file
30
apps/api/src/server.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import express from "express";
|
||||
import payload from "payload";
|
||||
|
||||
const app = express();
|
||||
|
||||
// Redirect root to Admin panel
|
||||
app.get("/", (_, res) => {
|
||||
res.redirect("/admin");
|
||||
});
|
||||
|
||||
const start = async () => {
|
||||
// Initialize Payload
|
||||
await payload.init({
|
||||
secret: process.env.PAYLOAD_SECRET,
|
||||
mongoURL: process.env.MONGODB_URI,
|
||||
express: app,
|
||||
onInit: async () => {
|
||||
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`);
|
||||
},
|
||||
mongoOptions: {
|
||||
dbName: process.env.DB_NAME,
|
||||
},
|
||||
});
|
||||
|
||||
// Add your own express routes here
|
||||
|
||||
app.listen(process.env.PAYLOAD_PORT ?? 3000);
|
||||
};
|
||||
|
||||
start();
|
||||
Reference in New Issue
Block a user