{(media || staticImage) && (
diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx
index 7886720..a50a0fb 100644
--- a/src/components/Logo/Logo.tsx
+++ b/src/components/Logo/Logo.tsx
@@ -37,3 +37,5 @@ export const Logo = (props: Props) => {
/>*/
)
}
+
+export default Logo;
\ No newline at end of file
diff --git a/src/components/Logo/LogoLarge.tsx b/src/components/Logo/LogoLarge.tsx
new file mode 100644
index 0000000..5d3caaf
--- /dev/null
+++ b/src/components/Logo/LogoLarge.tsx
@@ -0,0 +1,41 @@
+import clsx from 'clsx'
+import React from 'react'
+
+interface Props {
+ className?: string
+ loading?: 'lazy' | 'eager'
+ priority?: 'auto' | 'high' | 'low'
+}
+
+export const LogoLarge = (props: Props) => {
+ const { loading: loadingFromProps, priority: priorityFromProps, className } = props
+
+ const loading = loadingFromProps || 'lazy'
+ const priority = priorityFromProps || 'low'
+
+ return (
+ /* eslint-disable @next/next/no-img-element */
+

+ /*

*/
+ )
+}
+
+export default LogoLarge;
\ No newline at end of file
diff --git a/src/fields/defaultLexical.ts b/src/fields/defaultLexical.ts
index 2468d6e..507969c 100644
--- a/src/fields/defaultLexical.ts
+++ b/src/fields/defaultLexical.ts
@@ -1,4 +1,4 @@
-import type { TextFieldSingleValidation } from 'payload'
+import type { TextFieldSingleValidation } from "payload";
import {
BoldFeature,
ItalicFeature,
@@ -6,42 +6,47 @@ import {
ParagraphFeature,
lexicalEditor,
UnderlineFeature,
- type LinkFields,
-} from '@payloadcms/richtext-lexical'
+ type LinkFields, HeadingFeature, FixedToolbarFeature, UnorderedListFeature, OrderedListFeature, AlignFeature,
+} from "@payloadcms/richtext-lexical";
export const defaultLexical = lexicalEditor({
features: [
+ FixedToolbarFeature(),
ParagraphFeature(),
UnderlineFeature(),
BoldFeature(),
ItalicFeature(),
+ AlignFeature(),
+ UnorderedListFeature(),
+ OrderedListFeature(),
+ HeadingFeature({ enabledHeadingSizes: ["h2", "h3", "h4"] }),
LinkFeature({
- enabledCollections: ['pages', 'posts'],
+ enabledCollections: ["pages", "posts"],
fields: ({ defaultFields }) => {
const defaultFieldsWithoutUrl = defaultFields.filter((field) => {
- if ('name' in field && field.name === 'url') return false
- return true
- })
+ if ("name" in field && field.name === "url") return false;
+ return true;
+ });
return [
...defaultFieldsWithoutUrl,
{
- name: 'url',
- type: 'text',
+ name: "url",
+ type: "text",
admin: {
- condition: (_data, siblingData) => siblingData?.linkType !== 'internal',
+ condition: (_data, siblingData) => siblingData?.linkType !== "internal",
},
- label: ({ t }) => t('fields:enterURL'),
+ label: ({ t }) => t("fields:enterURL"),
required: true,
validate: ((value, options) => {
- if ((options?.siblingData as LinkFields)?.linkType === 'internal') {
- return true // no validation needed, as no url should exist for internal links
+ if ((options?.siblingData as LinkFields)?.linkType === "internal") {
+ return true; // no validation needed, as no url should exist for internal links
}
- return value ? true : 'URL is required'
+ return value ? true : "URL is required";
}) as TextFieldSingleValidation,
},
- ]
+ ];
},
}),
],
-})
+});
diff --git a/src/payload.config.ts b/src/payload.config.ts
index 738308b..01dbd83 100644
--- a/src/payload.config.ts
+++ b/src/payload.config.ts
@@ -1,32 +1,37 @@
-import { postgresAdapter } from '@payloadcms/db-postgres'
-import sharp from 'sharp'
-import path from 'path'
-import { buildConfig, PayloadRequest } from 'payload'
-import { fileURLToPath } from 'url'
+import { postgresAdapter } from "@payloadcms/db-postgres";
+import sharp from "sharp";
+import path from "path";
+import { buildConfig, PayloadRequest } from "payload";
+import { fileURLToPath } from "url";
-import { Categories } from './collections/Categories'
-import { Media } from './collections/Media'
-import { Pages } from './collections/Pages'
-import { Posts } from './collections/Posts'
-import { Users } from './collections/Users'
-import { Footer } from './Footer/config'
-import { Header } from './Header/config'
-import { plugins } from './plugins'
-import { defaultLexical } from '@/fields/defaultLexical'
-import { getServerSideURL } from './utilities/getURL'
+import { Categories } from "./collections/Categories";
+import { Media } from "./collections/Media";
+import { Pages } from "./collections/Pages";
+import { Posts } from "./collections/Posts";
+import { Users } from "./collections/Users";
+import { Footer } from "./Footer/config";
+import { Header } from "./Header/config";
+import { plugins } from "./plugins";
+import { defaultLexical } from "@/fields/defaultLexical";
+import { getServerSideURL } from "./utilities/getURL";
+import { nodemailerAdapter } from "@payloadcms/email-nodemailer";
-const filename = fileURLToPath(import.meta.url)
-const dirname = path.dirname(filename)
+const filename = fileURLToPath(import.meta.url);
+const dirname = path.dirname(filename);
export default buildConfig({
admin: {
components: {
// The `BeforeLogin` component renders a message that you see while logging into your admin panel.
// Feel free to delete this at any time. Simply remove the line below.
- beforeLogin: ['@/components/BeforeLogin'],
+ beforeLogin: ["@/components/BeforeLogin"],
// The `BeforeDashboard` component renders the 'welcome' block that you see after logging into your admin panel.
// Feel free to delete this at any time. Simply remove the line below.
- beforeDashboard: ['@/components/BeforeDashboard'],
+ beforeDashboard: ["@/components/BeforeDashboard"],
+ graphics: {
+ Icon: "@/components/Logo/Logo.tsx",
+ Logo: "@/components/Logo/LogoLarge.tsx",
+ },
},
importMap: {
baseDir: path.resolve(dirname),
@@ -35,20 +40,20 @@ export default buildConfig({
livePreview: {
breakpoints: [
{
- label: 'Mobile',
- name: 'mobile',
+ label: "Mobile",
+ name: "mobile",
width: 375,
height: 667,
},
{
- label: 'Tablet',
- name: 'tablet',
+ label: "Tablet",
+ name: "tablet",
width: 768,
height: 1024,
},
{
- label: 'Desktop',
- name: 'desktop',
+ label: "Desktop",
+ name: "desktop",
width: 1440,
height: 900,
},
@@ -59,9 +64,22 @@ export default buildConfig({
editor: defaultLexical,
db: postgresAdapter({
pool: {
- connectionString: process.env.DATABASE_URL || '',
+ connectionString: process.env.DATABASE_URL || "",
},
}),
+ email: nodemailerAdapter({
+ defaultFromAddress: 'no-reply@onyxsimple.com',
+ defaultFromName: 'ONYXSimple',
+ transportOptions: {
+ service: process.env.SMTP_SERVICE,
+ host: process.env.SMTP_HOST,
+ port: Number(process.env.SMTP_PORT) || 587,
+ auth: {
+ user: process.env.SMTP_USER,
+ pass: process.env.SMTP_PASS,
+ }
+ }
+ }),
collections: [Pages, Posts, Media, Categories, Users],
cors: [getServerSideURL()].filter(Boolean),
globals: [Header, Footer],
@@ -69,24 +87,24 @@ export default buildConfig({
secret: process.env.PAYLOAD_SECRET,
sharp,
typescript: {
- outputFile: path.resolve(dirname, 'payload-types.ts'),
+ outputFile: path.resolve(dirname, "payload-types.ts"),
},
jobs: {
access: {
run: ({ req }: { req: PayloadRequest }): boolean => {
// Allow logged in users to execute this endpoint (default)
- if (req.user) return true
+ if (req.user) return true;
- const secret = process.env.CRON_SECRET
- if (!secret) return false
+ const secret = process.env.CRON_SECRET;
+ if (!secret) return false;
// If there is no logged in user, then check
// for the Vercel Cron secret to be present as an
// Authorization header:
- const authHeader = req.headers.get('authorization')
- return authHeader === `Bearer ${secret}`
+ const authHeader = req.headers.get("authorization");
+ return authHeader === `Bearer ${secret}`;
},
},
tasks: [],
},
-})
+});
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index e68c728..8c15370 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -1,45 +1,45 @@
-import { formBuilderPlugin } from '@payloadcms/plugin-form-builder'
-import { nestedDocsPlugin } from '@payloadcms/plugin-nested-docs'
-import { redirectsPlugin } from '@payloadcms/plugin-redirects'
-import { seoPlugin } from '@payloadcms/plugin-seo'
-import { searchPlugin } from '@payloadcms/plugin-search'
-import { Plugin } from 'payload'
-import { revalidateRedirects } from '@/hooks/revalidateRedirects'
-import { GenerateTitle, GenerateURL } from '@payloadcms/plugin-seo/types'
-import { FixedToolbarFeature, HeadingFeature, lexicalEditor } from '@payloadcms/richtext-lexical'
-import { searchFields } from '@/search/fieldOverrides'
-import { beforeSyncWithSearch } from '@/search/beforeSync'
+import { formBuilderPlugin } from "@payloadcms/plugin-form-builder";
+import { nestedDocsPlugin } from "@payloadcms/plugin-nested-docs";
+import { redirectsPlugin } from "@payloadcms/plugin-redirects";
+import { seoPlugin } from "@payloadcms/plugin-seo";
+import { searchPlugin } from "@payloadcms/plugin-search";
+import { Plugin } from "payload";
+import { revalidateRedirects } from "@/hooks/revalidateRedirects";
+import { GenerateTitle, GenerateURL } from "@payloadcms/plugin-seo/types";
+import { FixedToolbarFeature, HeadingFeature, lexicalEditor } from "@payloadcms/richtext-lexical";
+import { searchFields } from "@/search/fieldOverrides";
+import { beforeSyncWithSearch } from "@/search/beforeSync";
-import { Page, Post } from '@/payload-types'
-import { getServerSideURL } from '@/utilities/getURL'
+import { Page, Post } from "@/payload-types";
+import { getServerSideURL } from "@/utilities/getURL";
const generateTitle: GenerateTitle
= ({ doc }) => {
- return doc?.title ? `${doc.title} | ONYXSimple` : 'ONYXSimple'
-}
+ return doc?.title ? `${doc.title} | ONYXSimple` : "ONYXSimple";
+};
const generateURL: GenerateURL = ({ doc }) => {
- const url = getServerSideURL()
+ const url = getServerSideURL();
- return doc?.slug ? `${url}/${doc.slug}` : url
-}
+ return doc?.slug ? `${url}/${doc.slug}` : url;
+};
export const plugins: Plugin[] = [
redirectsPlugin({
- collections: ['pages', 'posts'],
+ collections: ["pages", "posts"],
overrides: {
// @ts-expect-error - This is a valid override, mapped fields don't resolve to the same type
fields: ({ defaultFields }) => {
return defaultFields.map((field) => {
- if ('name' in field && field.name === 'from') {
+ if ("name" in field && field.name === "from") {
return {
...field,
admin: {
- description: 'You will need to rebuild the website when changing this field.',
+ description: "You will need to rebuild the website when changing this field.",
},
- }
+ };
}
- return field
- })
+ return field;
+ });
},
hooks: {
afterChange: [revalidateRedirects],
@@ -47,8 +47,8 @@ export const plugins: Plugin[] = [
},
}),
nestedDocsPlugin({
- collections: ['categories'],
- generateURL: (docs) => docs.reduce((url, doc) => `${url}/${doc.slug}`, ''),
+ collections: ["categories"],
+ generateURL: (docs) => docs.reduce((url, doc) => `${url}/${doc.slug}`, ""),
}),
seoPlugin({
generateTitle,
@@ -61,7 +61,7 @@ export const plugins: Plugin[] = [
formOverrides: {
fields: ({ defaultFields }) => {
return defaultFields.map((field) => {
- if ('name' in field && field.name === 'confirmationMessage') {
+ if ("name" in field && field.name === "confirmationMessage") {
return {
...field,
editor: lexicalEditor({
@@ -69,24 +69,24 @@ export const plugins: Plugin[] = [
return [
...rootFeatures,
FixedToolbarFeature(),
- HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
- ]
+ HeadingFeature({ enabledHeadingSizes: ["h1", "h2", "h3", "h4"] }),
+ ];
},
}),
- }
+ };
}
- return field
- })
+ return field;
+ });
},
},
}),
searchPlugin({
- collections: ['posts'],
+ collections: ["posts"],
beforeSync: beforeSyncWithSearch,
searchOverrides: {
fields: ({ defaultFields }) => {
- return [...defaultFields, ...searchFields]
+ return [...defaultFields, ...searchFields];
},
},
}),
-]
+];