@nextsparkjs/theme-crm 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/CRM_PLAN.md +343 -0
  2. package/about.md +122 -0
  3. package/config/app.config.ts +185 -0
  4. package/config/billing.config.ts +187 -0
  5. package/config/dashboard.config.ts +372 -0
  6. package/config/dev.config.ts +55 -0
  7. package/config/features.config.ts +336 -0
  8. package/config/flows.config.ts +511 -0
  9. package/config/permissions.config.ts +297 -0
  10. package/config/theme.config.ts +111 -0
  11. package/entities/activities/activities.config.ts +61 -0
  12. package/entities/activities/activities.fields.ts +362 -0
  13. package/entities/activities/activities.service.ts +503 -0
  14. package/entities/activities/activities.types.ts +117 -0
  15. package/entities/activities/messages/en.json +123 -0
  16. package/entities/activities/messages/es.json +123 -0
  17. package/entities/activities/migrations/020_activities_table.sql +123 -0
  18. package/entities/activities/migrations/021_activities_metas.sql +114 -0
  19. package/entities/activities/migrations/022_activities_sample_data.sql +420 -0
  20. package/entities/campaigns/campaigns.config.ts +61 -0
  21. package/entities/campaigns/campaigns.fields.ts +413 -0
  22. package/entities/campaigns/campaigns.service.ts +426 -0
  23. package/entities/campaigns/campaigns.types.ts +124 -0
  24. package/entities/campaigns/messages/en.json +145 -0
  25. package/entities/campaigns/messages/es.json +145 -0
  26. package/entities/campaigns/migrations/001_campaigns_table.sql +127 -0
  27. package/entities/campaigns/migrations/002_campaigns_metas.sql +114 -0
  28. package/entities/campaigns/migrations/003_campaigns_sample_data.sql +364 -0
  29. package/entities/companies/companies.config.ts +61 -0
  30. package/entities/companies/companies.fields.ts +429 -0
  31. package/entities/companies/companies.service.ts +566 -0
  32. package/entities/companies/companies.types.ts +125 -0
  33. package/entities/companies/messages/en.json +146 -0
  34. package/entities/companies/messages/es.json +146 -0
  35. package/entities/companies/migrations/001_companies_table.sql +150 -0
  36. package/entities/companies/migrations/002_companies_metas.sql +114 -0
  37. package/entities/companies/migrations/003_companies_sample_data.sql +246 -0
  38. package/entities/contacts/contacts.config.ts +61 -0
  39. package/entities/contacts/contacts.fields.ts +359 -0
  40. package/entities/contacts/contacts.service.ts +509 -0
  41. package/entities/contacts/contacts.types.ts +108 -0
  42. package/entities/contacts/messages/en.json +117 -0
  43. package/entities/contacts/messages/es.json +117 -0
  44. package/entities/contacts/migrations/001_contacts_table.sql +134 -0
  45. package/entities/contacts/migrations/002_contacts_metas.sql +114 -0
  46. package/entities/contacts/migrations/003_contacts_sample_data.sql +421 -0
  47. package/entities/leads/leads.config.ts +61 -0
  48. package/entities/leads/leads.fields.ts +336 -0
  49. package/entities/leads/leads.service.ts +496 -0
  50. package/entities/leads/leads.types.ts +114 -0
  51. package/entities/leads/messages/en.json +132 -0
  52. package/entities/leads/messages/es.json +132 -0
  53. package/entities/leads/migrations/001_leads_table.sql +150 -0
  54. package/entities/leads/migrations/002_leads_metas.sql +120 -0
  55. package/entities/leads/migrations/003_leads_sample_data.sql +242 -0
  56. package/entities/notes/messages/en.json +114 -0
  57. package/entities/notes/messages/es.json +114 -0
  58. package/entities/notes/migrations/020_notes_table.sql +118 -0
  59. package/entities/notes/migrations/021_notes_metas.sql +114 -0
  60. package/entities/notes/migrations/022_notes_sample_data.sql +275 -0
  61. package/entities/notes/notes.config.ts +61 -0
  62. package/entities/notes/notes.fields.ts +283 -0
  63. package/entities/notes/notes.service.ts +320 -0
  64. package/entities/notes/notes.types.ts +102 -0
  65. package/entities/opportunities/messages/en.json +107 -0
  66. package/entities/opportunities/messages/es.json +107 -0
  67. package/entities/opportunities/migrations/010_opportunities_table.sql +145 -0
  68. package/entities/opportunities/migrations/011_opportunities_metas.sql +114 -0
  69. package/entities/opportunities/migrations/012_opportunities_sample_data.sql +438 -0
  70. package/entities/opportunities/opportunities.config.ts +61 -0
  71. package/entities/opportunities/opportunities.fields.ts +416 -0
  72. package/entities/opportunities/opportunities.service.ts +525 -0
  73. package/entities/opportunities/opportunities.types.ts +135 -0
  74. package/entities/pipelines/messages/en.json +115 -0
  75. package/entities/pipelines/messages/es.json +115 -0
  76. package/entities/pipelines/migrations/001_pipelines_table.sql +106 -0
  77. package/entities/pipelines/migrations/002_pipelines_metas.sql +114 -0
  78. package/entities/pipelines/migrations/003_pipelines_sample_data.sql +91 -0
  79. package/entities/pipelines/pipelines.config.ts +62 -0
  80. package/entities/pipelines/pipelines.fields.ts +193 -0
  81. package/entities/pipelines/pipelines.service.ts +383 -0
  82. package/entities/pipelines/pipelines.types.ts +78 -0
  83. package/entities/products/messages/en.json +135 -0
  84. package/entities/products/messages/es.json +135 -0
  85. package/entities/products/migrations/001_products_table.sql +117 -0
  86. package/entities/products/migrations/002_products_metas.sql +114 -0
  87. package/entities/products/migrations/003_products_sample_data.sql +247 -0
  88. package/entities/products/products.config.ts +62 -0
  89. package/entities/products/products.fields.ts +361 -0
  90. package/entities/products/products.service.ts +437 -0
  91. package/entities/products/products.types.ts +125 -0
  92. package/lib/crm-constants.ts +77 -0
  93. package/lib/crm-utils.ts +185 -0
  94. package/lib/selectors.ts +333 -0
  95. package/messages/en.json +131 -0
  96. package/messages/es.json +131 -0
  97. package/migrations/999_theme_sample_data.sql +473 -0
  98. package/package.json +18 -0
  99. package/pendings.md +205 -0
  100. package/permissions-matrix.md +216 -0
  101. package/styles/components.css +414 -0
  102. package/styles/crm-theme.css +358 -0
  103. package/styles/globals.css +576 -0
  104. package/styles/variables.css +111 -0
  105. package/templates/dashboard/(main)/activities/components/ActivityCard.tsx +169 -0
  106. package/templates/dashboard/(main)/activities/components/ActivityTimeline.tsx +165 -0
  107. package/templates/dashboard/(main)/activities/page.tsx +297 -0
  108. package/templates/dashboard/(main)/campaigns/page.tsx +373 -0
  109. package/templates/dashboard/(main)/companies/page.tsx +296 -0
  110. package/templates/dashboard/(main)/contacts/page.tsx +347 -0
  111. package/templates/dashboard/(main)/layout.tsx +98 -0
  112. package/templates/dashboard/(main)/leads/page.tsx +335 -0
  113. package/templates/dashboard/(main)/opportunities/[id]/edit/page.tsx +95 -0
  114. package/templates/dashboard/(main)/opportunities/create/page.tsx +94 -0
  115. package/templates/dashboard/(main)/opportunities/page.tsx +350 -0
  116. package/templates/dashboard/(main)/pipelines/[id]/edit/page.tsx +95 -0
  117. package/templates/dashboard/(main)/pipelines/[id]/page.tsx +143 -0
  118. package/templates/dashboard/(main)/pipelines/create/page.tsx +94 -0
  119. package/templates/dashboard/(main)/pipelines/page.tsx +234 -0
  120. package/templates/dashboard/(main)/products/[id]/edit/page.tsx +97 -0
  121. package/templates/dashboard/(main)/products/[id]/page.tsx +509 -0
  122. package/templates/dashboard/(main)/products/create/page.tsx +96 -0
  123. package/templates/dashboard/(main)/products/page.tsx +308 -0
  124. package/templates/shared/ActionButtons.tsx +41 -0
  125. package/templates/shared/CRMDashboard.tsx +519 -0
  126. package/templates/shared/CRMDataTable.tsx +441 -0
  127. package/templates/shared/CRMMetricCard.tsx +76 -0
  128. package/templates/shared/CRMMobileNav.tsx +172 -0
  129. package/templates/shared/CRMSidebar.tsx +346 -0
  130. package/templates/shared/CRMTopBar.tsx +265 -0
  131. package/templates/shared/DealCard.tsx +123 -0
  132. package/templates/shared/EntityCard.tsx +58 -0
  133. package/templates/shared/OpportunityForm.tsx +649 -0
  134. package/templates/shared/PipelineForm.tsx +367 -0
  135. package/templates/shared/PipelineKanban.tsx +194 -0
  136. package/templates/shared/QuickFilters.tsx +47 -0
  137. package/templates/shared/StageColumn.tsx +175 -0
  138. package/templates/shared/StageSelect.tsx +177 -0
  139. package/templates/shared/StagesRepeater.tsx +317 -0
  140. package/templates/shared/index.ts +9 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Opportunities Entity Configuration - CRM
3
+ *
4
+ * Sales opportunities in the pipeline.
5
+ * Updated with team support and granular permissions.
6
+ */
7
+
8
+ import { TrendingUp } from 'lucide-react'
9
+ import type { EntityConfig } from '@nextsparkjs/core/lib/entities/types'
10
+ import { opportunitiesFields } from './opportunities.fields'
11
+
12
+ export const opportunitiesEntityConfig: EntityConfig = {
13
+ // ==========================================
14
+ // 1. BASIC IDENTIFICATION
15
+ // ==========================================
16
+ slug: 'opportunities',
17
+ enabled: true,
18
+ names: {
19
+ singular: 'opportunity',
20
+ plural: 'Opportunities'
21
+ },
22
+ icon: TrendingUp,
23
+
24
+ // ==========================================
25
+ // 2. ACCESS AND SCOPE CONFIGURATION
26
+ // ==========================================
27
+ access: {
28
+ public: false,
29
+ api: true,
30
+ metadata: true,
31
+ shared: true
32
+ },
33
+
34
+ // ==========================================
35
+ // 3. UI/UX FEATURES
36
+ // ==========================================
37
+ ui: {
38
+ dashboard: {
39
+ showInMenu: true,
40
+ showInTopbar: true
41
+ },
42
+ public: {
43
+ hasArchivePage: false,
44
+ hasSinglePage: false
45
+ },
46
+ features: {
47
+ searchable: true,
48
+ sortable: true,
49
+ filterable: true,
50
+ bulkOperations: true,
51
+ importExport: true
52
+ }
53
+ },
54
+
55
+ // ==========================================
56
+ // FIELDS
57
+ // ==========================================
58
+ fields: opportunitiesFields,
59
+ }
60
+
61
+ export default opportunitiesEntityConfig
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Opportunities Entity Fields Configuration
3
+ *
4
+ * Separated from main config according to new refactoring plan.
5
+ * Contains all field definitions for the opportunities entity.
6
+ */
7
+
8
+ import type { EntityField } from '@nextsparkjs/core/lib/entities/types'
9
+
10
+ export const opportunitiesFields: EntityField[] = [
11
+ {
12
+ name: 'name',
13
+ type: 'text',
14
+ required: true,
15
+ display: {
16
+ label: 'Opportunity Name',
17
+ description: 'Opportunity name or title',
18
+ placeholder: 'Enter opportunity name...',
19
+ showInList: true,
20
+ showInDetail: true,
21
+ showInForm: true,
22
+ order: 1,
23
+ columnWidth: 6,
24
+ },
25
+ api: {
26
+ searchable: true,
27
+ sortable: true,
28
+ readOnly: false,
29
+ },
30
+ },
31
+ {
32
+ name: 'companyId',
33
+ type: 'relation',
34
+ required: true,
35
+ relation: {
36
+ entity: 'companies',
37
+ titleField: 'name',
38
+ },
39
+ display: {
40
+ label: 'Company',
41
+ description: 'Company this opportunity belongs to',
42
+ placeholder: 'Select company...',
43
+ showInList: true,
44
+ showInDetail: true,
45
+ showInForm: true,
46
+ order: 2,
47
+ columnWidth: 6,
48
+ },
49
+ api: {
50
+ searchable: false,
51
+ sortable: true,
52
+ readOnly: false,
53
+ },
54
+ },
55
+ {
56
+ name: 'contactId',
57
+ type: 'relation',
58
+ required: false,
59
+ relation: {
60
+ entity: 'contacts',
61
+ titleField: 'firstName',
62
+ },
63
+ display: {
64
+ label: 'Primary Contact',
65
+ description: 'Primary contact for this opportunity',
66
+ placeholder: 'Select contact...',
67
+ showInList: true,
68
+ showInDetail: true,
69
+ showInForm: true,
70
+ order: 3,
71
+ columnWidth: 6,
72
+ },
73
+ api: {
74
+ searchable: false,
75
+ sortable: true,
76
+ readOnly: false,
77
+ },
78
+ },
79
+ {
80
+ name: 'pipelineId',
81
+ type: 'relation',
82
+ required: true,
83
+ relation: {
84
+ entity: 'pipelines',
85
+ titleField: 'name',
86
+ },
87
+ display: {
88
+ label: 'Pipeline',
89
+ description: 'Pipeline this opportunity is in',
90
+ placeholder: 'Select pipeline...',
91
+ showInList: false,
92
+ showInDetail: true,
93
+ showInForm: true,
94
+ order: 4,
95
+ columnWidth: 6,
96
+ },
97
+ api: {
98
+ searchable: false,
99
+ sortable: true,
100
+ readOnly: false,
101
+ },
102
+ },
103
+ {
104
+ name: 'stageId',
105
+ type: 'text',
106
+ required: true,
107
+ display: {
108
+ label: 'Stage',
109
+ description: 'Current stage in pipeline',
110
+ placeholder: 'Stage ID from pipeline',
111
+ showInList: true,
112
+ showInDetail: true,
113
+ showInForm: true,
114
+ order: 5,
115
+ columnWidth: 4,
116
+ },
117
+ api: {
118
+ searchable: false,
119
+ sortable: true,
120
+ readOnly: false,
121
+ },
122
+ },
123
+ {
124
+ name: 'amount',
125
+ type: 'number',
126
+ required: true,
127
+ display: {
128
+ label: 'Deal Amount',
129
+ description: 'Deal amount value',
130
+ placeholder: '0.00',
131
+ showInList: true,
132
+ showInDetail: true,
133
+ showInForm: true,
134
+ order: 6,
135
+ columnWidth: 4,
136
+ },
137
+ api: {
138
+ searchable: false,
139
+ sortable: true,
140
+ readOnly: false,
141
+ },
142
+ },
143
+ {
144
+ name: 'currency',
145
+ type: 'select',
146
+ required: false,
147
+ options: [
148
+ { value: 'USD', label: 'US Dollar' },
149
+ { value: 'EUR', label: 'Euro' },
150
+ { value: 'GBP', label: 'British Pound' },
151
+ { value: 'MXN', label: 'Mexican Peso' },
152
+ { value: 'CAD', label: 'Canadian Dollar' },
153
+ { value: 'AUD', label: 'Australian Dollar' },
154
+ { value: 'JPY', label: 'Japanese Yen' },
155
+ { value: 'CNY', label: 'Chinese Yuan' },
156
+ { value: 'INR', label: 'Indian Rupee' },
157
+ { value: 'BRL', label: 'Brazilian Real' },
158
+ ],
159
+ display: {
160
+ label: 'Currency',
161
+ description: 'Currency code for amount',
162
+ placeholder: 'Select currency...',
163
+ showInList: false,
164
+ showInDetail: true,
165
+ showInForm: true,
166
+ order: 7,
167
+ columnWidth: 4,
168
+ },
169
+ api: {
170
+ searchable: false,
171
+ sortable: true,
172
+ readOnly: false,
173
+ },
174
+ },
175
+ {
176
+ name: 'probability',
177
+ type: 'number',
178
+ required: false,
179
+ display: {
180
+ label: 'Win Probability (%)',
181
+ description: 'Win probability percentage',
182
+ placeholder: '0',
183
+ showInList: true,
184
+ showInDetail: true,
185
+ showInForm: true,
186
+ order: 8,
187
+ columnWidth: 4,
188
+ },
189
+ api: {
190
+ searchable: false,
191
+ sortable: true,
192
+ readOnly: false,
193
+ },
194
+ },
195
+ {
196
+ name: 'expectedRevenue',
197
+ type: 'number',
198
+ required: false,
199
+ display: {
200
+ label: 'Expected Revenue',
201
+ description: 'Calculated expected revenue',
202
+ showInList: true,
203
+ showInDetail: true,
204
+ showInForm: false,
205
+ order: 9,
206
+ columnWidth: 4,
207
+ },
208
+ api: {
209
+ searchable: false,
210
+ sortable: true,
211
+ readOnly: true,
212
+ },
213
+ },
214
+ {
215
+ name: 'closeDate',
216
+ type: 'date',
217
+ required: true,
218
+ display: {
219
+ label: 'Expected Close Date',
220
+ description: 'Expected or actual close date',
221
+ placeholder: 'Select date...',
222
+ showInList: true,
223
+ showInDetail: true,
224
+ showInForm: true,
225
+ order: 10,
226
+ columnWidth: 4,
227
+ },
228
+ api: {
229
+ searchable: false,
230
+ sortable: true,
231
+ readOnly: false,
232
+ },
233
+ },
234
+ {
235
+ name: 'type',
236
+ type: 'select',
237
+ required: false,
238
+ options: [
239
+ { value: 'new_business', label: 'New Business' },
240
+ { value: 'existing_business', label: 'Existing Business' },
241
+ { value: 'renewal', label: 'Renewal' },
242
+ { value: 'upgrade', label: 'Upgrade' },
243
+ { value: 'downgrade', label: 'Downgrade' },
244
+ ],
245
+ display: {
246
+ label: 'Opportunity Type',
247
+ description: 'Type of opportunity',
248
+ placeholder: 'Select type...',
249
+ showInList: false,
250
+ showInDetail: true,
251
+ showInForm: true,
252
+ order: 11,
253
+ columnWidth: 4,
254
+ },
255
+ api: {
256
+ searchable: false,
257
+ sortable: true,
258
+ readOnly: false,
259
+ },
260
+ },
261
+ {
262
+ name: 'source',
263
+ type: 'select',
264
+ required: false,
265
+ options: [
266
+ { value: 'web', label: 'Website' },
267
+ { value: 'referral', label: 'Referral' },
268
+ { value: 'cold_call', label: 'Cold Call' },
269
+ { value: 'trade_show', label: 'Trade Show' },
270
+ { value: 'social_media', label: 'Social Media' },
271
+ { value: 'email', label: 'Email' },
272
+ { value: 'advertising', label: 'Advertising' },
273
+ { value: 'partner', label: 'Partner' },
274
+ { value: 'other', label: 'Other' },
275
+ ],
276
+ display: {
277
+ label: 'Source',
278
+ description: 'Source of the opportunity',
279
+ placeholder: 'Select source...',
280
+ showInList: false,
281
+ showInDetail: true,
282
+ showInForm: true,
283
+ order: 12,
284
+ columnWidth: 4,
285
+ },
286
+ api: {
287
+ searchable: false,
288
+ sortable: true,
289
+ readOnly: false,
290
+ },
291
+ },
292
+ {
293
+ name: 'competitor',
294
+ type: 'text',
295
+ required: false,
296
+ display: {
297
+ label: 'Main Competitor',
298
+ description: 'Main competitor for this deal',
299
+ placeholder: 'Enter competitor...',
300
+ showInList: false,
301
+ showInDetail: true,
302
+ showInForm: true,
303
+ order: 13,
304
+ columnWidth: 4,
305
+ },
306
+ api: {
307
+ searchable: true,
308
+ sortable: true,
309
+ readOnly: false,
310
+ },
311
+ },
312
+ {
313
+ name: 'status',
314
+ type: 'select',
315
+ required: false,
316
+ options: [
317
+ { value: 'open', label: 'Open' },
318
+ { value: 'won', label: 'Won' },
319
+ { value: 'lost', label: 'Lost' },
320
+ { value: 'abandoned', label: 'Abandoned' },
321
+ ],
322
+ display: {
323
+ label: 'Status',
324
+ description: 'Current opportunity status',
325
+ placeholder: 'Select status...',
326
+ showInList: true,
327
+ showInDetail: true,
328
+ showInForm: true,
329
+ order: 14,
330
+ columnWidth: 4,
331
+ },
332
+ api: {
333
+ searchable: false,
334
+ sortable: true,
335
+ readOnly: false,
336
+ },
337
+ },
338
+ {
339
+ name: 'lostReason',
340
+ type: 'text',
341
+ required: false,
342
+ display: {
343
+ label: 'Lost Reason',
344
+ description: 'Reason if opportunity was lost',
345
+ placeholder: 'Enter reason...',
346
+ showInList: false,
347
+ showInDetail: true,
348
+ showInForm: true,
349
+ order: 15,
350
+ columnWidth: 6,
351
+ },
352
+ api: {
353
+ searchable: true,
354
+ sortable: false,
355
+ readOnly: false,
356
+ },
357
+ },
358
+ {
359
+ name: 'assignedTo',
360
+ type: 'user',
361
+ required: false,
362
+ display: {
363
+ label: 'Assigned To',
364
+ description: 'Sales rep assigned to opportunity',
365
+ placeholder: 'Select user...',
366
+ showInList: true,
367
+ showInDetail: true,
368
+ showInForm: true,
369
+ order: 16,
370
+ columnWidth: 4,
371
+ },
372
+ api: {
373
+ searchable: false,
374
+ sortable: true,
375
+ readOnly: false,
376
+ },
377
+ },
378
+ {
379
+ name: 'createdAt',
380
+ type: 'datetime',
381
+ required: false,
382
+ display: {
383
+ label: 'Created At',
384
+ description: 'When the opportunity was created',
385
+ showInList: true,
386
+ showInDetail: true,
387
+ showInForm: false,
388
+ order: 98,
389
+ columnWidth: 4,
390
+ },
391
+ api: {
392
+ searchable: false,
393
+ sortable: true,
394
+ readOnly: true,
395
+ },
396
+ },
397
+ {
398
+ name: 'updatedAt',
399
+ type: 'datetime',
400
+ required: false,
401
+ display: {
402
+ label: 'Updated At',
403
+ description: 'When the opportunity was last updated',
404
+ showInList: false,
405
+ showInDetail: true,
406
+ showInForm: false,
407
+ order: 99,
408
+ columnWidth: 4,
409
+ },
410
+ api: {
411
+ searchable: false,
412
+ sortable: true,
413
+ readOnly: true,
414
+ },
415
+ },
416
+ ]