create-crm-tmp 2.0.0 → 2.1.0

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 (190) hide show
  1. package/bin/create-crm-tmp.js +56 -35
  2. package/package.json +1 -1
  3. package/template/README.md +230 -115
  4. package/template/eslint.config.mjs +13 -0
  5. package/template/next.config.ts +14 -0
  6. package/template/package.json +15 -2
  7. package/template/prisma/migrations/20260318095700_init_db/migration.sql +978 -0
  8. package/template/prisma/migrations/migration_lock.toml +3 -0
  9. package/template/prisma/schema.prisma +132 -637
  10. package/template/src/app/(auth)/invite/[token]/page.tsx +10 -8
  11. package/template/src/app/(auth)/layout.tsx +1 -1
  12. package/template/src/app/(auth)/reset-password/complete/page.tsx +11 -8
  13. package/template/src/app/(auth)/reset-password/page.tsx +4 -4
  14. package/template/src/app/(auth)/reset-password/verify/page.tsx +4 -4
  15. package/template/src/app/(auth)/signin/page.tsx +14 -6
  16. package/template/src/app/(dashboard)/agenda/page.tsx +2243 -988
  17. package/template/src/app/(dashboard)/automatisation/_components/workflow-editor.tsx +18 -104
  18. package/template/src/app/(dashboard)/automatisation/page.tsx +10 -26
  19. package/template/src/app/(dashboard)/closing/page.tsx +78 -62
  20. package/template/src/app/(dashboard)/contacts/[id]/page.tsx +2082 -1080
  21. package/template/src/app/(dashboard)/contacts/companies/[id]/page.tsx +46 -47
  22. package/template/src/app/(dashboard)/contacts/page.tsx +1062 -780
  23. package/template/src/app/(dashboard)/dashboard/page.tsx +533 -37
  24. package/template/src/app/(dashboard)/dev/page.tsx +1291 -0
  25. package/template/src/app/(dashboard)/layout.tsx +6 -2
  26. package/template/src/app/(dashboard)/settings/page.tsx +797 -2582
  27. package/template/src/app/(dashboard)/templates/page.tsx +55 -54
  28. package/template/src/app/(dashboard)/users/list/page.tsx +51 -48
  29. package/template/src/app/(dashboard)/users/page.tsx +1 -1
  30. package/template/src/app/(dashboard)/users/permissions/page.tsx +2 -2
  31. package/template/src/app/(dashboard)/users/roles/page.tsx +7 -5
  32. package/template/src/app/api/agenda/google-events/route.ts +92 -0
  33. package/template/src/app/api/auth/check-active/route.ts +3 -2
  34. package/template/src/app/api/auth/google/route.ts +2 -1
  35. package/template/src/app/api/auth/google/status/route.ts +7 -31
  36. package/template/src/app/api/companies/[id]/activities/route.ts +1 -3
  37. package/template/src/app/api/companies/[id]/route.ts +1 -2
  38. package/template/src/app/api/companies/route.ts +42 -12
  39. package/template/src/app/api/contacts/[id]/files/[fileId]/preview/route.ts +9 -31
  40. package/template/src/app/api/contacts/[id]/files/[fileId]/route.ts +14 -32
  41. package/template/src/app/api/contacts/[id]/files/route.ts +112 -212
  42. package/template/src/app/api/contacts/[id]/interactions/[interactionId]/route.ts +27 -1
  43. package/template/src/app/api/contacts/[id]/interactions/route.ts +16 -16
  44. package/template/src/app/api/contacts/[id]/kyc/route.ts +21 -11
  45. package/template/src/app/api/contacts/[id]/meet/route.ts +19 -2
  46. package/template/src/app/api/contacts/[id]/route.ts +106 -34
  47. package/template/src/app/api/contacts/[id]/send-email/route.ts +27 -11
  48. package/template/src/app/api/contacts/[id]/workflows/run/route.ts +6 -0
  49. package/template/src/app/api/contacts/export/route.ts +9 -13
  50. package/template/src/app/api/contacts/import/route.ts +55 -25
  51. package/template/src/app/api/contacts/import-preview/route.ts +1 -1
  52. package/template/src/app/api/contacts/origins/route.ts +63 -0
  53. package/template/src/app/api/contacts/route.ts +153 -41
  54. package/template/src/app/api/cron/cleanup-editor-images/route.ts +166 -0
  55. package/template/src/app/api/dashboard/widgets/[id]/route.ts +44 -0
  56. package/template/src/app/api/dashboard/widgets/route.ts +181 -0
  57. package/template/src/app/api/dev/reminders/test/route.ts +114 -0
  58. package/template/src/app/api/editor/upload-image/route.ts +61 -0
  59. package/template/src/app/api/integrations/google-sheet/jobs/[jobId]/route.ts +47 -0
  60. package/template/src/app/api/integrations/google-sheet/jobs/usage/route.ts +50 -0
  61. package/template/src/app/api/integrations/google-sheet/sync/route.ts +24 -556
  62. package/template/src/app/api/jobs/google-sheet/process/route.ts +84 -0
  63. package/template/src/app/api/jobs/google-sheet/schedule/route.ts +50 -0
  64. package/template/src/app/api/reminders/clear/route.ts +120 -0
  65. package/template/src/app/api/reminders/clear/undo/route.ts +112 -0
  66. package/template/src/app/api/reminders/route.ts +164 -39
  67. package/template/src/app/api/reminders/state/route.ts +164 -0
  68. package/template/src/app/api/reset-password/request/route.ts +1 -1
  69. package/template/src/app/api/reset-password/verify/route.ts +1 -1
  70. package/template/src/app/api/send/route.ts +16 -4
  71. package/template/src/app/api/settings/google-ads/route.ts +14 -0
  72. package/template/src/app/api/settings/google-calendar/calendars/route.ts +97 -0
  73. package/template/src/app/api/settings/google-calendar/route.ts +124 -0
  74. package/template/src/app/api/settings/google-sheet/[id]/route.ts +28 -0
  75. package/template/src/app/api/settings/google-sheet/auto-map/route.ts +37 -4
  76. package/template/src/app/api/settings/google-sheet/preview/route.ts +9 -3
  77. package/template/src/app/api/settings/google-sheet/route.ts +14 -0
  78. package/template/src/app/api/settings/integrations/logs/route.ts +93 -0
  79. package/template/src/app/api/settings/integrations/notifications/route.ts +67 -0
  80. package/template/src/app/api/settings/meta-leads/[id]/route.ts +0 -1
  81. package/template/src/app/api/settings/meta-leads/route.ts +14 -2
  82. package/template/src/app/api/settings/smtp/route.ts +53 -6
  83. package/template/src/app/api/tasks/[id]/attendees/route.ts +24 -8
  84. package/template/src/app/api/tasks/[id]/route.ts +234 -58
  85. package/template/src/app/api/tasks/meet/route.ts +27 -19
  86. package/template/src/app/api/tasks/route.ts +62 -17
  87. package/template/src/app/api/users/[id]/route.ts +20 -14
  88. package/template/src/app/api/users/list/route.ts +57 -19
  89. package/template/src/app/api/webhooks/google-ads/route.ts +34 -14
  90. package/template/src/app/api/webhooks/meta-leads/route.ts +32 -12
  91. package/template/src/app/api/workflows/[id]/route.ts +0 -4
  92. package/template/src/app/api/workflows/process/route.ts +22 -51
  93. package/template/src/app/api/workflows/route.ts +0 -4
  94. package/template/src/app/globals.css +342 -4
  95. package/template/src/app/layout.tsx +11 -3
  96. package/template/src/app/page.tsx +1 -1
  97. package/template/src/components/address-autocomplete.tsx +7 -6
  98. package/template/src/components/config-error-alert.tsx +46 -0
  99. package/template/src/components/contacts/filter-bar.tsx +12 -3
  100. package/template/src/components/contacts/filter-builder.tsx +28 -43
  101. package/template/src/components/contacts/save-view-dialog.tsx +1 -1
  102. package/template/src/components/contacts/views-tab-bar.tsx +15 -6
  103. package/template/src/components/dashboard/activity-chart.tsx +41 -28
  104. package/template/src/components/dashboard/add-widget-dialog.tsx +157 -0
  105. package/template/src/components/dashboard/color-picker.tsx +64 -0
  106. package/template/src/components/dashboard/contacts-chart.tsx +69 -0
  107. package/template/src/components/dashboard/interactions-by-type-chart.tsx +121 -0
  108. package/template/src/components/dashboard/recent-activity.tsx +154 -0
  109. package/template/src/components/dashboard/stat-card.tsx +40 -40
  110. package/template/src/components/dashboard/status-distribution-chart.tsx +81 -0
  111. package/template/src/components/dashboard/tasks-pie-chart.tsx +37 -34
  112. package/template/src/components/dashboard/top-contacts-list.tsx +113 -0
  113. package/template/src/components/dashboard/upcoming-tasks-list.tsx +72 -81
  114. package/template/src/components/dashboard/widget-wrapper.tsx +36 -0
  115. package/template/src/components/date-picker.tsx +9 -6
  116. package/template/src/components/editor/upload-editor-image.ts +42 -0
  117. package/template/src/components/editor.tsx +161 -22
  118. package/template/src/components/email-template.tsx +2 -2
  119. package/template/src/components/global-search.tsx +30 -28
  120. package/template/src/components/header.tsx +178 -80
  121. package/template/src/components/inactive-account-guard.tsx +58 -0
  122. package/template/src/components/integration-notifications-listener.tsx +12 -0
  123. package/template/src/components/invitation-email-template.tsx +2 -2
  124. package/template/src/components/meet-cancellation-email-template.tsx +3 -3
  125. package/template/src/components/meet-confirmation-email-template.tsx +3 -3
  126. package/template/src/components/meet-update-email-template.tsx +3 -3
  127. package/template/src/components/page-header.tsx +5 -5
  128. package/template/src/components/protected-page.tsx +1 -1
  129. package/template/src/components/reset-password-email-template.tsx +2 -2
  130. package/template/src/components/settings/integrations/GoogleAdsIntegration.tsx +428 -0
  131. package/template/src/components/settings/integrations/GoogleSheetConfigMonitoringModal.tsx +680 -0
  132. package/template/src/components/settings/integrations/GoogleSheetIntegration.tsx +809 -0
  133. package/template/src/components/settings/integrations/ImportResultDialog.tsx +124 -0
  134. package/template/src/components/settings/integrations/IntegrationLogPanel.tsx +57 -0
  135. package/template/src/components/settings/integrations/IntegrationLogsTable.tsx +186 -0
  136. package/template/src/components/settings/integrations/MetaLeadIntegration.tsx +451 -0
  137. package/template/src/components/sidebar.tsx +45 -26
  138. package/template/src/components/skeleton.tsx +40 -43
  139. package/template/src/components/ui/accordion.tsx +2 -2
  140. package/template/src/components/ui/alert-dialog.tsx +1 -1
  141. package/template/src/components/ui/button.tsx +20 -9
  142. package/template/src/components/ui/components.tsx +1 -1
  143. package/template/src/components/ui/date-picker.tsx +422 -0
  144. package/template/src/components/ui/datetime-picker.tsx +338 -0
  145. package/template/src/components/ui/status-select.tsx +271 -0
  146. package/template/src/components/ui/tooltip.tsx +37 -0
  147. package/template/src/components/view-as-modal.tsx +13 -7
  148. package/template/src/contexts/app-toast-context.tsx +245 -57
  149. package/template/src/contexts/dashboard-theme-context.tsx +53 -0
  150. package/template/src/contexts/sidebar-context.tsx +22 -17
  151. package/template/src/contexts/task-reminder-context.tsx +134 -160
  152. package/template/src/contexts/view-as-context.tsx +33 -6
  153. package/template/src/hooks/use-focus-trap.ts +2 -2
  154. package/template/src/hooks/useIntegrationNotifications.ts +49 -0
  155. package/template/src/lib/auth.ts +8 -1
  156. package/template/src/lib/config-links.ts +14 -0
  157. package/template/src/lib/contact-duplicate.ts +79 -61
  158. package/template/src/lib/contact-interactions.ts +21 -21
  159. package/template/src/lib/contact-view-filters.ts +24 -64
  160. package/template/src/lib/contacts-list-url.ts +190 -0
  161. package/template/src/lib/dashboard-stats.ts +65 -7
  162. package/template/src/lib/dashboard-themes.ts +135 -0
  163. package/template/src/lib/date-utils.ts +127 -0
  164. package/template/src/lib/default-widgets.ts +12 -0
  165. package/template/src/lib/editor-html-image-dimensions.ts +172 -0
  166. package/template/src/lib/editor-image-limits.ts +19 -0
  167. package/template/src/lib/email-html-sanitize.ts +19 -0
  168. package/template/src/lib/encryption.ts +9 -6
  169. package/template/src/lib/fr-geography.ts +192 -0
  170. package/template/src/lib/google-calendar-agenda.ts +201 -0
  171. package/template/src/lib/google-calendar.ts +255 -5
  172. package/template/src/lib/google-sheet-sync-jobs.ts +96 -0
  173. package/template/src/lib/google-sheet-sync-runner.ts +514 -0
  174. package/template/src/lib/integration-import-log.ts +21 -0
  175. package/template/src/lib/permissions.ts +40 -10
  176. package/template/src/lib/prisma.ts +4 -1
  177. package/template/src/lib/qstash.ts +65 -0
  178. package/template/src/lib/reminder-state-server.ts +80 -0
  179. package/template/src/lib/reminder-state.ts +29 -0
  180. package/template/src/lib/supabase-storage.ts +113 -0
  181. package/template/src/lib/template-variables.ts +164 -23
  182. package/template/src/lib/utils.ts +45 -0
  183. package/template/src/lib/widget-registry.ts +173 -0
  184. package/template/src/lib/workflow-executor.ts +16 -70
  185. package/template/src/proxy.ts +1 -0
  186. package/template/vercel.json +3 -10
  187. package/template/skills-lock.json +0 -25
  188. package/template/src/components/dashboard/dashboard-content.tsx +0 -79
  189. package/template/src/lib/google-drive.ts +0 -1101
  190. package/template/src/types/yousign.ts +0 -52
@@ -0,0 +1,173 @@
1
+ import {
2
+ Users,
3
+ TrendingUp,
4
+ CheckCircle2,
5
+ Clock,
6
+ BarChart3,
7
+ Activity,
8
+ PieChart,
9
+ ListTodo,
10
+ MessageSquare,
11
+ Target,
12
+ UserCheck,
13
+ } from 'lucide-react';
14
+ import type { LucideIcon } from 'lucide-react';
15
+
16
+ export interface WidgetDefinition {
17
+ type: string;
18
+ label: string;
19
+ description: string;
20
+ icon: LucideIcon;
21
+ category: 'stat' | 'chart' | 'list';
22
+ defaultW: number;
23
+ defaultH: number;
24
+ minW: number;
25
+ minH: number;
26
+ maxW?: number;
27
+ maxH?: number;
28
+ }
29
+
30
+ export const WIDGET_REGISTRY: WidgetDefinition[] = [
31
+ {
32
+ type: 'stat_total_contacts',
33
+ label: 'Total Contacts',
34
+ description: 'Nombre total de contacts dans le CRM',
35
+ icon: Users,
36
+ category: 'stat',
37
+ defaultW: 3,
38
+ defaultH: 2,
39
+ minW: 2,
40
+ minH: 2,
41
+ maxH: 2,
42
+ },
43
+ {
44
+ type: 'stat_new_contacts',
45
+ label: 'Nouveaux ce Mois',
46
+ description: 'Contacts créés durant le mois en cours',
47
+ icon: TrendingUp,
48
+ category: 'stat',
49
+ defaultW: 3,
50
+ defaultH: 2,
51
+ minW: 2,
52
+ minH: 2,
53
+ maxH: 2,
54
+ },
55
+ {
56
+ type: 'stat_completed_tasks',
57
+ label: 'Tâches Complétées',
58
+ description: 'Nombre de tâches terminées',
59
+ icon: CheckCircle2,
60
+ category: 'stat',
61
+ defaultW: 3,
62
+ defaultH: 2,
63
+ minW: 2,
64
+ minH: 2,
65
+ maxH: 2,
66
+ },
67
+ {
68
+ type: 'stat_pending_tasks',
69
+ label: 'Tâches en Attente',
70
+ description: 'Nombre de tâches en cours',
71
+ icon: Clock,
72
+ category: 'stat',
73
+ defaultW: 3,
74
+ defaultH: 2,
75
+ minW: 2,
76
+ minH: 2,
77
+ maxH: 2,
78
+ },
79
+ {
80
+ type: 'contacts_chart',
81
+ label: 'Évolution des Contacts',
82
+ description: "Graphique de l'évolution des contacts sur 12 mois",
83
+ icon: BarChart3,
84
+ category: 'chart',
85
+ defaultW: 6,
86
+ defaultH: 4,
87
+ minW: 4,
88
+ minH: 3,
89
+ },
90
+ {
91
+ type: 'activity_chart',
92
+ label: 'Activité 7 jours',
93
+ description: 'Activité des 7 derniers jours (interactions et tâches)',
94
+ icon: Activity,
95
+ category: 'chart',
96
+ defaultW: 8,
97
+ defaultH: 4,
98
+ minW: 4,
99
+ minH: 3,
100
+ },
101
+ {
102
+ type: 'status_distribution',
103
+ label: 'Répartition par Statut',
104
+ description: 'Distribution des contacts selon leur statut',
105
+ icon: Target,
106
+ category: 'chart',
107
+ defaultW: 6,
108
+ defaultH: 4,
109
+ minW: 4,
110
+ minH: 3,
111
+ },
112
+ {
113
+ type: 'tasks_pie',
114
+ label: 'Statut des Tâches',
115
+ description: 'Répartition complétées vs en attente',
116
+ icon: PieChart,
117
+ category: 'chart',
118
+ defaultW: 4,
119
+ defaultH: 4,
120
+ minW: 3,
121
+ minH: 3,
122
+ },
123
+ {
124
+ type: 'interactions_by_type',
125
+ label: 'Interactions par Type',
126
+ description: 'Répartition des interactions par type ce mois',
127
+ icon: MessageSquare,
128
+ category: 'chart',
129
+ defaultW: 6,
130
+ defaultH: 4,
131
+ minW: 4,
132
+ minH: 3,
133
+ },
134
+ {
135
+ type: 'upcoming_tasks',
136
+ label: 'Tâches à Venir',
137
+ description: 'Liste des prochaines tâches planifiées',
138
+ icon: ListTodo,
139
+ category: 'list',
140
+ defaultW: 6,
141
+ defaultH: 5,
142
+ minW: 4,
143
+ minH: 3,
144
+ },
145
+ {
146
+ type: 'recent_activity',
147
+ label: 'Activité Récente',
148
+ description: 'Dernières interactions avec les contacts',
149
+ icon: Activity,
150
+ category: 'list',
151
+ defaultW: 6,
152
+ defaultH: 5,
153
+ minW: 4,
154
+ minH: 3,
155
+ },
156
+ {
157
+ type: 'top_contacts',
158
+ label: 'Derniers Prospects',
159
+ description: 'Tableau des derniers contacts ajoutés',
160
+ icon: UserCheck,
161
+ category: 'list',
162
+ defaultW: 6,
163
+ defaultH: 4,
164
+ minW: 4,
165
+ minH: 3,
166
+ },
167
+ ];
168
+
169
+ export function getWidgetDefinition(type: string): WidgetDefinition | undefined {
170
+ return WIDGET_REGISTRY.find((w) => w.type === type);
171
+ }
172
+
173
+ export { DEFAULT_WIDGETS } from './default-widgets';
@@ -21,10 +21,15 @@ const WORKFLOW_INCLUDE = {
21
21
 
22
22
  const CONTACT_INCLUDE = {
23
23
  status: true,
24
- company: { select: { name: true, id: true } },
24
+ company: { select: { name: true, id: true, address: true, city: true, postalCode: true } },
25
+ assignedCommercial: { select: { name: true } },
26
+ assignedTelepro: { select: { name: true } },
25
27
  };
26
28
 
27
- function getContactVariables(contact: any) {
29
+ export function getContactVariables(contact: any) {
30
+ const commercialName = contact.assignedCommercial?.name || '';
31
+ const teleproName = contact.assignedTelepro?.name || '';
32
+
28
33
  return {
29
34
  firstName: contact.firstName || '',
30
35
  lastName: contact.lastName || '',
@@ -36,6 +41,15 @@ function getContactVariables(contact: any) {
36
41
  city: contact.city || '',
37
42
  postalCode: contact.postalCode || '',
38
43
  companyName: contact.company?.name || '',
44
+ company: contact.company || null,
45
+ jobTitle: contact.jobTitle || '',
46
+ website: contact.website || '',
47
+ origin: contact.origin || '',
48
+ statusName: contact.status?.name || '',
49
+ assignedCommercialName: commercialName,
50
+ assignedTeleproName: teleproName,
51
+ closingReason: contact.closingReason || '',
52
+ createdAt: contact.createdAt || null,
39
53
  };
40
54
  }
41
55
 
@@ -134,74 +148,6 @@ export async function executeWorkflowsOnTaskCompleted(contactId: string, taskTyp
134
148
  }
135
149
  }
136
150
 
137
- /**
138
- * Exécute les workflows déclenchés par la création d'une transaction
139
- */
140
- export async function executeWorkflowsOnTransactionCreated(contactId: string) {
141
- try {
142
- const workflows = await prisma.workflow.findMany({
143
- where: { active: true, triggerType: 'TRANSACTION_CREATED' },
144
- include: WORKFLOW_INCLUDE,
145
- });
146
-
147
- const contact = await prisma.contact.findUnique({
148
- where: { id: contactId },
149
- include: CONTACT_INCLUDE,
150
- });
151
-
152
- if (!contact) return;
153
-
154
- for (const workflow of workflows) {
155
- await executeWorkflowActions(workflow, contactId, contact);
156
- }
157
- } catch (error) {
158
- console.error("Erreur lors de l'exécution des workflows pour transaction créée:", error);
159
- }
160
- }
161
-
162
- /**
163
- * Exécute les workflows déclenchés par un changement de statut de transaction
164
- */
165
- export async function executeWorkflowsOnTransactionStatusChanged(
166
- contactId: string,
167
- oldStatus: string | null,
168
- newStatus: string,
169
- ) {
170
- try {
171
- const workflows = await prisma.workflow.findMany({
172
- where: { active: true, triggerType: 'TRANSACTION_STATUS_CHANGED' },
173
- include: WORKFLOW_INCLUDE,
174
- });
175
-
176
- const contact = await prisma.contact.findUnique({
177
- where: { id: contactId },
178
- include: CONTACT_INCLUDE,
179
- });
180
-
181
- if (!contact) return;
182
-
183
- const matchingWorkflows = workflows.filter((workflow) => {
184
- if (
185
- workflow.triggerTransactionFromStatus &&
186
- oldStatus !== workflow.triggerTransactionFromStatus
187
- )
188
- return false;
189
- if (workflow.triggerTransactionToStatus && newStatus !== workflow.triggerTransactionToStatus)
190
- return false;
191
- return true;
192
- });
193
-
194
- for (const workflow of matchingWorkflows) {
195
- await executeWorkflowActions(workflow, contactId, contact);
196
- }
197
- } catch (error) {
198
- console.error(
199
- "Erreur lors de l'exécution des workflows pour changement de statut de transaction:",
200
- error,
201
- );
202
- }
203
- }
204
-
205
151
  /**
206
152
  * Exécute les workflows déclenchés par un changement d'assignation
207
153
  */
@@ -8,6 +8,7 @@ const PUBLIC_API_PREFIXES = [
8
8
  '/api/auth',
9
9
  '/api/webhooks',
10
10
  '/api/cron',
11
+ '/api/jobs',
11
12
  '/api/invite',
12
13
  '/api/reset-password',
13
14
  '/api/email/track',
@@ -1,20 +1,13 @@
1
1
  {
2
+ "buildCommand": "pnpm db:prepare:prod && pnpm build",
2
3
  "crons": [
3
4
  {
4
5
  "path": "/api/workflows/process",
5
6
  "schedule": "* * * * *"
6
7
  },
7
8
  {
8
- "path": "/api/cron/init-holidays",
9
- "schedule": "0 0 1 1 *"
10
- },
11
- {
12
- "path": "/api/cron/complete-transactions",
13
- "schedule": "0 */6 * * *"
14
- },
15
- {
16
- "path": "/api/cron/place-reminders",
17
- "schedule": "0 9 * * *"
9
+ "path": "/api/cron/cleanup-editor-images",
10
+ "schedule": "0 3 * * *"
18
11
  }
19
12
  ]
20
13
  }
@@ -1,25 +0,0 @@
1
- {
2
- "version": 1,
3
- "skills": {
4
- "frontend-design": {
5
- "source": "anthropics/skills",
6
- "sourceType": "github",
7
- "computedHash": "063a0e6448123cd359ad0044cc46b0e490cc7964d45ef4bb9fd842bd2ffbca67"
8
- },
9
- "supabase-postgres-best-practices": {
10
- "source": "supabase/agent-skills",
11
- "sourceType": "github",
12
- "computedHash": "9c87c315aed143ee3b34bec8117100f5035e0df09e6b23e1ecc772cff434c9ad"
13
- },
14
- "vercel-react-best-practices": {
15
- "source": "vercel-labs/agent-skills",
16
- "sourceType": "github",
17
- "computedHash": "3462ec83f862abb2d532953df33a4dbf87f4616849da5d4b5cc7c13601aaf997"
18
- },
19
- "web-design-guidelines": {
20
- "source": "vercel-labs/agent-skills",
21
- "sourceType": "github",
22
- "computedHash": "a6a44d5498f7e8f68289902f3dedfc6f38ae0cee1e96527c80724cf27f727c2a"
23
- }
24
- }
25
- }
@@ -1,79 +0,0 @@
1
- 'use client';
2
-
3
- import dynamic from 'next/dynamic';
4
- import { Users, CheckCircle2, Clock, TrendingUp } from 'lucide-react';
5
- import { StatCard } from '@/components/dashboard/stat-card';
6
- import { UpcomingTasksList } from '@/components/dashboard/upcoming-tasks-list';
7
- import { PageHeader } from '@/components/page-header';
8
- import { ProtectedPage } from '@/components/protected-page';
9
- import { Skeleton } from '@/components/skeleton';
10
- import type { DashboardStats } from '@/lib/dashboard-stats';
11
-
12
- const ActivityChart = dynamic(
13
- () => import('@/components/dashboard/activity-chart').then((m) => m.ActivityChart),
14
- { ssr: false, loading: () => <Skeleton className="h-80 rounded-lg" /> },
15
- );
16
- const TasksPieChart = dynamic(
17
- () => import('@/components/dashboard/tasks-pie-chart').then((m) => m.TasksPieChart),
18
- { ssr: false, loading: () => <Skeleton className="h-80 rounded-lg" /> },
19
- );
20
-
21
- interface DashboardContentProps {
22
- stats: DashboardStats;
23
- }
24
-
25
- export function DashboardContent({ stats }: Readonly<DashboardContentProps>) {
26
- return (
27
- <ProtectedPage requiredPermission="analytics.view">
28
- <div className="h-full">
29
- <PageHeader title="Tableau de Bord" description="Vue d'ensemble de votre activité" />
30
-
31
- <div className="space-y-6 p-4 sm:p-6">
32
- <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
33
- <StatCard
34
- title="Total Contacts"
35
- value={stats.overview.totalContacts.toLocaleString('fr-FR')}
36
- icon={Users}
37
- trend={{
38
- value: stats.overview.contactsGrowth,
39
- label: 'ce mois',
40
- }}
41
- iconColor="text-primary"
42
- iconBgColor="bg-primary/15"
43
- />
44
- <StatCard
45
- title="Nouveaux ce Mois"
46
- value={stats.overview.contactsThisMonth.toLocaleString('fr-FR')}
47
- icon={TrendingUp}
48
- iconColor="text-green-600"
49
- iconBgColor="bg-green-100"
50
- />
51
- <StatCard
52
- title="Tâches Complétées"
53
- value={stats.tasks.completed.toLocaleString('fr-FR')}
54
- icon={CheckCircle2}
55
- iconColor="text-emerald-600"
56
- iconBgColor="bg-emerald-100"
57
- />
58
- <StatCard
59
- title="Tâches en Attente"
60
- value={stats.tasks.pending.toLocaleString('fr-FR')}
61
- icon={Clock}
62
- iconColor="text-blue-600"
63
- iconBgColor="bg-blue-100"
64
- />
65
- </div>
66
-
67
- <div className="grid gap-6 lg:grid-cols-3">
68
- <div className="lg:col-span-2">
69
- <ActivityChart data={stats.activity.last7Days} />
70
- </div>
71
- <TasksPieChart completed={stats.tasks.completed} pending={stats.tasks.pending} />
72
- </div>
73
-
74
- <UpcomingTasksList tasks={stats.tasks.upcoming} />
75
- </div>
76
- </div>
77
- </ProtectedPage>
78
- );
79
- }