create-crm-tmp 1.1.2 → 2.0.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 (220) hide show
  1. package/package.json +1 -1
  2. package/template/.prettierignore +2 -0
  3. package/template/README.md +53 -67
  4. package/template/components.json +22 -0
  5. package/template/exemple-contacts.csv +54 -0
  6. package/template/next.config.ts +27 -1
  7. package/template/package.json +64 -27
  8. package/template/prisma/schema.prisma +821 -72
  9. package/template/skills-lock.json +25 -0
  10. package/template/src/app/(auth)/invite/[token]/page.tsx +21 -24
  11. package/template/src/app/(auth)/reset-password/complete/page.tsx +12 -21
  12. package/template/src/app/(auth)/reset-password/page.tsx +12 -8
  13. package/template/src/app/(auth)/reset-password/verify/page.tsx +12 -8
  14. package/template/src/app/(auth)/signin/page.tsx +20 -17
  15. package/template/src/app/(dashboard)/agenda/page.tsx +2231 -2188
  16. package/template/src/app/(dashboard)/automatisation/[id]/page.tsx +10 -7
  17. package/template/src/app/(dashboard)/automatisation/_components/workflow-editor.tsx +680 -323
  18. package/template/src/app/(dashboard)/automatisation/new/page.tsx +11 -8
  19. package/template/src/app/(dashboard)/automatisation/page.tsx +473 -180
  20. package/template/src/app/(dashboard)/closing/page.tsx +500 -468
  21. package/template/src/app/(dashboard)/contacts/[id]/page.tsx +5035 -4126
  22. package/template/src/app/(dashboard)/contacts/companies/[id]/page.tsx +1703 -0
  23. package/template/src/app/(dashboard)/contacts/loading.tsx +13 -0
  24. package/template/src/app/(dashboard)/contacts/page.tsx +3776 -2064
  25. package/template/src/app/(dashboard)/dashboard/page.tsx +37 -519
  26. package/template/src/app/(dashboard)/error.tsx +37 -0
  27. package/template/src/app/(dashboard)/layout.tsx +1 -1
  28. package/template/src/app/(dashboard)/loading.tsx +5 -0
  29. package/template/src/app/(dashboard)/settings/loading.tsx +19 -0
  30. package/template/src/app/(dashboard)/settings/page.tsx +2685 -2489
  31. package/template/src/app/(dashboard)/templates/page.tsx +500 -300
  32. package/template/src/app/(dashboard)/users/list/page.tsx +356 -350
  33. package/template/src/app/(dashboard)/users/page.tsx +279 -310
  34. package/template/src/app/(dashboard)/users/permissions/page.tsx +104 -99
  35. package/template/src/app/(dashboard)/users/roles/page.tsx +164 -137
  36. package/template/src/app/api/audit-logs/route.ts +1 -1
  37. package/template/src/app/api/auth/google/callback/route.ts +8 -5
  38. package/template/src/app/api/auth/google/disconnect/route.ts +2 -2
  39. package/template/src/app/api/companies/[id]/activities/route.ts +131 -0
  40. package/template/src/app/api/companies/[id]/route.ts +195 -0
  41. package/template/src/app/api/companies/export/route.ts +206 -0
  42. package/template/src/app/api/companies/route.ts +166 -0
  43. package/template/src/app/api/contact-views/[id]/pin/route.ts +69 -0
  44. package/template/src/app/api/contact-views/[id]/route.ts +197 -0
  45. package/template/src/app/api/contact-views/route.ts +146 -0
  46. package/template/src/app/api/contacts/[id]/files/[fileId]/preview/route.ts +77 -0
  47. package/template/src/app/api/contacts/[id]/files/[fileId]/route.ts +7 -17
  48. package/template/src/app/api/contacts/[id]/files/route.ts +83 -44
  49. package/template/src/app/api/contacts/[id]/interactions/route.ts +37 -0
  50. package/template/src/app/api/contacts/[id]/kyc/route.ts +71 -0
  51. package/template/src/app/api/contacts/[id]/meet/route.ts +38 -29
  52. package/template/src/app/api/contacts/[id]/route.ts +111 -20
  53. package/template/src/app/api/contacts/[id]/send-email/route.ts +6 -0
  54. package/template/src/app/api/contacts/[id]/workflows/run/route.ts +61 -0
  55. package/template/src/app/api/contacts/export/route.ts +12 -17
  56. package/template/src/app/api/contacts/import/route.ts +22 -19
  57. package/template/src/app/api/contacts/import-preview/route.ts +139 -0
  58. package/template/src/app/api/contacts/route.ts +202 -49
  59. package/template/src/app/api/dashboard/stats/route.ts +9 -292
  60. package/template/src/app/api/integrations/google-sheet/sync/route.ts +203 -185
  61. package/template/src/app/api/invite/complete/route.ts +20 -23
  62. package/template/src/app/api/reminders/route.ts +1 -0
  63. package/template/src/app/api/reset-password/complete/route.ts +11 -13
  64. package/template/src/app/api/send/route.ts +9 -85
  65. package/template/src/app/api/settings/closing-reasons/[id]/route.ts +10 -21
  66. package/template/src/app/api/settings/closing-reasons/route.ts +10 -21
  67. package/template/src/app/api/settings/company/route.ts +19 -26
  68. package/template/src/app/api/settings/google-ads/[id]/route.ts +20 -23
  69. package/template/src/app/api/settings/google-ads/route.ts +20 -23
  70. package/template/src/app/api/settings/google-sheet/[id]/route.ts +20 -23
  71. package/template/src/app/api/settings/google-sheet/auto-map/route.ts +23 -32
  72. package/template/src/app/api/settings/google-sheet/preview/route.ts +104 -0
  73. package/template/src/app/api/settings/google-sheet/route.ts +20 -23
  74. package/template/src/app/api/settings/meta-leads/[id]/route.ts +20 -23
  75. package/template/src/app/api/settings/meta-leads/route.ts +20 -23
  76. package/template/src/app/api/settings/statuses/[id]/route.ts +33 -23
  77. package/template/src/app/api/settings/statuses/route.ts +24 -22
  78. package/template/src/app/api/statuses/route.ts +2 -5
  79. package/template/src/app/api/tasks/[id]/attendees/route.ts +14 -7
  80. package/template/src/app/api/tasks/[id]/route.ts +161 -137
  81. package/template/src/app/api/tasks/meet/route.ts +11 -8
  82. package/template/src/app/api/tasks/route.ts +155 -95
  83. package/template/src/app/api/templates/[id]/route.ts +22 -13
  84. package/template/src/app/api/templates/route.ts +22 -5
  85. package/template/src/app/api/users/[id]/resend-invite/route.ts +95 -0
  86. package/template/src/app/api/users/[id]/route.ts +16 -1
  87. package/template/src/app/api/users/commercials/route.ts +38 -0
  88. package/template/src/app/api/users/for-agenda/route.ts +1 -2
  89. package/template/src/app/api/users/route.ts +94 -55
  90. package/template/src/app/api/webhooks/google-ads/route.ts +20 -1
  91. package/template/src/app/api/webhooks/meta-leads/route.ts +18 -1
  92. package/template/src/app/api/workflows/[id]/route.ts +33 -6
  93. package/template/src/app/api/workflows/process/route.ts +509 -146
  94. package/template/src/app/api/workflows/route.ts +46 -4
  95. package/template/src/app/globals.css +210 -101
  96. package/template/src/app/layout.tsx +19 -8
  97. package/template/src/app/page.tsx +37 -7
  98. package/template/src/components/address-autocomplete.tsx +232 -0
  99. package/template/src/components/contacts/filter-bar.tsx +181 -0
  100. package/template/src/components/contacts/filter-builder.tsx +589 -0
  101. package/template/src/components/contacts/save-view-dialog.tsx +160 -0
  102. package/template/src/components/contacts/views-tab-bar.tsx +440 -0
  103. package/template/src/components/dashboard/activity-chart.tsx +31 -39
  104. package/template/src/components/dashboard/dashboard-content.tsx +79 -0
  105. package/template/src/components/dashboard/stat-card.tsx +40 -42
  106. package/template/src/components/dashboard/tasks-pie-chart.tsx +34 -37
  107. package/template/src/components/dashboard/upcoming-tasks-list.tsx +78 -72
  108. package/template/src/components/date-picker.tsx +396 -0
  109. package/template/src/components/editor.tsx +27 -13
  110. package/template/src/components/email-template.tsx +4 -2
  111. package/template/src/components/global-search.tsx +358 -0
  112. package/template/src/components/header.tsx +57 -62
  113. package/template/src/components/invitation-email-template.tsx +4 -2
  114. package/template/src/components/lazy-editor.tsx +11 -0
  115. package/template/src/components/meet-cancellation-email-template.tsx +11 -3
  116. package/template/src/components/meet-confirmation-email-template.tsx +10 -3
  117. package/template/src/components/meet-update-email-template.tsx +10 -3
  118. package/template/src/components/page-header.tsx +19 -15
  119. package/template/src/components/protected-page.tsx +94 -0
  120. package/template/src/components/reset-password-email-template.tsx +4 -2
  121. package/template/src/components/sidebar.tsx +92 -94
  122. package/template/src/components/skeleton.tsx +128 -42
  123. package/template/src/components/ui/accordion.tsx +64 -0
  124. package/template/src/components/ui/alert-dialog.tsx +139 -0
  125. package/template/src/components/ui/button.tsx +60 -0
  126. package/template/src/components/view-as-banner.tsx +1 -1
  127. package/template/src/components/view-as-modal.tsx +21 -16
  128. package/template/src/config/nav-pages.ts +108 -0
  129. package/template/src/contexts/app-toast-context.tsx +174 -0
  130. package/template/src/contexts/sidebar-context.tsx +16 -47
  131. package/template/src/contexts/task-reminder-context.tsx +6 -6
  132. package/template/src/contexts/view-as-context.tsx +11 -16
  133. package/template/src/hooks/use-alert.tsx +65 -0
  134. package/template/src/hooks/use-confirm.tsx +87 -0
  135. package/template/src/hooks/use-contact-views.ts +140 -0
  136. package/template/src/hooks/use-contacts.ts +69 -0
  137. package/template/src/hooks/use-fetch.ts +17 -0
  138. package/template/src/hooks/use-focus-trap.ts +73 -0
  139. package/template/src/hooks/use-statuses.ts +22 -0
  140. package/template/src/lib/address-api.ts +155 -0
  141. package/template/src/lib/cache.ts +73 -0
  142. package/template/src/lib/check-permission.ts +12 -177
  143. package/template/src/lib/contact-interactions.ts +3 -1
  144. package/template/src/lib/contact-view-filters.ts +341 -0
  145. package/template/src/lib/dashboard-stats.ts +224 -0
  146. package/template/src/lib/date-utils.ts +49 -0
  147. package/template/src/lib/get-auth-user.ts +25 -0
  148. package/template/src/lib/google-calendar.ts +54 -12
  149. package/template/src/lib/google-drive.ts +796 -75
  150. package/template/src/lib/google-fetch.ts +63 -0
  151. package/template/src/lib/local-storage.ts +34 -0
  152. package/template/src/lib/permissions.ts +245 -47
  153. package/template/src/lib/prisma.ts +11 -11
  154. package/template/src/lib/roles.ts +14 -39
  155. package/template/src/lib/template-variables.ts +67 -33
  156. package/template/src/lib/utils.ts +26 -2
  157. package/template/src/lib/workflow-executor.ts +445 -229
  158. package/template/src/proxy.ts +34 -73
  159. package/template/src/types/contact-views.ts +351 -0
  160. package/template/src/types/yousign.ts +52 -0
  161. package/template/vercel.json +12 -0
  162. package/template/WORKFLOWS_CRON.md +0 -185
  163. package/template/prisma/migrations/20251126144728_init/migration.sql +0 -78
  164. package/template/prisma/migrations/20251126155204_add_user_roles/migration.sql +0 -5
  165. package/template/prisma/migrations/20251128095126_add_company_info/migration.sql +0 -19
  166. package/template/prisma/migrations/20251128123321_add_smtp_config/migration.sql +0 -22
  167. package/template/prisma/migrations/20251128132303_add_status/migration.sql +0 -23
  168. package/template/prisma/migrations/20251201102207_add_user_active/migration.sql +0 -75
  169. package/template/prisma/migrations/20251201105507_add_email_signature/migration.sql +0 -2
  170. package/template/prisma/migrations/20251201151122_add_tasks/migration.sql +0 -45
  171. package/template/prisma/migrations/20251202111854_add_task_reminder/migration.sql +0 -2
  172. package/template/prisma/migrations/20251202135859_add_google_meet_integration/migration.sql +0 -27
  173. package/template/prisma/migrations/20251203103317_add_meta_lead_integration/migration.sql +0 -20
  174. package/template/prisma/migrations/20251203104002_add_google_ads_integration/migration.sql +0 -18
  175. package/template/prisma/migrations/20251203112122_add_google_sheet_integration/migration.sql +0 -32
  176. package/template/prisma/migrations/20251203153853_allow_multiple_integration_configs/migration.sql +0 -20
  177. package/template/prisma/migrations/20251205141705_update_user_roles/migration.sql +0 -12
  178. package/template/prisma/migrations/20251205150000_add_commercial_and_telepro_assignment/migration.sql +0 -21
  179. package/template/prisma/migrations/20251205160000_add_interaction_logging/migration.sql +0 -11
  180. package/template/prisma/migrations/20251208090314_add_automatic_interaction_types/migration.sql +0 -12
  181. package/template/prisma/migrations/20251208094843_mg/migration.sql +0 -14
  182. package/template/prisma/migrations/20251208100000_add_company_support/migration.sql +0 -14
  183. package/template/prisma/migrations/20251208110000_add_templates/migration.sql +0 -26
  184. package/template/prisma/migrations/20251208141304_add_video_conference_task_type/migration.sql +0 -2
  185. package/template/prisma/migrations/20251209104759_add_internal_note_to_task/migration.sql +0 -2
  186. package/template/prisma/migrations/20251209134803_add_company_field/migration.sql +0 -2
  187. package/template/prisma/migrations/20251209150000_rename_company_to_company_name/migration.sql +0 -3
  188. package/template/prisma/migrations/20251209150016_add_email_tracking/migration.sql +0 -21
  189. package/template/prisma/migrations/20251209155908_add_notify_contact_to_task/migration.sql +0 -2
  190. package/template/prisma/migrations/20251210110019_add_appointment_types/migration.sql +0 -10
  191. package/template/prisma/migrations/20251210113928_add_contact_files/migration.sql +0 -26
  192. package/template/prisma/migrations/20251212132339_add_custom_roles/migration.sql +0 -24
  193. package/template/prisma/migrations/20251215104448_add_file_interaction_types/migration.sql +0 -11
  194. package/template/prisma/migrations/20251215145616_add_closing_reasons/migration.sql +0 -12
  195. package/template/prisma/migrations/20251216140850_add_log_users/migration.sql +0 -25
  196. package/template/prisma/migrations/20251216151000_rename_perdu_to_ferme/migration.sql +0 -8
  197. package/template/prisma/migrations/20251216162318_add_column_mappings_to_google_sheet/migration.sql +0 -2
  198. package/template/prisma/migrations/20251216185127_add_workflows/migration.sql +0 -80
  199. package/template/prisma/migrations/20251216192237_add_scheduled_workflow_actions/migration.sql +0 -32
  200. package/template/prisma/migrations/20251220000000_add_task_interaction_type/migration.sql +0 -4
  201. package/template/prisma/migrations/20251221000000_add_task_type/migration.sql +0 -3
  202. package/template/prisma/migrations/20251221000001_add_event_color/migration.sql +0 -23
  203. package/template/prisma/migrations/20260210114913_add_dashboard_widget/migration.sql +0 -20
  204. package/template/prisma/migrations/migration_lock.toml +0 -3
  205. package/template/src/app/(dashboard)/users/layout.tsx +0 -30
  206. package/template/src/app/api/dashboard/widgets/[id]/route.ts +0 -47
  207. package/template/src/app/api/dashboard/widgets/route.ts +0 -181
  208. package/template/src/components/dashboard/add-widget-dialog.tsx +0 -161
  209. package/template/src/components/dashboard/color-picker.tsx +0 -65
  210. package/template/src/components/dashboard/contacts-chart.tsx +0 -69
  211. package/template/src/components/dashboard/interactions-by-type-chart.tsx +0 -121
  212. package/template/src/components/dashboard/recent-activity.tsx +0 -157
  213. package/template/src/components/dashboard/sales-analytics-chart.tsx +0 -77
  214. package/template/src/components/dashboard/status-distribution-chart.tsx +0 -82
  215. package/template/src/components/dashboard/top-contacts-list.tsx +0 -119
  216. package/template/src/components/dashboard/widget-wrapper.tsx +0 -39
  217. package/template/src/contexts/dashboard-theme-context.tsx +0 -58
  218. package/template/src/lib/dashboard-themes.ts +0 -140
  219. package/template/src/lib/default-widgets.ts +0 -14
  220. package/template/src/lib/widget-registry.ts +0 -177
@@ -14,23 +14,71 @@ export interface ContactVariables {
14
14
  city?: string | null;
15
15
  postalCode?: string | null;
16
16
  companyName?: string | null;
17
+ company?: { name?: string | null } | null;
17
18
  }
18
19
 
19
- /**
20
- * Liste des variables disponibles avec leurs descriptions
21
- */
22
- export const AVAILABLE_VARIABLES = [
23
- { key: '{{firstName}}', description: 'Prénom du contact' },
24
- { key: '{{lastName}}', description: 'Nom du contact' },
25
- { key: '{{fullName}}', description: 'Prénom et nom complets' },
26
- { key: '{{civility}}', description: 'Civilité (M., Mme, Mlle)' },
27
- { key: '{{email}}', description: 'Email du contact' },
28
- { key: '{{phone}}', description: 'Téléphone principal' },
29
- { key: '{{secondaryPhone}}', description: 'Téléphone secondaire' },
30
- { key: '{{address}}', description: 'Adresse complète' },
31
- { key: '{{city}}', description: 'Ville' },
32
- { key: '{{postalCode}}', description: 'Code postal' },
33
- { key: '{{companyName}}', description: "Nom de l'entreprise associée" },
20
+ export interface TemplateVariable {
21
+ key: string;
22
+ description: string;
23
+ section: 'contact' | 'lieu' | 'tournee';
24
+ }
25
+
26
+ export const VARIABLE_SECTIONS = {
27
+ contact: { label: 'Contact', color: 'indigo' },
28
+ lieu: { label: 'Lieu & contacts sur place', color: 'blue' },
29
+ tournee: { label: 'Tournée', color: 'emerald' },
30
+ } as const;
31
+
32
+ export const AVAILABLE_VARIABLES: TemplateVariable[] = [
33
+ // Contact
34
+ { key: '{{firstName}}', description: 'Prénom du contact (ex. Jean)', section: 'contact' },
35
+ { key: '{{lastName}}', description: 'Nom de famille du contact.', section: 'contact' },
36
+ { key: '{{fullName}}', description: 'Prénom et nom en un seul bloc.', section: 'contact' },
37
+ { key: '{{civility}}', description: 'Civilité du contact : M., Mme, Mlle.', section: 'contact' },
38
+ { key: '{{email}}', description: 'Adresse email du contact.', section: 'contact' },
39
+ {
40
+ key: '{{phone}}',
41
+ description: 'Numéro de téléphone principal du contact.',
42
+ section: 'contact',
43
+ },
44
+ {
45
+ key: '{{secondaryPhone}}',
46
+ description: 'Autre numéro de téléphone du contact si renseigné.',
47
+ section: 'contact',
48
+ },
49
+ { key: '{{address}}', description: 'Adresse postale complète du contact.', section: 'contact' },
50
+ {
51
+ key: '{{companyName}}',
52
+ description: 'Nom de l’entreprise ou structure du contact.',
53
+ section: 'contact',
54
+ },
55
+ // Lieu
56
+ { key: '{{placeName}}', description: 'Nom du lieu.', section: 'lieu' },
57
+ { key: '{{placeAddress}}', description: 'Adresse complète du lieu.', section: 'lieu' },
58
+ {
59
+ key: '{{placeContactName}}',
60
+ description: 'Nom de la personne à contacter sur place.',
61
+ section: 'lieu',
62
+ },
63
+ // Tournée
64
+ {
65
+ key: '{{tourName}}',
66
+ description: 'Libellé auto de tournée (région + semaine ISO).',
67
+ section: 'tournee',
68
+ },
69
+ // { key: '{{tourNumber}}', description: 'Numéro unique de la tournée.', section: 'tournee' },
70
+ {
71
+ key: '{{presenceStart}}',
72
+ description: 'Date et heure de début de la présence (ex. lundi 10 mars 2026 à 09:00).',
73
+ section: 'tournee',
74
+ },
75
+ {
76
+ key: '{{presenceEnd}}',
77
+ description: 'Date et heure de fin de la présence (ex. lundi 10 mars 2026 à 12:00).',
78
+ section: 'tournee',
79
+ },
80
+ { key: '{{city}}', description: 'Ville où se déroule la tournée.', section: 'tournee' },
81
+ { key: '{{postalCode}}', description: 'Code postal de la tournée.', section: 'tournee' },
34
82
  ];
35
83
 
36
84
  /**
@@ -49,7 +97,10 @@ export function replaceTemplateVariables(template: string, variables: ContactVar
49
97
  result = result.replace(/\{\{address\}\}/g, variables.address || '');
50
98
  result = result.replace(/\{\{city\}\}/g, variables.city || '');
51
99
  result = result.replace(/\{\{postalCode\}\}/g, variables.postalCode || '');
52
- result = result.replace(/\{\{companyName\}\}/g, variables.companyName || '');
100
+ result = result.replace(
101
+ /\{\{companyName\}\}/g,
102
+ variables.company?.name ?? variables.companyName ?? '',
103
+ );
53
104
 
54
105
  // Variable composée : fullName
55
106
  const fullName = [variables.firstName, variables.lastName].filter(Boolean).join(' ') || '';
@@ -57,20 +108,3 @@ export function replaceTemplateVariables(template: string, variables: ContactVar
57
108
 
58
109
  return result;
59
110
  }
60
-
61
- /**
62
- * Extrait toutes les variables utilisées dans un template
63
- */
64
- export function extractVariables(template: string): string[] {
65
- const regex = /\{\{(\w+)\}\}/g;
66
- const variables: string[] = [];
67
- let match;
68
-
69
- while ((match = regex.exec(template)) !== null) {
70
- if (!variables.includes(match[1])) {
71
- variables.push(match[1]);
72
- }
73
- }
74
-
75
- return variables;
76
- }
@@ -1,7 +1,7 @@
1
- import { clsx } from 'clsx';
1
+ import { clsx, type ClassValue } from 'clsx';
2
2
  import { twMerge } from 'tailwind-merge';
3
3
 
4
- export function cn(...inputs: Array<string | false | null | undefined>) {
4
+ export function cn(...inputs: ClassValue[]) {
5
5
  return twMerge(clsx(inputs));
6
6
  }
7
7
 
@@ -44,3 +44,27 @@ export function normalizePhoneNumber(phone: string | null | undefined): string {
44
44
  // Si le numéro n'a pas 10 chiffres, retourner tel quel (cas d'erreur)
45
45
  return digits;
46
46
  }
47
+
48
+ const DATE_TIME_FORMATTER = new Intl.DateTimeFormat('fr-FR', {
49
+ day: '2-digit',
50
+ month: '2-digit',
51
+ year: 'numeric',
52
+ hour: '2-digit',
53
+ minute: '2-digit',
54
+ });
55
+
56
+ export function formatDateTime(dateString: string | null): string {
57
+ if (!dateString) return '-';
58
+ return DATE_TIME_FORMATTER.format(new Date(dateString));
59
+ }
60
+
61
+ export function indexToColumn(index: number): string {
62
+ let col = '';
63
+ let n = index + 1;
64
+ while (n > 0) {
65
+ const remainder = (n - 1) % 26;
66
+ col = String.fromCharCode(65 + remainder) + col;
67
+ n = Math.floor((n - 1) / 26);
68
+ }
69
+ return col;
70
+ }