Jelajahi Sumber

feat: added collections

collections added:
- Posts: for news/blog data
- Clients: for clients data
- Careers: for careers/recruitment information
- Authors: used as a 'writer' subject for news-type posts
- Media: for media
YusufSyam 3 minggu lalu
induk
melakukan
74b13247e0

+ 37 - 0
src/collections/Authors.ts

@@ -0,0 +1,37 @@
+import type { CollectionConfig } from 'payload'
+
+export const Authors: CollectionConfig = {
+  slug: 'authors',
+  admin: {
+    useAsTitle: 'name',
+    defaultColumns: ['name', 'socialMediaLink'],
+  },
+  fields: [
+    {
+      name: 'name',
+      label: 'Author',
+      type: 'text',
+      required: true,
+    },
+    {
+      name: 'image',
+      label: 'Profile Image',
+      type: 'upload',
+      relationTo: 'media',
+      required: true,
+    },
+    {
+      name: 'description',
+      label: 'Description',
+      type: 'textarea',
+      required: true,
+    },
+    {
+      name: 'socialMediaLink',
+      label: 'Social Media URL',
+      type: 'text',
+    },
+  ],
+}
+
+

+ 96 - 0
src/collections/Careers.ts

@@ -0,0 +1,96 @@
+import type { CollectionConfig } from 'payload'
+import { slugField } from 'payload'
+
+export const Careers: CollectionConfig = {
+  slug: 'careers',
+  admin: {
+    useAsTitle: 'title',
+    defaultColumns: ['title', 'jobCategory', 'isUrgentlyHiring'],
+  },
+  fields: [
+    {
+      name: 'title',
+      label: 'Job Title',
+      type: 'text',
+      required: true,
+    },
+    slugField({
+      name: 'slug',
+      fieldToUse: 'title',
+      localized: false,
+      unique: true,
+    }),
+    {
+      name: 'image',
+      label: 'Image',
+      type: 'upload',
+      relationTo: 'media',
+    },
+    {
+      name: 'requirements',
+      label: 'Requirements',
+      type: 'array',
+      fields: [
+        {
+          name: 'item',
+          label: 'Requirement',
+          type: 'text',
+          required: true,
+        },
+      ],
+    },
+    {
+      name: 'mainJobDescription',
+      label: 'Main Job Description',
+      type: 'array',
+      fields: [
+        {
+          name: 'item',
+          label: 'Job Description Item',
+          type: 'text',
+          required: true,
+        },
+      ],
+    },
+    {
+      name: 'isUrgentlyHiring',
+      label: 'Urgently Hiring',
+      type: 'checkbox',
+      defaultValue: false,
+    },
+    {
+      name: 'jobCategory',
+      label: 'Job Category',
+      type: 'select',
+      required: true,
+      options: [
+        {
+          label: 'Technology & Engineering',
+          value: 'Technology & Engineering',
+        },
+        {
+          label: 'Marketing, Sales & Communication',
+          value: 'Marketing, Sales & Communication',
+        },
+        {
+          label: 'Finance & Accounting',
+          value: 'Finance & Accounting',
+        },
+        {
+          label: 'Human Resources & General Affairs',
+          value: 'Human Resources & General Affairs',
+        },
+        {
+          label: 'Creative & Design',
+          value: 'Creative & Design',
+        },
+        {
+          label: 'Operations & Customer Success',
+          value: 'Operations & Customer Success',
+        },
+      ],
+    },
+  ],
+}
+
+

+ 57 - 0
src/collections/Clients.ts

@@ -0,0 +1,57 @@
+import type { CollectionConfig } from 'payload'
+
+export const Clients: CollectionConfig = {
+  slug: 'clients',
+  admin: {
+    useAsTitle: 'name',
+    defaultColumns: ['name', 'category', 'href'],
+  },
+  fields: [
+    {
+      name: 'name',
+      label: 'Client Name',
+      type: 'text',
+      required: true,
+    },
+    {
+      name: 'href',
+      label: 'Website URL',
+      type: 'text',
+      required: true,
+    },
+    {
+      name: 'logo',
+      label: 'Logo',
+      type: 'upload',
+      relationTo: 'media',
+      required: true,
+    },
+    {
+      name: 'category',
+      label: 'Category',
+      type: 'select',
+      required: true,
+      options: [
+        {
+          label: 'Banking & Finance',
+          value: 'Banking & Finance',
+        },
+        {
+          label: 'Enterprise & Industrial',
+          value: 'Enterprise & Industrial',
+        },
+        {
+          label: 'Government',
+          value: 'Government',
+        },
+      ],
+    },
+    {
+      name: 'imageHeight',
+      label: 'Image Height',
+      type: 'number',
+    },
+  ],
+}
+
+

+ 81 - 0
src/collections/Posts.ts

@@ -0,0 +1,81 @@
+import type { CollectionConfig } from 'payload'
+import { slugField } from 'payload'
+
+export const Posts: CollectionConfig = {
+  slug: 'posts',
+  admin: {
+    useAsTitle: 'title',
+    defaultColumns: ['title', 'type', 'category', 'publishedDate'],
+  },
+  fields: [
+    {
+      name: 'type',
+      label: 'Type',
+      type: 'select',
+      required: true,
+      defaultValue: 'blog',
+      options: [
+        {
+          label: 'News',
+          value: 'news',
+        },
+        {
+          label: 'Blog',
+          value: 'blog',
+        },
+      ],
+    },
+    {
+      name: 'category',
+      label: 'Category',
+      type: 'text',
+      required: true,
+    },
+    {
+      name: 'title',
+      label: 'Title',
+      type: 'text',
+      required: true,
+    },
+    slugField({
+      name: 'slug',
+      fieldToUse: 'title',
+      localized: false,
+      unique: true,
+    }),
+    {
+      name: 'image',
+      label: 'Featured Image',
+      type: 'upload',
+      relationTo: 'media',
+      required: true,
+    },
+    {
+      name: 'excerpt',
+      label: 'Excerpt',
+      type: 'textarea',
+      required: true,
+    },
+    {
+      name: 'publishedDate',
+      label: 'Published Date',
+      type: 'date',
+      required: true,
+    },
+    {
+      name: 'content',
+      label: 'Content',
+      type: 'richText',
+      required: true,
+    },
+    {
+      name: 'author',
+      label: 'Author',
+      type: 'relationship',
+      relationTo: 'authors',
+      required: true,
+    },
+  ],
+}
+
+

+ 203 - 11
src/payload-types.ts

@@ -69,6 +69,10 @@ export interface Config {
   collections: {
     users: User;
     media: Media;
+    authors: Author;
+    posts: Post;
+    clients: Client;
+    careers: Career;
     'payload-kv': PayloadKv;
     'payload-locked-documents': PayloadLockedDocument;
     'payload-preferences': PayloadPreference;
@@ -78,13 +82,17 @@ export interface Config {
   collectionsSelect: {
     users: UsersSelect<false> | UsersSelect<true>;
     media: MediaSelect<false> | MediaSelect<true>;
+    authors: AuthorsSelect<false> | AuthorsSelect<true>;
+    posts: PostsSelect<false> | PostsSelect<true>;
+    clients: ClientsSelect<false> | ClientsSelect<true>;
+    careers: CareersSelect<false> | CareersSelect<true>;
     'payload-kv': PayloadKvSelect<false> | PayloadKvSelect<true>;
     'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
     'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
     'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
   };
   db: {
-    defaultIDType: string;
+    defaultIDType: number;
   };
   fallbackLocale: null;
   globals: {};
@@ -121,7 +129,7 @@ export interface UserAuthOperations {
  * via the `definition` "users".
  */
 export interface User {
-  id: string;
+  id: number;
   updatedAt: string;
   createdAt: string;
   email: string;
@@ -145,7 +153,7 @@ export interface User {
  * via the `definition` "media".
  */
 export interface Media {
-  id: string;
+  id: number;
   alt: string;
   updatedAt: string;
   createdAt: string;
@@ -159,12 +167,111 @@ export interface Media {
   focalX?: number | null;
   focalY?: number | null;
 }
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "authors".
+ */
+export interface Author {
+  id: number;
+  name: string;
+  image: number | Media;
+  description: string;
+  socialMediaLink?: string | null;
+  updatedAt: string;
+  createdAt: string;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "posts".
+ */
+export interface Post {
+  id: number;
+  type: 'news' | 'blog';
+  category: string;
+  title: string;
+  /**
+   * When enabled, the slug will auto-generate from the title field on save and autosave.
+   */
+  generateSlug?: boolean | null;
+  slug: string;
+  image: number | Media;
+  excerpt: string;
+  publishedDate: string;
+  content: {
+    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;
+  };
+  author: number | Author;
+  updatedAt: string;
+  createdAt: string;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "clients".
+ */
+export interface Client {
+  id: number;
+  name: string;
+  href: string;
+  logo: number | Media;
+  category: 'Banking & Finance' | 'Enterprise & Industrial' | 'Government';
+  imageHeight?: number | null;
+  updatedAt: string;
+  createdAt: string;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "careers".
+ */
+export interface Career {
+  id: number;
+  title: string;
+  /**
+   * When enabled, the slug will auto-generate from the title field on save and autosave.
+   */
+  generateSlug?: boolean | null;
+  slug: string;
+  image?: (number | null) | Media;
+  requirements?:
+    | {
+        item: string;
+        id?: string | null;
+      }[]
+    | null;
+  mainJobDescription?:
+    | {
+        item: string;
+        id?: string | null;
+      }[]
+    | null;
+  isUrgentlyHiring?: boolean | null;
+  jobCategory:
+    | 'Technology & Engineering'
+    | 'Marketing, Sales & Communication'
+    | 'Finance & Accounting'
+    | 'Human Resources & General Affairs'
+    | 'Creative & Design'
+    | 'Operations & Customer Success';
+  updatedAt: string;
+  createdAt: string;
+}
 /**
  * This interface was referenced by `Config`'s JSON-Schema
  * via the `definition` "payload-kv".
  */
 export interface PayloadKv {
-  id: string;
+  id: number;
   key: string;
   data:
     | {
@@ -181,20 +288,36 @@ export interface PayloadKv {
  * via the `definition` "payload-locked-documents".
  */
 export interface PayloadLockedDocument {
-  id: string;
+  id: number;
   document?:
     | ({
         relationTo: 'users';
-        value: string | User;
+        value: number | User;
       } | null)
     | ({
         relationTo: 'media';
-        value: string | Media;
+        value: number | Media;
+      } | null)
+    | ({
+        relationTo: 'authors';
+        value: number | Author;
+      } | null)
+    | ({
+        relationTo: 'posts';
+        value: number | Post;
+      } | null)
+    | ({
+        relationTo: 'clients';
+        value: number | Client;
+      } | null)
+    | ({
+        relationTo: 'careers';
+        value: number | Career;
       } | null);
   globalSlug?: string | null;
   user: {
     relationTo: 'users';
-    value: string | User;
+    value: number | User;
   };
   updatedAt: string;
   createdAt: string;
@@ -204,10 +327,10 @@ export interface PayloadLockedDocument {
  * via the `definition` "payload-preferences".
  */
 export interface PayloadPreference {
-  id: string;
+  id: number;
   user: {
     relationTo: 'users';
-    value: string | User;
+    value: number | User;
   };
   key?: string | null;
   value?:
@@ -227,7 +350,7 @@ export interface PayloadPreference {
  * via the `definition` "payload-migrations".
  */
 export interface PayloadMigration {
-  id: string;
+  id: number;
   name?: string | null;
   batch?: number | null;
   updatedAt: string;
@@ -273,6 +396,75 @@ export interface MediaSelect<T extends boolean = true> {
   focalX?: T;
   focalY?: T;
 }
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "authors_select".
+ */
+export interface AuthorsSelect<T extends boolean = true> {
+  name?: T;
+  image?: T;
+  description?: T;
+  socialMediaLink?: T;
+  updatedAt?: T;
+  createdAt?: T;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "posts_select".
+ */
+export interface PostsSelect<T extends boolean = true> {
+  type?: T;
+  category?: T;
+  title?: T;
+  generateSlug?: T;
+  slug?: T;
+  image?: T;
+  excerpt?: T;
+  publishedDate?: T;
+  content?: T;
+  author?: T;
+  updatedAt?: T;
+  createdAt?: T;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "clients_select".
+ */
+export interface ClientsSelect<T extends boolean = true> {
+  name?: T;
+  href?: T;
+  logo?: T;
+  category?: T;
+  imageHeight?: T;
+  updatedAt?: T;
+  createdAt?: T;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "careers_select".
+ */
+export interface CareersSelect<T extends boolean = true> {
+  title?: T;
+  generateSlug?: T;
+  slug?: T;
+  image?: T;
+  requirements?:
+    | T
+    | {
+        item?: T;
+        id?: T;
+      };
+  mainJobDescription?:
+    | T
+    | {
+        item?: T;
+        id?: T;
+      };
+  isUrgentlyHiring?: T;
+  jobCategory?: T;
+  updatedAt?: T;
+  createdAt?: T;
+}
 /**
  * This interface was referenced by `Config`'s JSON-Schema
  * via the `definition` "payload-kv_select".

+ 5 - 1
src/payload.config.ts

@@ -7,6 +7,10 @@ import sharp from 'sharp'
 
 import { Users } from './collections/Users'
 import { Media } from './collections/Media'
+import { Authors } from './collections/Authors'
+import { Posts } from './collections/Posts'
+import { Clients } from './collections/Clients'
+import { Careers } from './collections/Careers'
 
 const filename = fileURLToPath(import.meta.url)
 const dirname = path.dirname(filename)
@@ -18,7 +22,7 @@ export default buildConfig({
       baseDir: path.resolve(dirname),
     },
   },
-  collections: [Users, Media],
+  collections: [Users, Media, Authors, Posts, Clients, Careers],
   editor: lexicalEditor(),
   secret: process.env.PAYLOAD_SECRET || '',
   typescript: {