chore: clean up test scripts and sync payload CRM collections
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 11s
Build & Deploy / 🧪 QA (push) Failing after 23s
Build & Deploy / 🏗️ Build (push) Failing after 27s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 5s

This commit is contained in:
2026-02-27 18:41:48 +01:00
parent 8907963d57
commit 4b5609a75e
15 changed files with 4301 additions and 106 deletions

View File

@@ -0,0 +1,96 @@
import type { CollectionConfig } from "payload";
export const CrmAccounts: CollectionConfig = {
slug: "crm-accounts",
labels: {
singular: "Account",
plural: "Accounts",
},
admin: {
useAsTitle: "name",
defaultColumns: ["name", "status", "leadTemperature", "updatedAt"],
group: "CRM",
},
access: {
read: ({ req: { user } }) => Boolean(user), // Admin only
create: ({ req: { user } }) => Boolean(user),
update: ({ req: { user } }) => Boolean(user),
delete: ({ req: { user } }) => Boolean(user),
},
fields: [
{
name: "analyzeButton",
type: "ui",
admin: {
components: {
Field: "/src/payload/components/AiAnalyzeButton#AiAnalyzeButton",
},
},
},
{
name: "name",
type: "text",
required: true,
label: "Company / Account Name",
},
{
name: "website",
type: "text",
label: "Website URL",
admin: {
description: "The website of the account, useful for AI analysis.",
},
},
{
type: "row",
fields: [
{
name: "status",
type: "select",
options: [
{ label: "Lead", value: "lead" },
{ label: "Client", value: "client" },
{ label: "Lost", value: "lost" },
],
defaultValue: "lead",
admin: {
width: "50%",
description: "Change from Lead to Client upon conversion.",
},
},
{
name: "leadTemperature",
type: "select",
options: [
{ label: "Cold", value: "cold" },
{ label: "Warm", value: "warm" },
{ label: "Hot", value: "hot" },
],
admin: {
condition: (data) => {
return data?.status === "lead";
},
width: "50%",
},
},
],
},
{
name: "assignedTo",
type: "relationship",
relationTo: "users",
label: "Assigned To (User)",
},
{
name: "reports",
type: "relationship",
relationTo: "media",
hasMany: true,
label: "AI Reports & Documents",
admin: {
description:
"PDFs and strategy documents generated by AI or attached manually.",
},
},
],
};

View File

@@ -0,0 +1,79 @@
import type { CollectionConfig } from "payload";
export const CrmContacts: CollectionConfig = {
slug: "crm-contacts",
labels: {
singular: "Contact",
plural: "Contacts",
},
admin: {
useAsTitle: "email", // Fallback, will define an afterRead hook or virtual field for a better title
defaultColumns: ["firstName", "lastName", "email", "account"],
group: "CRM",
},
access: {
read: ({ req: { user } }) => Boolean(user),
create: ({ req: { user } }) => Boolean(user),
update: ({ req: { user } }) => Boolean(user),
delete: ({ req: { user } }) => Boolean(user),
},
fields: [
{
type: "row",
fields: [
{
name: "firstName",
type: "text",
required: true,
admin: {
width: "50%",
},
},
{
name: "lastName",
type: "text",
required: true,
admin: {
width: "50%",
},
},
],
},
{
name: "email",
type: "email",
required: true,
unique: true,
},
{
type: "row",
fields: [
{
name: "phone",
type: "text",
admin: {
width: "50%",
},
},
{
name: "linkedIn",
type: "text",
admin: {
width: "50%",
},
},
],
},
{
name: "role",
type: "text",
label: "Job Title / Role",
},
{
name: "account",
type: "relationship",
relationTo: "crm-accounts",
label: "Company / Account",
},
],
};

View File

@@ -0,0 +1,90 @@
import type { CollectionConfig } from "payload";
import { sendEmailOnOutboundInteraction } from "../hooks/sendEmailOnOutboundInteraction";
export const CrmInteractions: CollectionConfig = {
slug: "crm-interactions",
labels: {
singular: "Interaction",
plural: "Interactions",
},
admin: {
useAsTitle: "subject",
defaultColumns: ["type", "direction", "subject", "date", "contact"],
group: "CRM",
},
access: {
read: ({ req: { user } }) => Boolean(user),
create: ({ req: { user } }) => Boolean(user),
update: ({ req: { user } }) => Boolean(user),
delete: ({ req: { user } }) => Boolean(user),
},
hooks: {
afterChange: [sendEmailOnOutboundInteraction],
},
fields: [
{
type: "row",
fields: [
{
name: "type",
type: "select",
options: [
{ label: "Email", value: "email" },
{ label: "Call", value: "call" },
{ label: "Meeting", value: "meeting" },
{ label: "Note", value: "note" },
],
required: true,
defaultValue: "email",
admin: {
width: "50%",
},
},
{
name: "direction",
type: "select",
options: [
{ label: "Inbound", value: "inbound" },
{ label: "Outbound", value: "outbound" },
],
admin: {
width: "50%",
},
},
],
},
{
name: "date",
type: "date",
required: true,
defaultValue: () => new Date().toISOString(),
admin: {
date: {
pickerAppearance: "dayAndTime",
},
},
},
{
name: "contact",
type: "relationship",
relationTo: "crm-contacts",
label: "Contact Person",
},
{
name: "account",
type: "relationship",
relationTo: "crm-accounts",
label: "Account / Company",
},
{
name: "subject",
type: "text",
required: true,
},
{
name: "content",
type: "richText",
label: "Content / Notes / Email Body",
},
],
};