@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,414 @@
1
+ /**
2
+ * CRM Theme - Component Styles
3
+ *
4
+ * Specific component overrides for the CRM app.
5
+ */
6
+
7
+ /* ============================================================================
8
+ Lead Conversion Modal
9
+ ============================================================================ */
10
+
11
+ .convert-lead-modal {
12
+ max-width: 600px;
13
+ width: 100%;
14
+ }
15
+
16
+ .convert-options {
17
+ display: flex;
18
+ flex-direction: column;
19
+ gap: 1rem;
20
+ margin-top: 1rem;
21
+ }
22
+
23
+ .convert-option {
24
+ display: flex;
25
+ align-items: flex-start;
26
+ gap: 0.75rem;
27
+ padding: 1rem;
28
+ border: 1px solid hsl(var(--border));
29
+ border-radius: var(--radius);
30
+ cursor: pointer;
31
+ transition: border-color var(--transition-fast), background var(--transition-fast);
32
+ }
33
+
34
+ .convert-option:hover {
35
+ border-color: hsl(var(--primary));
36
+ background: hsl(var(--primary) / 0.05);
37
+ }
38
+
39
+ .convert-option.selected {
40
+ border-color: hsl(var(--primary));
41
+ background: hsl(var(--primary) / 0.1);
42
+ }
43
+
44
+ .convert-option-icon {
45
+ width: 2.5rem;
46
+ height: 2.5rem;
47
+ border-radius: var(--radius-sm);
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ background: hsl(var(--muted));
52
+ color: hsl(var(--muted-foreground));
53
+ }
54
+
55
+ .convert-option.selected .convert-option-icon {
56
+ background: hsl(var(--primary));
57
+ color: hsl(var(--primary-foreground));
58
+ }
59
+
60
+ .convert-option-content {
61
+ flex: 1;
62
+ }
63
+
64
+ .convert-option-title {
65
+ font-weight: 600;
66
+ font-size: 0.875rem;
67
+ }
68
+
69
+ .convert-option-description {
70
+ font-size: 0.75rem;
71
+ color: hsl(var(--muted-foreground));
72
+ margin-top: 0.25rem;
73
+ }
74
+
75
+ /* ============================================================================
76
+ Quick View Sidebar
77
+ ============================================================================ */
78
+
79
+ .quick-view {
80
+ position: fixed;
81
+ top: 0;
82
+ right: 0;
83
+ width: 400px;
84
+ height: 100vh;
85
+ background: hsl(var(--background));
86
+ border-left: 1px solid hsl(var(--border));
87
+ box-shadow: -4px 0 15px -3px rgb(0 0 0 / 0.1);
88
+ z-index: 50;
89
+ overflow-y: auto;
90
+ transform: translateX(100%);
91
+ transition: transform 0.3s ease;
92
+ }
93
+
94
+ .quick-view.open {
95
+ transform: translateX(0);
96
+ }
97
+
98
+ .quick-view-header {
99
+ padding: 1rem 1.5rem;
100
+ border-bottom: 1px solid hsl(var(--border));
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: space-between;
104
+ position: sticky;
105
+ top: 0;
106
+ background: hsl(var(--background));
107
+ z-index: 1;
108
+ }
109
+
110
+ .quick-view-body {
111
+ padding: 1.5rem;
112
+ }
113
+
114
+ .quick-view-section {
115
+ margin-bottom: 1.5rem;
116
+ }
117
+
118
+ .quick-view-section-title {
119
+ font-size: 0.75rem;
120
+ font-weight: 600;
121
+ text-transform: uppercase;
122
+ letter-spacing: 0.05em;
123
+ color: hsl(var(--muted-foreground));
124
+ margin-bottom: 0.75rem;
125
+ }
126
+
127
+ @media (max-width: 640px) {
128
+ .quick-view {
129
+ width: 100%;
130
+ }
131
+ }
132
+
133
+ /* ============================================================================
134
+ Contact Card
135
+ ============================================================================ */
136
+
137
+ .contact-card {
138
+ display: flex;
139
+ align-items: center;
140
+ gap: 0.75rem;
141
+ padding: 0.75rem;
142
+ border-radius: var(--radius-sm);
143
+ transition: background var(--transition-fast);
144
+ }
145
+
146
+ .contact-card:hover {
147
+ background: hsl(var(--muted) / 0.5);
148
+ }
149
+
150
+ .contact-avatar {
151
+ width: 2.5rem;
152
+ height: 2.5rem;
153
+ border-radius: 9999px;
154
+ object-fit: cover;
155
+ background: hsl(var(--muted));
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ font-weight: 600;
160
+ font-size: 0.875rem;
161
+ color: hsl(var(--muted-foreground));
162
+ }
163
+
164
+ .contact-info {
165
+ flex: 1;
166
+ min-width: 0;
167
+ }
168
+
169
+ .contact-name {
170
+ font-size: 0.875rem;
171
+ font-weight: 500;
172
+ color: hsl(var(--foreground));
173
+ }
174
+
175
+ .contact-role {
176
+ font-size: 0.75rem;
177
+ color: hsl(var(--muted-foreground));
178
+ }
179
+
180
+ .contact-primary-badge {
181
+ font-size: 0.625rem;
182
+ font-weight: 600;
183
+ text-transform: uppercase;
184
+ padding: 0.125rem 0.375rem;
185
+ border-radius: 9999px;
186
+ background: hsl(var(--primary) / 0.1);
187
+ color: hsl(var(--primary));
188
+ }
189
+
190
+ /* ============================================================================
191
+ Company Header
192
+ ============================================================================ */
193
+
194
+ .company-header {
195
+ display: flex;
196
+ align-items: flex-start;
197
+ gap: 1rem;
198
+ padding-bottom: 1.5rem;
199
+ border-bottom: 1px solid hsl(var(--border));
200
+ margin-bottom: 1.5rem;
201
+ }
202
+
203
+ .company-logo {
204
+ width: 4rem;
205
+ height: 4rem;
206
+ border-radius: var(--radius);
207
+ object-fit: contain;
208
+ background: hsl(var(--muted));
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ }
213
+
214
+ .company-logo-placeholder {
215
+ font-size: 1.5rem;
216
+ font-weight: 700;
217
+ color: hsl(var(--muted-foreground));
218
+ }
219
+
220
+ .company-details {
221
+ flex: 1;
222
+ }
223
+
224
+ .company-name {
225
+ font-size: 1.25rem;
226
+ font-weight: 700;
227
+ }
228
+
229
+ .company-industry {
230
+ font-size: 0.875rem;
231
+ color: hsl(var(--muted-foreground));
232
+ margin-top: 0.25rem;
233
+ }
234
+
235
+ .company-meta {
236
+ display: flex;
237
+ gap: 1rem;
238
+ margin-top: 0.5rem;
239
+ font-size: 0.75rem;
240
+ color: hsl(var(--muted-foreground));
241
+ }
242
+
243
+ /* ============================================================================
244
+ Opportunity Value Highlight
245
+ ============================================================================ */
246
+
247
+ .opportunity-value {
248
+ display: flex;
249
+ align-items: baseline;
250
+ gap: 0.25rem;
251
+ }
252
+
253
+ .opportunity-amount {
254
+ font-size: 1.5rem;
255
+ font-weight: 700;
256
+ color: hsl(var(--foreground));
257
+ }
258
+
259
+ .opportunity-currency {
260
+ font-size: 0.875rem;
261
+ color: hsl(var(--muted-foreground));
262
+ }
263
+
264
+ .opportunity-probability {
265
+ display: inline-flex;
266
+ align-items: center;
267
+ gap: 0.25rem;
268
+ padding: 0.25rem 0.5rem;
269
+ border-radius: var(--radius-sm);
270
+ background: hsl(var(--muted));
271
+ font-size: 0.75rem;
272
+ font-weight: 600;
273
+ }
274
+
275
+ /* ============================================================================
276
+ Campaign Progress
277
+ ============================================================================ */
278
+
279
+ .campaign-progress {
280
+ margin-top: 1rem;
281
+ }
282
+
283
+ .campaign-progress-bar {
284
+ height: 0.5rem;
285
+ border-radius: 9999px;
286
+ background: hsl(var(--muted));
287
+ overflow: hidden;
288
+ }
289
+
290
+ .campaign-progress-fill {
291
+ height: 100%;
292
+ border-radius: 9999px;
293
+ background: hsl(var(--primary));
294
+ transition: width 0.5s ease;
295
+ }
296
+
297
+ .campaign-progress-stats {
298
+ display: flex;
299
+ justify-content: space-between;
300
+ margin-top: 0.5rem;
301
+ font-size: 0.75rem;
302
+ color: hsl(var(--muted-foreground));
303
+ }
304
+
305
+ /* ============================================================================
306
+ Report Charts
307
+ ============================================================================ */
308
+
309
+ .report-chart-card {
310
+ background: hsl(var(--card));
311
+ border: 1px solid hsl(var(--border));
312
+ border-radius: var(--radius);
313
+ padding: 1.5rem;
314
+ height: 100%;
315
+ }
316
+
317
+ .report-chart-header {
318
+ display: flex;
319
+ align-items: center;
320
+ justify-content: space-between;
321
+ margin-bottom: 1rem;
322
+ }
323
+
324
+ .report-chart-title {
325
+ font-size: 0.875rem;
326
+ font-weight: 600;
327
+ }
328
+
329
+ .report-chart-period {
330
+ font-size: 0.75rem;
331
+ color: hsl(var(--muted-foreground));
332
+ }
333
+
334
+ /* ============================================================================
335
+ Empty States
336
+ ============================================================================ */
337
+
338
+ .crm-empty-state {
339
+ display: flex;
340
+ flex-direction: column;
341
+ align-items: center;
342
+ justify-content: center;
343
+ padding: 3rem 1.5rem;
344
+ text-align: center;
345
+ }
346
+
347
+ .crm-empty-icon {
348
+ width: 4rem;
349
+ height: 4rem;
350
+ margin-bottom: 1rem;
351
+ color: hsl(var(--muted-foreground) / 0.5);
352
+ }
353
+
354
+ .crm-empty-title {
355
+ font-size: 1.125rem;
356
+ font-weight: 600;
357
+ color: hsl(var(--foreground));
358
+ margin-bottom: 0.5rem;
359
+ }
360
+
361
+ .crm-empty-description {
362
+ font-size: 0.875rem;
363
+ color: hsl(var(--muted-foreground));
364
+ max-width: 20rem;
365
+ margin-bottom: 1.5rem;
366
+ }
367
+
368
+ /* ============================================================================
369
+ Filters Bar
370
+ ============================================================================ */
371
+
372
+ .filters-bar {
373
+ display: flex;
374
+ align-items: center;
375
+ gap: 0.5rem;
376
+ padding: 0.75rem 1rem;
377
+ background: hsl(var(--muted) / 0.3);
378
+ border-radius: var(--radius);
379
+ margin-bottom: 1rem;
380
+ }
381
+
382
+ .filter-chip {
383
+ display: inline-flex;
384
+ align-items: center;
385
+ gap: 0.25rem;
386
+ padding: 0.25rem 0.75rem;
387
+ border-radius: 9999px;
388
+ font-size: 0.75rem;
389
+ font-weight: 500;
390
+ background: hsl(var(--background));
391
+ border: 1px solid hsl(var(--border));
392
+ cursor: pointer;
393
+ transition: all var(--transition-fast);
394
+ }
395
+
396
+ .filter-chip:hover {
397
+ border-color: hsl(var(--primary));
398
+ }
399
+
400
+ .filter-chip.active {
401
+ background: hsl(var(--primary));
402
+ border-color: hsl(var(--primary));
403
+ color: hsl(var(--primary-foreground));
404
+ }
405
+
406
+ .filter-chip-remove {
407
+ margin-left: 0.25rem;
408
+ opacity: 0.7;
409
+ }
410
+
411
+ .filter-chip-remove:hover {
412
+ opacity: 1;
413
+ }
414
+