feat: implement Project Management with Gantt Chart, Milestones, and CRM enhancements
This commit is contained in:
@@ -1,16 +1,18 @@
|
||||
import type { CollectionConfig } from "payload";
|
||||
import { sendEmailOnOutboundInteraction } from "../hooks/sendEmailOnOutboundInteraction";
|
||||
import { lexicalEditor } from "@payloadcms/richtext-lexical";
|
||||
|
||||
export const CrmInteractions: CollectionConfig = {
|
||||
slug: "crm-interactions",
|
||||
labels: {
|
||||
singular: "Interaction",
|
||||
plural: "Interactions",
|
||||
singular: "Journal Entry",
|
||||
plural: "Journal",
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: "subject",
|
||||
defaultColumns: ["type", "direction", "subject", "date", "contact"],
|
||||
defaultColumns: ["type", "subject", "date", "contact", "account"],
|
||||
group: "CRM",
|
||||
description:
|
||||
"Your CRM journal. Log what happened, when, on which channel, and attach any relevant files. This is for summaries and facts — not for sending messages.",
|
||||
},
|
||||
access: {
|
||||
read: ({ req: { user } }) => Boolean(user),
|
||||
@@ -18,9 +20,6 @@ export const CrmInteractions: CollectionConfig = {
|
||||
update: ({ req: { user } }) => Boolean(user),
|
||||
delete: ({ req: { user } }) => Boolean(user),
|
||||
},
|
||||
hooks: {
|
||||
afterChange: [sendEmailOnOutboundInteraction],
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
@@ -28,25 +27,76 @@ export const CrmInteractions: CollectionConfig = {
|
||||
{
|
||||
name: "type",
|
||||
type: "select",
|
||||
label: "Channel",
|
||||
options: [
|
||||
{ label: "Email", value: "email" },
|
||||
{ label: "Call", value: "call" },
|
||||
{ label: "Meeting", value: "meeting" },
|
||||
{ label: "Note", value: "note" },
|
||||
{ label: "📧 Email", value: "email" },
|
||||
{ label: "📞 Phone Call", value: "call" },
|
||||
{ label: "🤝 Meeting", value: "meeting" },
|
||||
{ label: "📱 WhatsApp", value: "whatsapp" },
|
||||
{ label: "🌐 Social Media", value: "social" },
|
||||
{ label: "📄 Document / File", value: "document" },
|
||||
{ label: "📝 Internal Note", value: "note" },
|
||||
],
|
||||
required: true,
|
||||
defaultValue: "email",
|
||||
defaultValue: "note",
|
||||
admin: {
|
||||
width: "50%",
|
||||
description: "Where did this communication take place?",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "direction",
|
||||
type: "select",
|
||||
options: [
|
||||
{ label: "Inbound", value: "inbound" },
|
||||
{ label: "Outbound", value: "outbound" },
|
||||
{ label: "📥 Incoming (from Client)", value: "inbound" },
|
||||
{ label: "📤 Outgoing (to Client)", value: "outbound" },
|
||||
],
|
||||
admin: {
|
||||
hidden: true, // Hide from UI to prevent usage, but keep in DB schema to avoid Drizzle prompts
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "date",
|
||||
type: "date",
|
||||
required: true,
|
||||
defaultValue: () => new Date().toISOString(),
|
||||
admin: {
|
||||
width: "50%",
|
||||
date: {
|
||||
pickerAppearance: "dayAndTime",
|
||||
},
|
||||
description: "When did this happen?",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "subject",
|
||||
type: "text",
|
||||
required: true,
|
||||
label: "Subject / Title",
|
||||
admin: {
|
||||
placeholder: "e.g. Herr X hat Website-Relaunch beauftragt",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "row",
|
||||
fields: [
|
||||
{
|
||||
name: "contact",
|
||||
type: "relationship",
|
||||
relationTo: "crm-contacts",
|
||||
label: "Contact Person",
|
||||
admin: {
|
||||
width: "50%",
|
||||
description: "Who was involved?",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "account",
|
||||
type: "relationship",
|
||||
relationTo: "crm-accounts",
|
||||
label: "Company / Account",
|
||||
admin: {
|
||||
width: "50%",
|
||||
},
|
||||
@@ -54,37 +104,40 @@ export const CrmInteractions: CollectionConfig = {
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "date",
|
||||
type: "date",
|
||||
required: true,
|
||||
defaultValue: () => new Date().toISOString(),
|
||||
name: "topic",
|
||||
type: "relationship",
|
||||
relationTo: "crm-topics",
|
||||
label: "Related Topic",
|
||||
admin: {
|
||||
date: {
|
||||
pickerAppearance: "dayAndTime",
|
||||
description:
|
||||
"Optional: Group this entry under a specific project or topic.",
|
||||
condition: (data) => {
|
||||
return Boolean(data?.account);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
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",
|
||||
label: "Summary / Notes",
|
||||
editor: lexicalEditor({
|
||||
features: ({ defaultFeatures }) => [...defaultFeatures],
|
||||
}),
|
||||
admin: {
|
||||
description:
|
||||
"Summarize what happened, what was decided, or what the next steps are.",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "attachments",
|
||||
type: "relationship",
|
||||
relationTo: "media",
|
||||
hasMany: true,
|
||||
label: "Attachments",
|
||||
admin: {
|
||||
description:
|
||||
"Attach received documents, screenshots, contracts, or any relevant files.",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user