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
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
StickyNote,
|
|
15
15
|
Bell,
|
|
16
16
|
} from 'lucide-react';
|
|
17
|
-
import { cn } from '@/lib/utils';
|
|
17
|
+
import { cn, devToast } from '@/lib/utils';
|
|
18
18
|
import { useAppToast } from '@/contexts/app-toast-context';
|
|
19
|
+
import { StatusSelect } from '@/components/ui/status-select';
|
|
19
20
|
|
|
20
21
|
interface Status {
|
|
21
22
|
id: string;
|
|
@@ -51,8 +52,6 @@ type TriggerType =
|
|
|
51
52
|
| 'TIME_BASED'
|
|
52
53
|
| 'MANUAL'
|
|
53
54
|
| 'TASK_COMPLETED'
|
|
54
|
-
| 'TRANSACTION_CREATED'
|
|
55
|
-
| 'TRANSACTION_STATUS_CHANGED'
|
|
56
55
|
| 'CONTACT_ASSIGNMENT_CHANGED';
|
|
57
56
|
|
|
58
57
|
export interface WorkflowAction {
|
|
@@ -91,8 +90,6 @@ export interface WorkflowEditorInitialData {
|
|
|
91
90
|
triggerTimeHours: number | null;
|
|
92
91
|
triggerTimeReference: string | null;
|
|
93
92
|
triggerTaskType: string | null;
|
|
94
|
-
triggerTransactionFromStatus: string | null;
|
|
95
|
-
triggerTransactionToStatus: string | null;
|
|
96
93
|
actions: WorkflowAction[];
|
|
97
94
|
}
|
|
98
95
|
|
|
@@ -100,21 +97,6 @@ interface WorkflowEditorProps {
|
|
|
100
97
|
workflowId?: string;
|
|
101
98
|
}
|
|
102
99
|
|
|
103
|
-
const TRANSACTION_STATUSES = [
|
|
104
|
-
{ value: 'DRAFT', label: 'Brouillon' },
|
|
105
|
-
{ value: 'PENDING_ID_VERIFICATION', label: 'Vérification identité' },
|
|
106
|
-
{ value: 'ID_VERIFIED', label: 'Identité vérifiée' },
|
|
107
|
-
{ value: 'ITEMS_ENTERED', label: 'Articles saisis' },
|
|
108
|
-
{ value: 'PENDING_SIGNATURE', label: 'En attente de signature' },
|
|
109
|
-
{ value: 'SIGNED', label: 'Signée' },
|
|
110
|
-
{ value: 'LOCKED', label: 'Verrouillée' },
|
|
111
|
-
{ value: 'PAYMENT_PENDING', label: 'Paiement en attente' },
|
|
112
|
-
{ value: 'COMPLETED', label: 'Complétée' },
|
|
113
|
-
{ value: 'PENDING_RETRACTION', label: 'Rétractation en attente' },
|
|
114
|
-
{ value: 'CANCELLED_RETRACTION', label: 'Rétractation annulée' },
|
|
115
|
-
{ value: 'CANCELLED', label: 'Annulée' },
|
|
116
|
-
];
|
|
117
|
-
|
|
118
100
|
const TASK_TYPES = [
|
|
119
101
|
{ value: '', label: 'Tous les types' },
|
|
120
102
|
{ value: 'CALL', label: 'Appel' },
|
|
@@ -164,8 +146,6 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
164
146
|
triggerTimeHours: null,
|
|
165
147
|
triggerTimeReference: null,
|
|
166
148
|
triggerTaskType: null,
|
|
167
|
-
triggerTransactionFromStatus: null,
|
|
168
|
-
triggerTransactionToStatus: null,
|
|
169
149
|
actions: [],
|
|
170
150
|
});
|
|
171
151
|
|
|
@@ -204,13 +184,11 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
204
184
|
triggerTimeHours: data.triggerTimeHours,
|
|
205
185
|
triggerTimeReference: data.triggerTimeReference,
|
|
206
186
|
triggerTaskType: data.triggerTaskType,
|
|
207
|
-
triggerTransactionFromStatus: data.triggerTransactionFromStatus,
|
|
208
|
-
triggerTransactionToStatus: data.triggerTransactionToStatus,
|
|
209
187
|
actions: data.actions,
|
|
210
188
|
});
|
|
211
189
|
setActions(data.actions || []);
|
|
212
190
|
} catch (err: any) {
|
|
213
|
-
setError(
|
|
191
|
+
setError(devToast('Erreur lors du chargement du workflow', err));
|
|
214
192
|
} finally {
|
|
215
193
|
setLoading(false);
|
|
216
194
|
}
|
|
@@ -313,8 +291,6 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
313
291
|
triggerTimeHours: formData.triggerTimeHours || null,
|
|
314
292
|
triggerTimeReference: formData.triggerTimeReference || null,
|
|
315
293
|
triggerTaskType: formData.triggerTaskType || null,
|
|
316
|
-
triggerTransactionFromStatus: formData.triggerTransactionFromStatus || null,
|
|
317
|
-
triggerTransactionToStatus: formData.triggerTransactionToStatus || null,
|
|
318
294
|
actions: actions.map((action, index) => ({
|
|
319
295
|
...action,
|
|
320
296
|
order: index,
|
|
@@ -333,7 +309,7 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
333
309
|
|
|
334
310
|
router.push('/automatisation');
|
|
335
311
|
} catch (err: any) {
|
|
336
|
-
setError(
|
|
312
|
+
setError(devToast('Erreur lors de la sauvegarde du workflow', err));
|
|
337
313
|
} finally {
|
|
338
314
|
setSaving(false);
|
|
339
315
|
}
|
|
@@ -418,10 +394,6 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
418
394
|
return 'Déclencheur manuel';
|
|
419
395
|
case 'TASK_COMPLETED':
|
|
420
396
|
return 'Tâche complétée';
|
|
421
|
-
case 'TRANSACTION_CREATED':
|
|
422
|
-
return 'Transaction créée';
|
|
423
|
-
case 'TRANSACTION_STATUS_CHANGED':
|
|
424
|
-
return 'Changement de statut de transaction';
|
|
425
397
|
case 'CONTACT_ASSIGNMENT_CHANGED':
|
|
426
398
|
return "Changement d'assignation";
|
|
427
399
|
default:
|
|
@@ -430,9 +402,9 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
430
402
|
};
|
|
431
403
|
|
|
432
404
|
const selectClass =
|
|
433
|
-
'mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus:
|
|
405
|
+
'mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50';
|
|
434
406
|
const selectClassSm =
|
|
435
|
-
'mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm text-gray-900 focus:
|
|
407
|
+
'mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50';
|
|
436
408
|
const inputClassSm = selectClassSm;
|
|
437
409
|
|
|
438
410
|
const renderActionConfig = (action: WorkflowAction, index: number) => {
|
|
@@ -675,25 +647,21 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
675
647
|
conditionOperator: (e.target.value as 'EQUALS' | 'NOT_EQUALS') || null,
|
|
676
648
|
})
|
|
677
649
|
}
|
|
678
|
-
className="block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus:
|
|
650
|
+
className="block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50"
|
|
679
651
|
>
|
|
680
652
|
<option value="">Pas de condition statut</option>
|
|
681
653
|
<option value="EQUALS">Statut est égal à</option>
|
|
682
654
|
<option value="NOT_EQUALS">Statut n'est pas égal à</option>
|
|
683
655
|
</select>
|
|
684
656
|
{action.conditionOperator && (
|
|
685
|
-
<
|
|
657
|
+
<StatusSelect
|
|
658
|
+
statuses={statuses}
|
|
686
659
|
value={action.conditionStatusId || ''}
|
|
687
|
-
onChange={(
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
<option key={s.id} value={s.id}>
|
|
693
|
-
{s.name}
|
|
694
|
-
</option>
|
|
695
|
-
))}
|
|
696
|
-
</select>
|
|
660
|
+
onChange={(value) => updateAction(index, { conditionStatusId: value || null })}
|
|
661
|
+
placeholder="Sélectionner..."
|
|
662
|
+
className="block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50"
|
|
663
|
+
size="sm"
|
|
664
|
+
/>
|
|
697
665
|
)}
|
|
698
666
|
</div>
|
|
699
667
|
|
|
@@ -703,7 +671,7 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
703
671
|
type="text"
|
|
704
672
|
value={action.conditionOrigin || ''}
|
|
705
673
|
onChange={(e) => updateAction(index, { conditionOrigin: e.target.value || null })}
|
|
706
|
-
className="block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus:
|
|
674
|
+
className="block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50"
|
|
707
675
|
placeholder="Origine du contact (laisser vide pour ignorer)"
|
|
708
676
|
/>
|
|
709
677
|
</div>
|
|
@@ -724,7 +692,7 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
724
692
|
conditionHasCompany: val === 'true' ? true : val === 'false' ? false : null,
|
|
725
693
|
});
|
|
726
694
|
}}
|
|
727
|
-
className="block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus:
|
|
695
|
+
className="block w-full rounded-lg border border-gray-300 px-3 py-2 text-xs text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50"
|
|
728
696
|
>
|
|
729
697
|
<option value="">Société : indifférent</option>
|
|
730
698
|
<option value="true">A une société</option>
|
|
@@ -985,9 +953,7 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
985
953
|
onClick={() => setFormData((prev) => ({ ...prev, active: !prev.active }))}
|
|
986
954
|
className={cn(
|
|
987
955
|
'relative inline-flex h-6 w-11 cursor-pointer items-center rounded-full border transition-colors',
|
|
988
|
-
formData.active
|
|
989
|
-
? 'border-blue-500 bg-blue-500'
|
|
990
|
-
: 'border-gray-300 bg-gray-200',
|
|
956
|
+
formData.active ? 'border-blue-500 bg-blue-500' : 'border-gray-300 bg-gray-200',
|
|
991
957
|
)}
|
|
992
958
|
>
|
|
993
959
|
<span
|
|
@@ -1020,10 +986,6 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
1020
986
|
<option value="STATUS_CHANGED">Changement de statut</option>
|
|
1021
987
|
<option value="TIME_BASED">Basé sur le temps</option>
|
|
1022
988
|
<option value="TASK_COMPLETED">Tâche complétée</option>
|
|
1023
|
-
<option value="TRANSACTION_CREATED">Transaction créée</option>
|
|
1024
|
-
<option value="TRANSACTION_STATUS_CHANGED">
|
|
1025
|
-
Changement de statut de transaction
|
|
1026
|
-
</option>
|
|
1027
989
|
<option value="CONTACT_ASSIGNMENT_CHANGED">Changement d'assignation</option>
|
|
1028
990
|
<option value="MANUAL">Déclencheur manuel</option>
|
|
1029
991
|
</select>
|
|
@@ -1162,54 +1124,6 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
1162
1124
|
</select>
|
|
1163
1125
|
</div>
|
|
1164
1126
|
)}
|
|
1165
|
-
|
|
1166
|
-
{/* TRANSACTION_STATUS_CHANGED config */}
|
|
1167
|
-
{formData.triggerType === 'TRANSACTION_STATUS_CHANGED' && (
|
|
1168
|
-
<div className="grid gap-3 md:grid-cols-2">
|
|
1169
|
-
<div>
|
|
1170
|
-
<label className="block text-xs font-medium text-gray-700">
|
|
1171
|
-
Du statut (optionnel)
|
|
1172
|
-
</label>
|
|
1173
|
-
<select
|
|
1174
|
-
value={formData.triggerTransactionFromStatus ?? ''}
|
|
1175
|
-
onChange={(e) =>
|
|
1176
|
-
setFormData((prev) => ({
|
|
1177
|
-
...prev,
|
|
1178
|
-
triggerTransactionFromStatus: e.target.value || null,
|
|
1179
|
-
}))
|
|
1180
|
-
}
|
|
1181
|
-
className={selectClassSm}
|
|
1182
|
-
>
|
|
1183
|
-
<option value="">Tous les statuts</option>
|
|
1184
|
-
{TRANSACTION_STATUSES.map((s) => (
|
|
1185
|
-
<option key={s.value} value={s.value}>
|
|
1186
|
-
{s.label}
|
|
1187
|
-
</option>
|
|
1188
|
-
))}
|
|
1189
|
-
</select>
|
|
1190
|
-
</div>
|
|
1191
|
-
<div>
|
|
1192
|
-
<label className="block text-xs font-medium text-gray-700">Vers le statut</label>
|
|
1193
|
-
<select
|
|
1194
|
-
value={formData.triggerTransactionToStatus ?? ''}
|
|
1195
|
-
onChange={(e) =>
|
|
1196
|
-
setFormData((prev) => ({
|
|
1197
|
-
...prev,
|
|
1198
|
-
triggerTransactionToStatus: e.target.value || null,
|
|
1199
|
-
}))
|
|
1200
|
-
}
|
|
1201
|
-
className={selectClassSm}
|
|
1202
|
-
>
|
|
1203
|
-
<option value="">Tous les statuts</option>
|
|
1204
|
-
{TRANSACTION_STATUSES.map((s) => (
|
|
1205
|
-
<option key={s.value} value={s.value}>
|
|
1206
|
-
{s.label}
|
|
1207
|
-
</option>
|
|
1208
|
-
))}
|
|
1209
|
-
</select>
|
|
1210
|
-
</div>
|
|
1211
|
-
</div>
|
|
1212
|
-
)}
|
|
1213
1127
|
</div>
|
|
1214
1128
|
|
|
1215
1129
|
<div className="flex flex-col gap-2 pt-2 sm:flex-row sm:justify-end">
|
|
@@ -1223,7 +1137,7 @@ export function WorkflowEditor({ workflowId }: WorkflowEditorProps) {
|
|
|
1223
1137
|
<button
|
|
1224
1138
|
type="submit"
|
|
1225
1139
|
disabled={saving || loading}
|
|
1226
|
-
className="w-full cursor-pointer rounded-xl bg-blue-600 px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-colors hover:bg-blue-700 focus:ring-2 focus:ring-gray-400/30 focus:ring-offset-2 focus:outline-none disabled:cursor-not-allowed disabled:bg-blue-400 sm:w-auto"
|
|
1140
|
+
className="w-full cursor-pointer rounded-xl bg-blue-600 px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-colors hover:bg-blue-700 focus:ring-2 focus:ring-gray-400/30 focus:ring-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-blue-400 sm:w-auto"
|
|
1227
1141
|
>
|
|
1228
1142
|
{saving ? 'Enregistrement...' : 'Enregistrer le workflow'}
|
|
1229
1143
|
</button>
|
|
@@ -19,13 +19,11 @@ import {
|
|
|
19
19
|
UserPlus,
|
|
20
20
|
StickyNote,
|
|
21
21
|
Bell,
|
|
22
|
-
ArrowRightLeft,
|
|
23
|
-
ShoppingCart,
|
|
24
22
|
Users,
|
|
25
23
|
Filter,
|
|
26
24
|
Info,
|
|
27
25
|
} from 'lucide-react';
|
|
28
|
-
import { cn } from '@/lib/utils';
|
|
26
|
+
import { cn, devToast } from '@/lib/utils';
|
|
29
27
|
import { ProtectedPage } from '@/components/protected-page';
|
|
30
28
|
import { useConfirm } from '@/hooks/use-confirm';
|
|
31
29
|
import { useUserRole } from '@/hooks/use-user-role';
|
|
@@ -81,7 +79,7 @@ export default function AutomatisationPage() {
|
|
|
81
79
|
setWorkflows(data);
|
|
82
80
|
} catch (err: any) {
|
|
83
81
|
console.error('Erreur lors du chargement des workflows:', err);
|
|
84
|
-
setError(
|
|
82
|
+
setError(devToast('Erreur lors du chargement des workflows', err));
|
|
85
83
|
} finally {
|
|
86
84
|
setLoading(false);
|
|
87
85
|
}
|
|
@@ -101,7 +99,7 @@ export default function AutomatisationPage() {
|
|
|
101
99
|
useEffect(() => {
|
|
102
100
|
fetchWorkflows();
|
|
103
101
|
fetchStatuses();
|
|
104
|
-
|
|
102
|
+
|
|
105
103
|
}, []);
|
|
106
104
|
|
|
107
105
|
useEffect(() => {
|
|
@@ -142,7 +140,7 @@ export default function AutomatisationPage() {
|
|
|
142
140
|
fetchWorkflows();
|
|
143
141
|
setTimeout(() => setSuccess(''), 5000);
|
|
144
142
|
} catch (err: any) {
|
|
145
|
-
setError(
|
|
143
|
+
setError(devToast('Erreur lors de la suppression du workflow', err));
|
|
146
144
|
}
|
|
147
145
|
};
|
|
148
146
|
|
|
@@ -165,9 +163,10 @@ export default function AutomatisationPage() {
|
|
|
165
163
|
throw new Error('Erreur lors de la mise à jour');
|
|
166
164
|
}
|
|
167
165
|
|
|
166
|
+
toast.success(workflow.active ? 'Workflow désactivé' : 'Workflow activé');
|
|
168
167
|
fetchWorkflows();
|
|
169
168
|
} catch (err: any) {
|
|
170
|
-
setError(
|
|
169
|
+
setError(devToast('Erreur lors de la mise à jour du workflow', err));
|
|
171
170
|
}
|
|
172
171
|
};
|
|
173
172
|
const getTriggerLabel = (triggerType: string) => {
|
|
@@ -182,10 +181,6 @@ export default function AutomatisationPage() {
|
|
|
182
181
|
return 'Déclencheur manuel';
|
|
183
182
|
case 'TASK_COMPLETED':
|
|
184
183
|
return 'Tâche complétée';
|
|
185
|
-
case 'TRANSACTION_CREATED':
|
|
186
|
-
return 'Transaction créée';
|
|
187
|
-
case 'TRANSACTION_STATUS_CHANGED':
|
|
188
|
-
return 'Changement statut transaction';
|
|
189
184
|
case 'CONTACT_ASSIGNMENT_CHANGED':
|
|
190
185
|
return "Changement d'assignation";
|
|
191
186
|
default:
|
|
@@ -222,7 +217,6 @@ export default function AutomatisationPage() {
|
|
|
222
217
|
/>
|
|
223
218
|
|
|
224
219
|
<div className="p-4 sm:p-6 lg:p-8">
|
|
225
|
-
|
|
226
220
|
{/* Guide d'utilisation */}
|
|
227
221
|
<div className="mb-6 rounded-2xl border border-blue-100 bg-white shadow-sm">
|
|
228
222
|
<button
|
|
@@ -289,16 +283,6 @@ export default function AutomatisationPage() {
|
|
|
289
283
|
title: 'Tâche complétée',
|
|
290
284
|
desc: 'Se lance quand une tâche liée à un contact est terminée. Filtrable par type de tâche.',
|
|
291
285
|
},
|
|
292
|
-
{
|
|
293
|
-
icon: <ShoppingCart className="h-4 w-4 text-orange-600" />,
|
|
294
|
-
title: 'Transaction créée',
|
|
295
|
-
desc: 'Se lance quand une nouvelle transaction est créée pour un contact.',
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
icon: <ArrowRightLeft className="h-4 w-4 text-rose-600" />,
|
|
299
|
-
title: 'Statut transaction',
|
|
300
|
-
desc: 'Se lance quand le statut d\u2019une transaction change (ex. Signée, Complétée). Filtrable par statut.',
|
|
301
|
-
},
|
|
302
286
|
{
|
|
303
287
|
icon: <Users className="h-4 w-4 text-cyan-600" />,
|
|
304
288
|
title: "Changement d'assignation",
|
|
@@ -444,9 +428,9 @@ export default function AutomatisationPage() {
|
|
|
444
428
|
Ajouter une note dans l'historique.
|
|
445
429
|
</li>
|
|
446
430
|
<li>
|
|
447
|
-
<strong>Qualification
|
|
448
|
-
|
|
449
|
-
|
|
431
|
+
<strong>Qualification après RDV :</strong> Déclencheur « Changement de
|
|
432
|
+
statut » (ex. vers « Qualifié ») → Envoyer un email de
|
|
433
|
+
suivi → Notifier le manager.
|
|
450
434
|
</li>
|
|
451
435
|
<li>
|
|
452
436
|
<strong>Réassignation intelligente :</strong> Déclencheur « Tâche
|
|
@@ -490,7 +474,7 @@ export default function AutomatisationPage() {
|
|
|
490
474
|
value={search}
|
|
491
475
|
onChange={(e) => setSearch(e.target.value)}
|
|
492
476
|
placeholder="Rechercher une automatisation..."
|
|
493
|
-
className="w-full rounded-full border border-gray-200 bg-gray-50 py-2 pr-3 pl-9 text-sm text-gray-900 placeholder:text-gray-400 focus:bg-white focus:ring-2 focus:ring-gray-400/30 focus:outline-none"
|
|
477
|
+
className="w-full rounded-full border border-gray-200 bg-gray-50 py-2 pr-3 pl-9 text-sm text-gray-900 placeholder:text-gray-400 focus:bg-white focus:ring-2 focus:ring-gray-400/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50"
|
|
494
478
|
/>
|
|
495
479
|
</div>
|
|
496
480
|
</div>
|