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
@@ -1,91 +1,52 @@
1
- import { NextResponse } from 'next/server';
2
- import type { NextRequest } from 'next/server';
3
- import { auth } from './lib/auth';
4
- import { isAdmin } from './lib/roles';
5
- import { prisma } from './lib/prisma';
1
+ import { NextRequest, NextResponse } from 'next/server';
6
2
 
7
- // Routes qui nécessitent une authentification
8
- const protectedRoutes = [
9
- '/dashboard',
10
- '/contacts',
11
- '/settings',
12
- '/users',
13
- '/agenda',
14
- '/automatisation',
15
- '/templates',
16
- '/closing',
17
- ];
18
-
19
- // Routes réservées aux admins
20
- const adminRoutes = ['/users'];
3
+ const SESSION_COOKIE = 'better-auth.session_token';
21
4
 
22
- // Routes d'authentification
23
- const authRoutes = ['/signin'];
24
-
25
- export async function proxy(request: NextRequest) {
26
- const { pathname } = request.nextUrl;
5
+ const PUBLIC_PAGES = new Set(['/', '/signin', '/invite', '/reset-password']);
27
6
 
28
- // Vérifier la session en utilisant Better Auth
29
- const session = await auth.api.getSession({
30
- headers: request.headers,
31
- });
32
-
33
- let isAuthenticated = !!session;
34
- let isActiveUser = true;
35
-
36
- // Récupérer le rôle depuis la session ou depuis la base de données
37
- let userRole: string | null = null;
38
- if (session && session.user?.id) {
39
- const dbUser = await prisma.user.findUnique({
40
- where: { id: session.user.id },
41
- select: { role: true, active: true },
42
- });
7
+ const PUBLIC_API_PREFIXES = [
8
+ '/api/auth',
9
+ '/api/webhooks',
10
+ '/api/cron',
11
+ '/api/invite',
12
+ '/api/reset-password',
13
+ '/api/email/track',
14
+ '/api/workflows/process',
15
+ ];
43
16
 
44
- userRole = (session.user as any).role || dbUser?.role || null;
45
- isActiveUser = dbUser?.active ?? true;
46
- if (!isActiveUser) {
47
- isAuthenticated = false;
48
- }
17
+ function isPublicPage(pathname: string): boolean {
18
+ if (PUBLIC_PAGES.has(pathname)) return true;
19
+ for (const path of PUBLIC_PAGES) {
20
+ if (path !== '/' && pathname.startsWith(path + '/')) return true;
49
21
  }
22
+ return false;
23
+ }
50
24
 
51
- // Vérifier si la route actuelle est protégée
52
- const isProtectedRoute = protectedRoutes.some((route) => pathname.startsWith(route));
53
-
54
- // Vérifier si la route est réservée aux admins
55
- const isAdminRoute = adminRoutes.some((route) => pathname.startsWith(route));
25
+ function isPublicApi(pathname: string): boolean {
26
+ return PUBLIC_API_PREFIXES.some((prefix) => pathname.startsWith(prefix));
27
+ }
56
28
 
57
- // Vérifier si la route actuelle est une route d'auth
58
- const isAuthRoute = authRoutes.some((route) => pathname.startsWith(route));
29
+ export function proxy(request: NextRequest) {
30
+ const { pathname } = request.nextUrl;
59
31
 
60
- // Si l'utilisateur n'est pas connecté et tente d'accéder à une route protégée
61
- if (!isAuthenticated && isProtectedRoute) {
62
- const signInUrl = new URL('/signin', request.url);
63
- signInUrl.searchParams.set('callbackUrl', pathname);
64
- return NextResponse.redirect(signInUrl);
32
+ if (isPublicPage(pathname) || isPublicApi(pathname)) {
33
+ return NextResponse.next();
65
34
  }
66
35
 
67
- // Si l'utilisateur est connecté mais n'est pas admin et tente d'accéder à une route admin
68
- if (isAuthenticated && isAdminRoute && !isAdmin(userRole || undefined)) {
69
- return NextResponse.redirect(new URL('/dashboard', request.url));
70
- }
36
+ const hasSession = request.cookies.has(SESSION_COOKIE);
71
37
 
72
- // Si l'utilisateur est connecté et tente d'accéder aux pages d'auth
73
- if (isAuthenticated && isAuthRoute) {
74
- return NextResponse.redirect(new URL('/dashboard', request.url));
38
+ if (!hasSession) {
39
+ if (pathname.startsWith('/api/')) {
40
+ return NextResponse.json({ error: 'Non authentifié' }, { status: 401 });
41
+ }
42
+ const signinUrl = new URL('/signin', request.url);
43
+ signinUrl.searchParams.set('callbackUrl', pathname);
44
+ return NextResponse.redirect(signinUrl);
75
45
  }
76
46
 
77
47
  return NextResponse.next();
78
48
  }
79
49
 
80
50
  export const config = {
81
- matcher: [
82
- /*
83
- * Match all request paths except for the ones starting with:
84
- * - api (API routes)
85
- * - _next/static (static files)
86
- * - _next/image (image optimization files)
87
- * - favicon.ico (favicon file)
88
- */
89
- '/((?!api|_next/static|_next/image|favicon.ico).*)',
90
- ],
51
+ matcher: ['/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt|.*..*).*)'],
91
52
  };
@@ -0,0 +1,351 @@
1
+ export type FilterOperator =
2
+ | 'equals'
3
+ | 'not_equals'
4
+ | 'contains'
5
+ | 'not_contains'
6
+ | 'starts_with'
7
+ | 'ends_with'
8
+ | 'is_any_of'
9
+ | 'is_none_of'
10
+ | 'gt'
11
+ | 'gte'
12
+ | 'lt'
13
+ | 'lte'
14
+ | 'between'
15
+ | 'is_known'
16
+ | 'is_unknown'
17
+ | 'date_preset';
18
+
19
+ export type DatePreset =
20
+ | 'today'
21
+ | 'yesterday'
22
+ | 'tomorrow'
23
+ | 'this_week'
24
+ | 'this_week_so_far'
25
+ | 'last_week'
26
+ | 'next_week'
27
+ | 'this_month'
28
+ | 'this_month_so_far'
29
+ | 'last_month'
30
+ | 'next_month'
31
+ | 'this_quarter'
32
+ | 'this_quarter_so_far'
33
+ | 'last_quarter'
34
+ | 'this_year'
35
+ | 'this_year_so_far'
36
+ | 'last_year'
37
+ | 'last_7_days'
38
+ | 'last_14_days'
39
+ | 'last_30_days'
40
+ | 'last_60_days'
41
+ | 'last_90_days'
42
+ | 'last_180_days'
43
+ | 'last_365_days';
44
+
45
+ export interface ViewFilter {
46
+ field: string;
47
+ operator: FilterOperator;
48
+ value: string | string[] | null;
49
+ preset?: DatePreset;
50
+ }
51
+
52
+ export interface ViewColumn {
53
+ id: string;
54
+ visible: boolean;
55
+ order: number;
56
+ }
57
+
58
+ export interface ViewSortConfig {
59
+ field: string;
60
+ direction: 'asc' | 'desc';
61
+ }
62
+
63
+ export type FilterFieldType = 'text' | 'select' | 'date' | 'boolean' | 'select_or_text';
64
+
65
+ export interface FilterFieldDefinition {
66
+ field: string;
67
+ label: string;
68
+ type: FilterFieldType;
69
+ group: string;
70
+ operators: FilterOperator[];
71
+ optionsEndpoint?: string;
72
+ staticOptions?: { value: string; label: string }[];
73
+ clientSideOnly?: boolean;
74
+ entityTypes?: ('contacts' | 'companies')[];
75
+ }
76
+
77
+ export const DATE_PRESET_LABELS: Record<DatePreset, string> = {
78
+ today: "Aujourd'hui",
79
+ yesterday: 'Hier',
80
+ tomorrow: 'Demain',
81
+ this_week: 'Cette semaine',
82
+ this_week_so_far: "Cette semaine jusqu'à aujourd'hui",
83
+ last_week: 'La semaine dernière',
84
+ next_week: 'La semaine prochaine',
85
+ this_month: 'Ce mois-ci',
86
+ this_month_so_far: "Ce mois jusqu'à aujourd'hui",
87
+ last_month: 'Le mois dernier',
88
+ next_month: 'Le mois prochain',
89
+ this_quarter: 'Ce trimestre',
90
+ this_quarter_so_far: "Ce trimestre jusqu'à aujourd'hui",
91
+ last_quarter: 'Le trimestre dernier',
92
+ this_year: 'Cette année',
93
+ this_year_so_far: "Cette année jusqu'à aujourd'hui",
94
+ last_year: "L'année dernière",
95
+ last_7_days: 'Les 7 derniers jours',
96
+ last_14_days: 'Les 14 derniers jours',
97
+ last_30_days: 'Les 30 derniers jours',
98
+ last_60_days: 'Les 60 derniers jours',
99
+ last_90_days: 'Les 90 derniers jours',
100
+ last_180_days: 'Les 180 derniers jours',
101
+ last_365_days: 'Les 365 derniers jours',
102
+ };
103
+
104
+ export const OPERATOR_LABELS: Record<FilterOperator, string> = {
105
+ equals: 'est égal à',
106
+ not_equals: "n'est pas égal à",
107
+ contains: 'contient',
108
+ not_contains: 'ne contient pas',
109
+ starts_with: 'commence par',
110
+ ends_with: 'se termine par',
111
+ is_any_of: 'est parmi',
112
+ is_none_of: "n'est pas parmi",
113
+ gt: 'est supérieur à',
114
+ gte: 'est supérieur ou égal à',
115
+ lt: 'est inférieur à',
116
+ lte: 'est inférieur ou égal à',
117
+ between: 'est entre',
118
+ is_known: 'est connu',
119
+ is_unknown: 'est inconnu',
120
+ date_preset: 'est',
121
+ };
122
+
123
+ export const FILTER_FIELD_DEFINITIONS: FilterFieldDefinition[] = [
124
+ {
125
+ field: 'firstName',
126
+ label: 'Prénom',
127
+ type: 'text',
128
+ group: 'Informations du contact',
129
+ operators: [
130
+ 'equals',
131
+ 'not_equals',
132
+ 'contains',
133
+ 'not_contains',
134
+ 'starts_with',
135
+ 'ends_with',
136
+ 'is_known',
137
+ 'is_unknown',
138
+ ],
139
+ entityTypes: ['contacts'],
140
+ },
141
+ {
142
+ field: 'lastName',
143
+ label: 'Nom',
144
+ type: 'text',
145
+ group: 'Informations du contact',
146
+ operators: [
147
+ 'equals',
148
+ 'not_equals',
149
+ 'contains',
150
+ 'not_contains',
151
+ 'starts_with',
152
+ 'ends_with',
153
+ 'is_known',
154
+ 'is_unknown',
155
+ ],
156
+ entityTypes: ['contacts'],
157
+ },
158
+ {
159
+ field: 'phone',
160
+ label: 'Téléphone',
161
+ type: 'text',
162
+ group: 'Informations du contact',
163
+ operators: ['equals', 'contains', 'starts_with', 'is_known', 'is_unknown'],
164
+ },
165
+ {
166
+ field: 'email',
167
+ label: 'Email',
168
+ type: 'text',
169
+ group: 'Informations du contact',
170
+ operators: [
171
+ 'equals',
172
+ 'not_equals',
173
+ 'contains',
174
+ 'not_contains',
175
+ 'starts_with',
176
+ 'ends_with',
177
+ 'is_known',
178
+ 'is_unknown',
179
+ ],
180
+ },
181
+ {
182
+ field: 'address',
183
+ label: 'Adresse',
184
+ type: 'text',
185
+ group: 'Informations du contact',
186
+ operators: ['contains', 'is_known', 'is_unknown'],
187
+ },
188
+ {
189
+ field: 'city',
190
+ label: 'Ville',
191
+ type: 'text',
192
+ group: 'Informations du contact',
193
+ operators: ['equals', 'not_equals', 'contains', 'starts_with', 'is_known', 'is_unknown'],
194
+ },
195
+ {
196
+ field: 'postalCode',
197
+ label: 'Code postal',
198
+ type: 'text',
199
+ group: 'Informations du contact',
200
+ operators: ['equals', 'starts_with', 'is_known', 'is_unknown'],
201
+ },
202
+ {
203
+ field: 'civility',
204
+ label: 'Civilité',
205
+ type: 'select',
206
+ group: 'Informations du contact',
207
+ operators: ['is_any_of', 'is_none_of'],
208
+ staticOptions: [
209
+ { value: 'M', label: 'M.' },
210
+ { value: 'MME', label: 'Mme' },
211
+ { value: 'MLLE', label: 'Mlle' },
212
+ ],
213
+ entityTypes: ['contacts'],
214
+ },
215
+ {
216
+ field: 'statusId',
217
+ label: 'Statut',
218
+ type: 'select',
219
+ group: 'Statut & Assignation',
220
+ operators: ['is_any_of', 'is_none_of', 'is_known', 'is_unknown'],
221
+ optionsEndpoint: '/api/statuses',
222
+ entityTypes: ['contacts'],
223
+ },
224
+ {
225
+ field: 'origin',
226
+ label: 'Origine',
227
+ type: 'select_or_text',
228
+ group: 'Statut & Assignation',
229
+ operators: [
230
+ 'equals',
231
+ 'not_equals',
232
+ 'is_any_of',
233
+ 'is_none_of',
234
+ 'contains',
235
+ 'is_known',
236
+ 'is_unknown',
237
+ ],
238
+ entityTypes: ['contacts'],
239
+ },
240
+ {
241
+ field: 'assignedCommercialId',
242
+ label: 'Commercial',
243
+ type: 'select',
244
+ group: 'Statut & Assignation',
245
+ operators: ['is_any_of', 'is_none_of', 'is_known', 'is_unknown'],
246
+ optionsEndpoint: '/api/users/list',
247
+ },
248
+ {
249
+ field: 'assignedTeleproId',
250
+ label: 'Télépro',
251
+ type: 'select',
252
+ group: 'Statut & Assignation',
253
+ operators: ['is_any_of', 'is_none_of', 'is_known', 'is_unknown'],
254
+ optionsEndpoint: '/api/users/list',
255
+ },
256
+ {
257
+ field: 'createdById',
258
+ label: 'Créé par',
259
+ type: 'select',
260
+ group: 'Statut & Assignation',
261
+ operators: ['is_any_of', 'is_none_of'],
262
+ optionsEndpoint: '/api/users/list',
263
+ },
264
+ {
265
+ field: 'createdAt',
266
+ label: 'Date de création',
267
+ type: 'date',
268
+ group: 'Dates',
269
+ operators: ['date_preset', 'equals', 'gt', 'gte', 'lt', 'lte', 'between'],
270
+ },
271
+ {
272
+ field: 'updatedAt',
273
+ label: 'Date de modification',
274
+ type: 'date',
275
+ group: 'Dates',
276
+ operators: ['date_preset', 'equals', 'gt', 'gte', 'lt', 'lte', 'between'],
277
+ },
278
+ {
279
+ field: 'region',
280
+ label: 'Région',
281
+ type: 'select',
282
+ group: 'Géographie',
283
+ operators: ['is_any_of', 'is_none_of'],
284
+ entityTypes: ['contacts'],
285
+ },
286
+ {
287
+ field: 'department',
288
+ label: 'Département',
289
+ type: 'select',
290
+ group: 'Géographie',
291
+ operators: ['is_any_of', 'is_none_of'],
292
+ entityTypes: ['contacts'],
293
+ },
294
+ {
295
+ field: 'name',
296
+ label: 'Nom',
297
+ type: 'text',
298
+ group: "Informations de l'entreprise",
299
+ operators: [
300
+ 'equals',
301
+ 'not_equals',
302
+ 'contains',
303
+ 'not_contains',
304
+ 'starts_with',
305
+ 'ends_with',
306
+ 'is_known',
307
+ 'is_unknown',
308
+ ],
309
+ entityTypes: ['companies'],
310
+ },
311
+ {
312
+ field: 'siret',
313
+ label: 'SIRET',
314
+ type: 'text',
315
+ group: "Informations de l'entreprise",
316
+ operators: ['equals', 'contains', 'starts_with', 'is_known', 'is_unknown'],
317
+ entityTypes: ['companies'],
318
+ },
319
+ {
320
+ field: 'industry',
321
+ label: 'Secteur',
322
+ type: 'text',
323
+ group: "Informations de l'entreprise",
324
+ operators: ['equals', 'not_equals', 'contains', 'is_known', 'is_unknown'],
325
+ entityTypes: ['companies'],
326
+ },
327
+ {
328
+ field: 'website',
329
+ label: 'Site web',
330
+ type: 'text',
331
+ group: "Informations de l'entreprise",
332
+ operators: ['contains', 'is_known', 'is_unknown'],
333
+ entityTypes: ['companies'],
334
+ },
335
+ ];
336
+
337
+ export interface ContactViewData {
338
+ id: string;
339
+ name: string;
340
+ userId: string;
341
+ user?: { id: string; name: string };
342
+ isPublic: boolean;
343
+ isDefault: boolean;
344
+ entityType: 'contacts' | 'companies';
345
+ filters: ViewFilter[];
346
+ columns: ViewColumn[] | null;
347
+ sortConfig: ViewSortConfig | null;
348
+ pinOrder: number | null;
349
+ createdAt: string;
350
+ updatedAt: string;
351
+ }
@@ -0,0 +1,52 @@
1
+ export interface YousignSignatureRequest {
2
+ id: string;
3
+ name: string;
4
+ status: 'draft' | 'ongoing' | 'done' | 'expired' | 'declined' | 'canceled';
5
+ created_at: string;
6
+ updated_at: string;
7
+ expires_at: string;
8
+ delivery_mode: 'email' | 'none';
9
+ documents: YousignDocument[];
10
+ signers: YousignSigner[];
11
+ }
12
+
13
+ export interface YousignDocument {
14
+ id: string;
15
+ name: string;
16
+ nature: string;
17
+ created_at: string;
18
+ }
19
+
20
+ export interface YousignSigner {
21
+ id: string;
22
+ info: {
23
+ first_name: string;
24
+ last_name: string;
25
+ email: string;
26
+ phone_number?: string;
27
+ locale: string;
28
+ };
29
+ signature_link: string;
30
+ status: 'initiated' | 'notified' | 'processing' | 'signed' | 'declined' | 'error';
31
+ signed_at?: string;
32
+ }
33
+
34
+ export interface YousignWebhookEvent {
35
+ event_id: string;
36
+ event_name: string;
37
+ event_time: string;
38
+ subscription_id: string;
39
+ subscription_description: string;
40
+ sandbox: boolean;
41
+ data: {
42
+ signature_request: {
43
+ id: string;
44
+ status: string;
45
+ signed_at?: string;
46
+ };
47
+ signer?: {
48
+ id: string;
49
+ status: string;
50
+ };
51
+ };
52
+ }
@@ -3,6 +3,18 @@
3
3
  {
4
4
  "path": "/api/workflows/process",
5
5
  "schedule": "* * * * *"
6
+ },
7
+ {
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 * * *"
6
18
  }
7
19
  ]
8
20
  }