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.
- package/bin/create-crm-tmp.js +56 -35
- package/package.json +1 -1
- package/template/README.md +230 -115
- package/template/eslint.config.mjs +13 -0
- package/template/next.config.ts +14 -0
- package/template/package.json +15 -2
- package/template/prisma/migrations/20260318095700_init_db/migration.sql +978 -0
- package/template/prisma/migrations/migration_lock.toml +3 -0
- package/template/prisma/schema.prisma +132 -637
- package/template/src/app/(auth)/invite/[token]/page.tsx +10 -8
- package/template/src/app/(auth)/layout.tsx +1 -1
- package/template/src/app/(auth)/reset-password/complete/page.tsx +11 -8
- package/template/src/app/(auth)/reset-password/page.tsx +4 -4
- package/template/src/app/(auth)/reset-password/verify/page.tsx +4 -4
- package/template/src/app/(auth)/signin/page.tsx +14 -6
- package/template/src/app/(dashboard)/agenda/page.tsx +2243 -988
- package/template/src/app/(dashboard)/automatisation/_components/workflow-editor.tsx +18 -104
- package/template/src/app/(dashboard)/automatisation/page.tsx +10 -26
- package/template/src/app/(dashboard)/closing/page.tsx +78 -62
- package/template/src/app/(dashboard)/contacts/[id]/page.tsx +2082 -1080
- package/template/src/app/(dashboard)/contacts/companies/[id]/page.tsx +46 -47
- package/template/src/app/(dashboard)/contacts/page.tsx +1062 -780
- package/template/src/app/(dashboard)/dashboard/page.tsx +533 -37
- package/template/src/app/(dashboard)/dev/page.tsx +1291 -0
- package/template/src/app/(dashboard)/layout.tsx +6 -2
- package/template/src/app/(dashboard)/settings/page.tsx +797 -2582
- package/template/src/app/(dashboard)/templates/page.tsx +55 -54
- package/template/src/app/(dashboard)/users/list/page.tsx +51 -48
- package/template/src/app/(dashboard)/users/page.tsx +1 -1
- package/template/src/app/(dashboard)/users/permissions/page.tsx +2 -2
- package/template/src/app/(dashboard)/users/roles/page.tsx +7 -5
- package/template/src/app/api/agenda/google-events/route.ts +92 -0
- package/template/src/app/api/auth/check-active/route.ts +3 -2
- package/template/src/app/api/auth/google/route.ts +2 -1
- package/template/src/app/api/auth/google/status/route.ts +7 -31
- package/template/src/app/api/companies/[id]/activities/route.ts +1 -3
- package/template/src/app/api/companies/[id]/route.ts +1 -2
- package/template/src/app/api/companies/route.ts +42 -12
- package/template/src/app/api/contacts/[id]/files/[fileId]/preview/route.ts +9 -31
- package/template/src/app/api/contacts/[id]/files/[fileId]/route.ts +14 -32
- package/template/src/app/api/contacts/[id]/files/route.ts +112 -212
- package/template/src/app/api/contacts/[id]/interactions/[interactionId]/route.ts +27 -1
- package/template/src/app/api/contacts/[id]/interactions/route.ts +16 -16
- package/template/src/app/api/contacts/[id]/kyc/route.ts +21 -11
- package/template/src/app/api/contacts/[id]/meet/route.ts +19 -2
- package/template/src/app/api/contacts/[id]/route.ts +106 -34
- package/template/src/app/api/contacts/[id]/send-email/route.ts +27 -11
- package/template/src/app/api/contacts/[id]/workflows/run/route.ts +6 -0
- package/template/src/app/api/contacts/export/route.ts +9 -13
- package/template/src/app/api/contacts/import/route.ts +55 -25
- package/template/src/app/api/contacts/import-preview/route.ts +1 -1
- package/template/src/app/api/contacts/origins/route.ts +63 -0
- package/template/src/app/api/contacts/route.ts +153 -41
- package/template/src/app/api/cron/cleanup-editor-images/route.ts +166 -0
- package/template/src/app/api/dashboard/widgets/[id]/route.ts +44 -0
- package/template/src/app/api/dashboard/widgets/route.ts +181 -0
- package/template/src/app/api/dev/reminders/test/route.ts +114 -0
- package/template/src/app/api/editor/upload-image/route.ts +61 -0
- package/template/src/app/api/integrations/google-sheet/jobs/[jobId]/route.ts +47 -0
- package/template/src/app/api/integrations/google-sheet/jobs/usage/route.ts +50 -0
- package/template/src/app/api/integrations/google-sheet/sync/route.ts +24 -556
- package/template/src/app/api/jobs/google-sheet/process/route.ts +84 -0
- package/template/src/app/api/jobs/google-sheet/schedule/route.ts +50 -0
- package/template/src/app/api/reminders/clear/route.ts +120 -0
- package/template/src/app/api/reminders/clear/undo/route.ts +112 -0
- package/template/src/app/api/reminders/route.ts +164 -39
- package/template/src/app/api/reminders/state/route.ts +164 -0
- package/template/src/app/api/reset-password/request/route.ts +1 -1
- package/template/src/app/api/reset-password/verify/route.ts +1 -1
- package/template/src/app/api/send/route.ts +16 -4
- package/template/src/app/api/settings/google-ads/route.ts +14 -0
- package/template/src/app/api/settings/google-calendar/calendars/route.ts +97 -0
- package/template/src/app/api/settings/google-calendar/route.ts +124 -0
- package/template/src/app/api/settings/google-sheet/[id]/route.ts +28 -0
- package/template/src/app/api/settings/google-sheet/auto-map/route.ts +37 -4
- package/template/src/app/api/settings/google-sheet/preview/route.ts +9 -3
- package/template/src/app/api/settings/google-sheet/route.ts +14 -0
- package/template/src/app/api/settings/integrations/logs/route.ts +93 -0
- package/template/src/app/api/settings/integrations/notifications/route.ts +67 -0
- package/template/src/app/api/settings/meta-leads/[id]/route.ts +0 -1
- package/template/src/app/api/settings/meta-leads/route.ts +14 -2
- package/template/src/app/api/settings/smtp/route.ts +53 -6
- package/template/src/app/api/tasks/[id]/attendees/route.ts +24 -8
- package/template/src/app/api/tasks/[id]/route.ts +234 -58
- package/template/src/app/api/tasks/meet/route.ts +27 -19
- package/template/src/app/api/tasks/route.ts +62 -17
- package/template/src/app/api/users/[id]/route.ts +20 -14
- package/template/src/app/api/users/list/route.ts +57 -19
- package/template/src/app/api/webhooks/google-ads/route.ts +34 -14
- package/template/src/app/api/webhooks/meta-leads/route.ts +32 -12
- package/template/src/app/api/workflows/[id]/route.ts +0 -4
- package/template/src/app/api/workflows/process/route.ts +22 -51
- package/template/src/app/api/workflows/route.ts +0 -4
- package/template/src/app/globals.css +342 -4
- package/template/src/app/layout.tsx +11 -3
- package/template/src/app/page.tsx +1 -1
- package/template/src/components/address-autocomplete.tsx +7 -6
- package/template/src/components/config-error-alert.tsx +46 -0
- package/template/src/components/contacts/filter-bar.tsx +12 -3
- package/template/src/components/contacts/filter-builder.tsx +28 -43
- package/template/src/components/contacts/save-view-dialog.tsx +1 -1
- package/template/src/components/contacts/views-tab-bar.tsx +15 -6
- package/template/src/components/dashboard/activity-chart.tsx +41 -28
- package/template/src/components/dashboard/add-widget-dialog.tsx +157 -0
- package/template/src/components/dashboard/color-picker.tsx +64 -0
- package/template/src/components/dashboard/contacts-chart.tsx +69 -0
- package/template/src/components/dashboard/interactions-by-type-chart.tsx +121 -0
- package/template/src/components/dashboard/recent-activity.tsx +154 -0
- package/template/src/components/dashboard/stat-card.tsx +40 -40
- package/template/src/components/dashboard/status-distribution-chart.tsx +81 -0
- package/template/src/components/dashboard/tasks-pie-chart.tsx +37 -34
- package/template/src/components/dashboard/top-contacts-list.tsx +113 -0
- package/template/src/components/dashboard/upcoming-tasks-list.tsx +72 -81
- package/template/src/components/dashboard/widget-wrapper.tsx +36 -0
- package/template/src/components/date-picker.tsx +9 -6
- package/template/src/components/editor/upload-editor-image.ts +42 -0
- package/template/src/components/editor.tsx +161 -22
- package/template/src/components/email-template.tsx +2 -2
- package/template/src/components/global-search.tsx +30 -28
- package/template/src/components/header.tsx +178 -80
- package/template/src/components/inactive-account-guard.tsx +58 -0
- package/template/src/components/integration-notifications-listener.tsx +12 -0
- package/template/src/components/invitation-email-template.tsx +2 -2
- package/template/src/components/meet-cancellation-email-template.tsx +3 -3
- package/template/src/components/meet-confirmation-email-template.tsx +3 -3
- package/template/src/components/meet-update-email-template.tsx +3 -3
- package/template/src/components/page-header.tsx +5 -5
- package/template/src/components/protected-page.tsx +1 -1
- package/template/src/components/reset-password-email-template.tsx +2 -2
- package/template/src/components/settings/integrations/GoogleAdsIntegration.tsx +428 -0
- package/template/src/components/settings/integrations/GoogleSheetConfigMonitoringModal.tsx +680 -0
- package/template/src/components/settings/integrations/GoogleSheetIntegration.tsx +809 -0
- package/template/src/components/settings/integrations/ImportResultDialog.tsx +124 -0
- package/template/src/components/settings/integrations/IntegrationLogPanel.tsx +57 -0
- package/template/src/components/settings/integrations/IntegrationLogsTable.tsx +186 -0
- package/template/src/components/settings/integrations/MetaLeadIntegration.tsx +451 -0
- package/template/src/components/sidebar.tsx +45 -26
- package/template/src/components/skeleton.tsx +40 -43
- package/template/src/components/ui/accordion.tsx +2 -2
- package/template/src/components/ui/alert-dialog.tsx +1 -1
- package/template/src/components/ui/button.tsx +20 -9
- package/template/src/components/ui/components.tsx +1 -1
- package/template/src/components/ui/date-picker.tsx +422 -0
- package/template/src/components/ui/datetime-picker.tsx +338 -0
- package/template/src/components/ui/status-select.tsx +271 -0
- package/template/src/components/ui/tooltip.tsx +37 -0
- package/template/src/components/view-as-modal.tsx +13 -7
- package/template/src/contexts/app-toast-context.tsx +245 -57
- package/template/src/contexts/dashboard-theme-context.tsx +53 -0
- package/template/src/contexts/sidebar-context.tsx +22 -17
- package/template/src/contexts/task-reminder-context.tsx +134 -160
- package/template/src/contexts/view-as-context.tsx +33 -6
- package/template/src/hooks/use-focus-trap.ts +2 -2
- package/template/src/hooks/useIntegrationNotifications.ts +49 -0
- package/template/src/lib/auth.ts +8 -1
- package/template/src/lib/config-links.ts +14 -0
- package/template/src/lib/contact-duplicate.ts +79 -61
- package/template/src/lib/contact-interactions.ts +21 -21
- package/template/src/lib/contact-view-filters.ts +24 -64
- package/template/src/lib/contacts-list-url.ts +190 -0
- package/template/src/lib/dashboard-stats.ts +65 -7
- package/template/src/lib/dashboard-themes.ts +135 -0
- package/template/src/lib/date-utils.ts +127 -0
- package/template/src/lib/default-widgets.ts +12 -0
- package/template/src/lib/editor-html-image-dimensions.ts +172 -0
- package/template/src/lib/editor-image-limits.ts +19 -0
- package/template/src/lib/email-html-sanitize.ts +19 -0
- package/template/src/lib/encryption.ts +9 -6
- package/template/src/lib/fr-geography.ts +192 -0
- package/template/src/lib/google-calendar-agenda.ts +201 -0
- package/template/src/lib/google-calendar.ts +255 -5
- package/template/src/lib/google-sheet-sync-jobs.ts +96 -0
- package/template/src/lib/google-sheet-sync-runner.ts +514 -0
- package/template/src/lib/integration-import-log.ts +21 -0
- package/template/src/lib/permissions.ts +40 -10
- package/template/src/lib/prisma.ts +4 -1
- package/template/src/lib/qstash.ts +65 -0
- package/template/src/lib/reminder-state-server.ts +80 -0
- package/template/src/lib/reminder-state.ts +29 -0
- package/template/src/lib/supabase-storage.ts +113 -0
- package/template/src/lib/template-variables.ts +164 -23
- package/template/src/lib/utils.ts +45 -0
- package/template/src/lib/widget-registry.ts +173 -0
- package/template/src/lib/workflow-executor.ts +16 -70
- package/template/src/proxy.ts +1 -0
- package/template/vercel.json +3 -10
- package/template/skills-lock.json +0 -25
- package/template/src/components/dashboard/dashboard-content.tsx +0 -79
- package/template/src/lib/google-drive.ts +0 -1101
- 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
|
*/
|
package/template/src/proxy.ts
CHANGED
package/template/vercel.json
CHANGED
|
@@ -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/
|
|
9
|
-
"schedule": "0
|
|
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
|
-
}
|