diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 1d7ac85..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] -} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 572ee15..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Next.js: debug full stack", - "type": "node", - "request": "launch", - "program": "${workspaceFolder}/node_modules/next/dist/bin/next", - "runtimeArgs": ["--inspect"], - "skipFiles": ["/**"], - "serverReadyAction": { - "action": "debugWithChrome", - "killOnServerStop": true, - "pattern": "- Local:.+(https?://.+)", - "uriFormat": "%s", - "webRoot": "${workspaceFolder}" - }, - "cwd": "${workspaceFolder}" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 5918b30..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "npm.packageManager": "pnpm", - "editor.defaultFormatter": "esbenp.prettier-vscode", - "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } - }, - "[typescriptreact]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } - }, - "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } - }, - "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true - }, - "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true - }, - "editor.formatOnSaveMode": "file", - "typescript.tsdk": "node_modules/typescript/lib", - "[javascript][typescript][typescriptreact]": { - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } - } -} diff --git a/src/app/(frontend)/page.tsx b/src/app/(frontend)/page.tsx index d0e8d64..bebe23a 100644 --- a/src/app/(frontend)/page.tsx +++ b/src/app/(frontend)/page.tsx @@ -1,11 +1,13 @@ import { headers as getHeaders } from 'next/headers.js' import Image from 'next/image' import { getPayload } from 'payload' +import type { Payload } from 'payload' import React from 'react' import { fileURLToPath } from 'url' import config from '@/payload.config' import './styles.css' +import { RichText } from '@payloadcms/richtext-lexical/react' export default async function HomePage() { const headers = await getHeaders() @@ -15,9 +17,26 @@ export default async function HomePage() { const fileURL = `vscode://file/${fileURLToPath(import.meta.url)}` + const homePage = await payload.find({ + collection: 'pages', + where: { + title: { + equals: 'Home', + }, + }, + }) + + const page = homePage.docs?.[0] + + console.log(page) + return (
-
+
+

{page.title}

+ {page.richText && ( + + )} true, + }, + admin: { + defaultColumns: ['title', 'slug', 'updatedAt',], + }, + fields: [ + { + name: 'title', + type: 'text', + required: true, + }, + { + name: 'richText', + type: 'richText' + } + ], +} diff --git a/src/collections/Users.ts b/src/collections/Users.ts index c683d0e..2619093 100644 --- a/src/collections/Users.ts +++ b/src/collections/Users.ts @@ -2,6 +2,17 @@ import type { CollectionConfig } from 'payload' export const Users: CollectionConfig = { slug: 'users', + access: { + create: ({ req: { user } }) => { + return Boolean(user?.role === "superAdmin") + }, + update: ({ req: { user } }) => { + return Boolean(user?.role === "superAdmin" || user?.role === "admin") + }, + delete: ({ req: { user }, data }) => { + return Boolean(user?.role === "superAdmin") + }, + }, admin: { useAsTitle: 'email', }, @@ -9,5 +20,16 @@ export const Users: CollectionConfig = { fields: [ // Email added by default // Add more fields as needed + { + name: 'role', + type: 'select', + options: [ + { label: 'Super Admin', value: 'superAdmin' }, + { label: 'Admin', value: 'admin' }, + { label: 'User', value: 'user' }, + ], + required: true, + defaultValue: 'user' + } ], } diff --git a/src/payload-types.ts b/src/payload-types.ts index 72b7ce4..825fbb8 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -69,6 +69,7 @@ export interface Config { collections: { users: User; media: Media; + pages: Page; 'payload-locked-documents': PayloadLockedDocument; 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; @@ -77,6 +78,7 @@ export interface Config { collectionsSelect: { users: UsersSelect | UsersSelect; media: MediaSelect | MediaSelect; + pages: PagesSelect | PagesSelect; 'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect; 'payload-preferences': PayloadPreferencesSelect | PayloadPreferencesSelect; 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; @@ -119,6 +121,7 @@ export interface UserAuthOperations { */ export interface User { id: number; + role: 'superAdmin' | 'admin' | 'user'; updatedAt: string; createdAt: string; email: string; @@ -156,6 +159,31 @@ export interface Media { focalX?: number | null; focalY?: number | null; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "pages". + */ +export interface Page { + id: number; + title: string; + richText?: { + root: { + type: string; + children: { + type: any; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + updatedAt: string; + createdAt: string; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-locked-documents". @@ -170,6 +198,10 @@ export interface PayloadLockedDocument { | ({ relationTo: 'media'; value: number | Media; + } | null) + | ({ + relationTo: 'pages'; + value: number | Page; } | null); globalSlug?: string | null; user: { @@ -218,6 +250,7 @@ export interface PayloadMigration { * via the `definition` "users_select". */ export interface UsersSelect { + role?: T; updatedAt?: T; createdAt?: T; email?: T; @@ -253,6 +286,16 @@ export interface MediaSelect { focalX?: T; focalY?: T; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "pages_select". + */ +export interface PagesSelect { + title?: T; + richText?: T; + updatedAt?: T; + createdAt?: T; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-locked-documents_select". diff --git a/src/payload.config.ts b/src/payload.config.ts index 5f2c20c..7769a01 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -1,7 +1,7 @@ // storage-adapter-import-placeholder import { postgresAdapter } from '@payloadcms/db-postgres' import { payloadCloudPlugin } from '@payloadcms/payload-cloud' -import { lexicalEditor } from '@payloadcms/richtext-lexical' +import { FixedToolbarFeature, HorizontalRuleFeature, lexicalEditor, UploadFeature } from '@payloadcms/richtext-lexical' import path from 'path' import { buildConfig } from 'payload' import { fileURLToPath } from 'url' @@ -9,6 +9,7 @@ import sharp from 'sharp' import { Users } from './collections/Users' import { Media } from './collections/Media' +import { Page } from './collections/Page' const filename = fileURLToPath(import.meta.url) const dirname = path.dirname(filename) @@ -20,8 +21,34 @@ export default buildConfig({ baseDir: path.resolve(dirname), }, }, - collections: [Users, Media], - editor: lexicalEditor(), + collections: [Users, Media, Page], + editor: lexicalEditor({ + features: ({ defaultFeatures, rootFeatures }) => [ + ...defaultFeatures, + FixedToolbarFeature({ + applyToFocusedEditor: true + }), + HorizontalRuleFeature(), + UploadFeature({ + collections: { + uploads: { + fields: [ + { + name: 'caption', + type: 'text', + label: 'Caption', + }, + { + name: 'alt', + type: 'text', + label: 'Alt Text', + }, + ] + } + } + }) + ] + }), secret: process.env.PAYLOAD_SECRET || '', typescript: { outputFile: path.resolve(dirname, 'payload-types.ts'),