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
|
@@ -7,10 +7,7 @@ import { Loader2 } from 'lucide-react';
|
|
|
7
7
|
|
|
8
8
|
export function Skeleton({ className }: { className?: string }) {
|
|
9
9
|
return (
|
|
10
|
-
<div
|
|
11
|
-
className={cn('animate-pulse rounded bg-muted', className)}
|
|
12
|
-
aria-label="Chargement..."
|
|
13
|
-
/>
|
|
10
|
+
<div className={cn('bg-muted animate-pulse rounded', className)} aria-label="Chargement..." />
|
|
14
11
|
);
|
|
15
12
|
}
|
|
16
13
|
|
|
@@ -27,7 +24,7 @@ interface SpinnerProps {
|
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
export function Spinner({ size = 'lg', className }: Readonly<SpinnerProps>) {
|
|
30
|
-
return <Loader2 className={cn('animate-spin
|
|
27
|
+
return <Loader2 className={cn('text-primary animate-spin', SPINNER_SIZES[size], className)} />;
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
interface PageLoaderProps {
|
|
@@ -40,7 +37,7 @@ export function PageLoader({ text = 'Chargement...', className }: Readonly<PageL
|
|
|
40
37
|
<div className={cn('flex h-full items-center justify-center py-12', className)}>
|
|
41
38
|
<div className="text-center">
|
|
42
39
|
<Spinner size="lg" className="mx-auto" />
|
|
43
|
-
<p className="mt-3 text-sm
|
|
40
|
+
<p className="text-muted-foreground mt-3 text-sm">{text}</p>
|
|
44
41
|
</div>
|
|
45
42
|
</div>
|
|
46
43
|
);
|
|
@@ -67,7 +64,7 @@ export function ListPageSkeleton({
|
|
|
67
64
|
}: Readonly<ListPageSkeletonProps>) {
|
|
68
65
|
return (
|
|
69
66
|
<div className="h-full">
|
|
70
|
-
<div className="flex items-center justify-between border-b
|
|
67
|
+
<div className="border-border bg-card flex items-center justify-between border-b px-4 py-4 sm:px-6">
|
|
71
68
|
<div>
|
|
72
69
|
<Skeleton className={cn('h-7', headerWidth)} />
|
|
73
70
|
<Skeleton className={cn('mt-1 h-4', descriptionWidth)} />
|
|
@@ -101,43 +98,43 @@ export function ListPageSkeleton({
|
|
|
101
98
|
|
|
102
99
|
export function ContactTableSkeleton() {
|
|
103
100
|
return (
|
|
104
|
-
<div className="overflow-x-auto rounded-lg border
|
|
105
|
-
<table className="min-w-full divide-y
|
|
101
|
+
<div className="border-border bg-card overflow-x-auto rounded-lg border shadow-(--shadow-card)">
|
|
102
|
+
<table className="divide-border min-w-full divide-y">
|
|
106
103
|
<thead className="bg-muted">
|
|
107
104
|
<tr>
|
|
108
105
|
<th className="px-3 py-3 sm:px-6">
|
|
109
106
|
<Skeleton className="h-4 w-4" />
|
|
110
107
|
</th>
|
|
111
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
108
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
112
109
|
Contact
|
|
113
110
|
</th>
|
|
114
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
111
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
115
112
|
Téléphone
|
|
116
113
|
</th>
|
|
117
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
114
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
118
115
|
Email
|
|
119
116
|
</th>
|
|
120
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
117
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
121
118
|
Statut
|
|
122
119
|
</th>
|
|
123
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
120
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
124
121
|
Origine
|
|
125
122
|
</th>
|
|
126
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
123
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
127
124
|
COMMERCIAL
|
|
128
125
|
</th>
|
|
129
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
126
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
130
127
|
TÉLÉPRO
|
|
131
128
|
</th>
|
|
132
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
129
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
133
130
|
CRÉÉ LE
|
|
134
131
|
</th>
|
|
135
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
132
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
136
133
|
MODIFIÉ LE
|
|
137
134
|
</th>
|
|
138
135
|
</tr>
|
|
139
136
|
</thead>
|
|
140
|
-
<tbody className="divide-
|
|
137
|
+
<tbody className="divide-border bg-card divide-y">
|
|
141
138
|
{Array.from({ length: 8 }).map((_, i) => (
|
|
142
139
|
<tr key={i} className="hover:bg-muted/70">
|
|
143
140
|
<td className="px-3 py-4 whitespace-nowrap sm:px-6">
|
|
@@ -188,7 +185,7 @@ export function ContactCardsSkeleton() {
|
|
|
188
185
|
return (
|
|
189
186
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
190
187
|
{Array.from({ length: 9 }).map((_, i) => (
|
|
191
|
-
<div key={i} className="
|
|
188
|
+
<div key={i} className="border-border bg-card rounded-lg border p-6 shadow-(--shadow-card)">
|
|
192
189
|
{/* En-tête */}
|
|
193
190
|
<div className="mb-4 flex items-start justify-between">
|
|
194
191
|
<div className="flex items-center gap-3">
|
|
@@ -226,7 +223,7 @@ export function ContactCardsSkeleton() {
|
|
|
226
223
|
</div>
|
|
227
224
|
|
|
228
225
|
{/* Pied de carte avec utilisateurs assignés */}
|
|
229
|
-
<div className="flex items-start justify-between border-t
|
|
226
|
+
<div className="border-border/70 flex items-start justify-between border-t pt-4">
|
|
230
227
|
<div className="space-y-2">
|
|
231
228
|
<div className="flex items-center gap-2">
|
|
232
229
|
<Skeleton className="h-7 w-7 rounded-full" />
|
|
@@ -250,12 +247,12 @@ export function ContactCardsSkeleton() {
|
|
|
250
247
|
|
|
251
248
|
export function AgendaMonthSkeleton() {
|
|
252
249
|
return (
|
|
253
|
-
<div className="
|
|
254
|
-
<div className="grid grid-cols-7 border-b
|
|
250
|
+
<div className="border-border bg-card rounded-lg border shadow-(--shadow-card)">
|
|
251
|
+
<div className="border-border grid grid-cols-7 border-b">
|
|
255
252
|
{['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'].map((day) => (
|
|
256
253
|
<div
|
|
257
254
|
key={day}
|
|
258
|
-
className="border-
|
|
255
|
+
className="border-border text-foreground border-r p-3 text-center text-sm font-semibold last:border-r-0"
|
|
259
256
|
>
|
|
260
257
|
{day}
|
|
261
258
|
</div>
|
|
@@ -265,7 +262,7 @@ export function AgendaMonthSkeleton() {
|
|
|
265
262
|
{Array.from({ length: 42 }).map((_, i) => (
|
|
266
263
|
<div
|
|
267
264
|
key={i}
|
|
268
|
-
className="min-h-[100px] border-r border-b
|
|
265
|
+
className="border-border min-h-[100px] border-r border-b p-2 last:border-r-0"
|
|
269
266
|
>
|
|
270
267
|
<Skeleton className="mb-2 h-5 w-6" />
|
|
271
268
|
<div className="space-y-1">
|
|
@@ -288,31 +285,31 @@ export function AgendaWeekSkeleton() {
|
|
|
288
285
|
};
|
|
289
286
|
|
|
290
287
|
return (
|
|
291
|
-
<div className="overflow-auto rounded-lg border
|
|
292
|
-
<div className="grid grid-cols-8 border-b
|
|
288
|
+
<div className="border-border bg-card overflow-auto rounded-lg border shadow-(--shadow-card)">
|
|
289
|
+
<div className="border-border bg-muted text-muted-foreground grid grid-cols-8 border-b text-xs font-medium">
|
|
293
290
|
<div className="px-3 py-2 text-right">(UTC+01:00) Hr</div>
|
|
294
291
|
{Array.from({ length: 7 }).map((_, i) => (
|
|
295
|
-
<div key={i} className="border-
|
|
292
|
+
<div key={i} className="border-border border-l px-3 py-2 text-center">
|
|
296
293
|
<Skeleton className="mx-auto h-4 w-12" />
|
|
297
294
|
<Skeleton className="mx-auto mt-1 h-8 w-8 rounded-full" />
|
|
298
295
|
</div>
|
|
299
296
|
))}
|
|
300
297
|
</div>
|
|
301
298
|
<div className="grid grid-cols-8 text-xs">
|
|
302
|
-
<div className="border-
|
|
299
|
+
<div className="border-border bg-muted border-r">
|
|
303
300
|
{HOURS.map((hour) => (
|
|
304
301
|
<div
|
|
305
302
|
key={hour}
|
|
306
|
-
className="flex h-16 items-start justify-end border-b
|
|
303
|
+
className="border-border flex h-16 items-start justify-end border-b pr-2"
|
|
307
304
|
>
|
|
308
305
|
<Skeleton className="h-3 w-10" />
|
|
309
306
|
</div>
|
|
310
307
|
))}
|
|
311
308
|
</div>
|
|
312
309
|
{Array.from({ length: 7 }).map((_, dayIndex) => (
|
|
313
|
-
<div key={dayIndex} className="border-
|
|
310
|
+
<div key={dayIndex} className="border-border border-l">
|
|
314
311
|
{HOURS.map((hour, hourIndex) => (
|
|
315
|
-
<div key={hour} className="relative h-16 border-b
|
|
312
|
+
<div key={hour} className="border-border/70 relative h-16 border-b px-1.5 py-0.5">
|
|
316
313
|
{shouldShowSkeleton(dayIndex, hourIndex) && (
|
|
317
314
|
<Skeleton className="h-12 w-full rounded" />
|
|
318
315
|
)}
|
|
@@ -329,7 +326,7 @@ export function AgendaDaySkeleton() {
|
|
|
329
326
|
return (
|
|
330
327
|
<div className="space-y-4">
|
|
331
328
|
{Array.from({ length: 5 }).map((_, i) => (
|
|
332
|
-
<div key={i} className="
|
|
329
|
+
<div key={i} className="border-border bg-card rounded-lg border p-4 shadow-(--shadow-card)">
|
|
333
330
|
<div className="flex items-start justify-between">
|
|
334
331
|
<div className="flex-1">
|
|
335
332
|
<div className="flex items-center gap-2">
|
|
@@ -357,28 +354,28 @@ export function AgendaDaySkeleton() {
|
|
|
357
354
|
|
|
358
355
|
export function UsersTableSkeleton() {
|
|
359
356
|
return (
|
|
360
|
-
<div className="overflow-x-auto rounded-lg border
|
|
361
|
-
<table className="min-w-full divide-y
|
|
357
|
+
<div className="border-border bg-card overflow-x-auto rounded-lg border shadow-(--shadow-card)">
|
|
358
|
+
<table className="divide-border min-w-full divide-y">
|
|
362
359
|
<thead className="bg-muted">
|
|
363
360
|
<tr>
|
|
364
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
361
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
365
362
|
Utilisateur
|
|
366
363
|
</th>
|
|
367
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
364
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
368
365
|
Email
|
|
369
366
|
</th>
|
|
370
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
367
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
371
368
|
Rôle
|
|
372
369
|
</th>
|
|
373
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
370
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
374
371
|
Email vérifié
|
|
375
372
|
</th>
|
|
376
|
-
<th className="px-3 py-3 text-left text-xs font-medium tracking-wider
|
|
373
|
+
<th className="text-muted-foreground px-3 py-3 text-left text-xs font-medium tracking-wider uppercase sm:px-6">
|
|
377
374
|
Compte
|
|
378
375
|
</th>
|
|
379
376
|
</tr>
|
|
380
377
|
</thead>
|
|
381
|
-
<tbody className="divide-
|
|
378
|
+
<tbody className="divide-border bg-card divide-y">
|
|
382
379
|
{Array.from({ length: 6 }).map((_, i) => (
|
|
383
380
|
<tr key={i} className="hover:bg-muted/70">
|
|
384
381
|
<td className="px-3 py-4 whitespace-nowrap sm:px-6">
|
|
@@ -416,7 +413,7 @@ export function TemplatesPageSkeleton() {
|
|
|
416
413
|
return (
|
|
417
414
|
<div className="h-full">
|
|
418
415
|
{/* Header Skeleton */}
|
|
419
|
-
<div className="border-
|
|
416
|
+
<div className="border-border bg-card border-b px-4 py-4 sm:px-6 lg:px-8">
|
|
420
417
|
<div className="flex items-center justify-between">
|
|
421
418
|
<div className="space-y-2">
|
|
422
419
|
<Skeleton className="h-8 w-48" />
|
|
@@ -439,7 +436,7 @@ export function TemplatesPageSkeleton() {
|
|
|
439
436
|
{Array.from({ length: 6 }).map((_, i) => (
|
|
440
437
|
<div
|
|
441
438
|
key={i}
|
|
442
|
-
className="
|
|
439
|
+
className="border-border bg-card rounded-lg border p-4 shadow-(--shadow-card) transition-shadow"
|
|
443
440
|
>
|
|
444
441
|
<div className="flex items-start justify-between">
|
|
445
442
|
<div className="flex-1">
|
|
@@ -33,13 +33,13 @@ function AccordionTrigger({
|
|
|
33
33
|
<AccordionPrimitive.Trigger
|
|
34
34
|
data-slot="accordion-trigger"
|
|
35
35
|
className={cn(
|
|
36
|
-
'focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-
|
|
36
|
+
'focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-colors outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',
|
|
37
37
|
className,
|
|
38
38
|
)}
|
|
39
39
|
{...props}
|
|
40
40
|
>
|
|
41
41
|
{children}
|
|
42
|
-
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
|
|
42
|
+
<ChevronDownIcon aria-hidden="true" className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
|
|
43
43
|
</AccordionPrimitive.Trigger>
|
|
44
44
|
</AccordionPrimitive.Header>
|
|
45
45
|
);
|
|
@@ -50,7 +50,7 @@ function AlertDialogContent({
|
|
|
50
50
|
<AlertDialogPrimitive.Content
|
|
51
51
|
data-slot="alert-dialog-content"
|
|
52
52
|
className={cn(
|
|
53
|
-
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
|
|
53
|
+
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg overscroll-contain',
|
|
54
54
|
className,
|
|
55
55
|
)}
|
|
56
56
|
{...props}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Slot } from '@radix-ui/react-slot';
|
|
3
3
|
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
+
import { motion } from 'motion/react';
|
|
4
5
|
|
|
5
6
|
import { cn } from '@/lib/utils';
|
|
6
7
|
|
|
7
8
|
const buttonVariants = cva(
|
|
8
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-
|
|
9
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,background-color,border-color,box-shadow,opacity] duration-(--duration-fast) ease-(--ease-standard) disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
9
10
|
{
|
|
10
11
|
variants: {
|
|
11
12
|
variant: {
|
|
@@ -16,7 +17,7 @@ const buttonVariants = cva(
|
|
|
16
17
|
'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
|
|
17
18
|
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
18
19
|
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
|
19
|
-
link: 'text-primary underline-offset-4 hover:underline',
|
|
20
|
+
link: 'text-primary underline-offset-4 hover:underline active:scale-100',
|
|
20
21
|
},
|
|
21
22
|
size: {
|
|
22
23
|
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
|
@@ -44,15 +45,25 @@ function Button({
|
|
|
44
45
|
VariantProps<typeof buttonVariants> & {
|
|
45
46
|
asChild?: boolean;
|
|
46
47
|
}) {
|
|
47
|
-
const
|
|
48
|
+
const baseClassName = cn(buttonVariants({ variant, size, className }));
|
|
49
|
+
const baseProps = {
|
|
50
|
+
'data-slot': 'button',
|
|
51
|
+
'data-variant': variant,
|
|
52
|
+
'data-size': size,
|
|
53
|
+
className: baseClassName,
|
|
54
|
+
};
|
|
48
55
|
|
|
56
|
+
if (asChild) {
|
|
57
|
+
return <Slot {...baseProps} {...props} />;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// motion/react redéfinit des handlers (onDrag, onAnimationStart, etc.) ; cast pour compatibilité avec HTML button
|
|
49
61
|
return (
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
{...props}
|
|
62
|
+
<motion.button
|
|
63
|
+
{...baseProps}
|
|
64
|
+
whileHover={{ scale: 1.02 }}
|
|
65
|
+
whileTap={{ scale: 0.98 }}
|
|
66
|
+
{...(props as React.ComponentPropsWithoutRef<typeof motion.button>)}
|
|
56
67
|
/>
|
|
57
68
|
);
|
|
58
69
|
}
|
|
@@ -86,7 +86,7 @@ export function Dropdown({
|
|
|
86
86
|
|
|
87
87
|
return (
|
|
88
88
|
<div className="lexkit-dropdown" ref={dropdownRef}>
|
|
89
|
-
<
|
|
89
|
+
<button type="button" onClick={() => onOpenChange(!isOpen)}>{trigger}</button>
|
|
90
90
|
{isOpen && <div className="lexkit-dropdown-content">{children}</div>}
|
|
91
91
|
</div>
|
|
92
92
|
);
|