ptechcore_ui 1.0.1 → 1.0.3

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 (62) hide show
  1. package/dist/index.cjs +1396 -0
  2. package/dist/index.d.cts +62 -0
  3. package/dist/index.d.ts +62 -0
  4. package/dist/index.js +1366 -0
  5. package/package.json +14 -1
  6. package/eslint.config.js +0 -28
  7. package/index.html +0 -78
  8. package/postcss.config.js +0 -6
  9. package/src/App.tsx +0 -156
  10. package/src/assets/imgs/login_illustration.png +0 -0
  11. package/src/components/common/Buttons.tsx +0 -39
  12. package/src/components/common/Cards.tsx +0 -18
  13. package/src/components/common/FDrawer.tsx +0 -2448
  14. package/src/components/common/FDrawer.types.ts +0 -191
  15. package/src/components/common/Inputs.tsx +0 -409
  16. package/src/components/common/Modals.tsx +0 -41
  17. package/src/components/common/Navigations.tsx +0 -0
  18. package/src/components/common/Toast.tsx +0 -0
  19. package/src/components/demo/ToastDemo.tsx +0 -73
  20. package/src/components/layout/Header.tsx +0 -202
  21. package/src/components/layout/ModernDoubleSidebarLayout.tsx +0 -719
  22. package/src/components/layout/PrivateLayout.tsx +0 -52
  23. package/src/components/layout/Sidebar.tsx +0 -182
  24. package/src/components/ui/Toast.tsx +0 -93
  25. package/src/contexts/SessionContext.tsx +0 -77
  26. package/src/contexts/ThemeContext.tsx +0 -58
  27. package/src/contexts/ToastContext.tsx +0 -94
  28. package/src/index.css +0 -3
  29. package/src/index.ts +0 -10
  30. package/src/main.tsx +0 -10
  31. package/src/models/Organization.ts +0 -47
  32. package/src/models/Plan.ts +0 -42
  33. package/src/models/User.ts +0 -23
  34. package/src/pages/Analytics.tsx +0 -101
  35. package/src/pages/CreateOrganization.tsx +0 -215
  36. package/src/pages/Dashboard.tsx +0 -15
  37. package/src/pages/Home.tsx +0 -12
  38. package/src/pages/Profile.tsx +0 -313
  39. package/src/pages/Settings.tsx +0 -382
  40. package/src/pages/Team.tsx +0 -180
  41. package/src/pages/auth/Login.tsx +0 -140
  42. package/src/pages/auth/Register.tsx +0 -302
  43. package/src/pages/organizations/DetailEntity.tsx +0 -1002
  44. package/src/pages/organizations/DetailOrganizations.tsx +0 -1628
  45. package/src/pages/organizations/ListOrganizations.tsx +0 -270
  46. package/src/pages/pricings/CartPlan.tsx +0 -486
  47. package/src/pages/pricings/ListPricing.tsx +0 -321
  48. package/src/pages/users/CreateUser.tsx +0 -448
  49. package/src/pages/users/ListUsers.tsx +0 -0
  50. package/src/services/AuthServices.ts +0 -94
  51. package/src/services/OrganizationServices.ts +0 -61
  52. package/src/services/PlanSubscriptionServices.tsx +0 -137
  53. package/src/services/UserServices.ts +0 -36
  54. package/src/services/api.ts +0 -64
  55. package/src/styles/theme.ts +0 -383
  56. package/src/utils/utils.ts +0 -48
  57. package/src/vite-env.d.ts +0 -1
  58. package/tailwind.config.js +0 -158
  59. package/tsconfig.app.json +0 -24
  60. package/tsconfig.json +0 -31
  61. package/tsconfig.node.json +0 -22
  62. package/vite.config.ts +0 -10
package/dist/index.js ADDED
@@ -0,0 +1,1366 @@
1
+ // src/components/common/Buttons.tsx
2
+ import { jsx } from "react/jsx-runtime";
3
+ var PrimaryButton = ({
4
+ loading = false,
5
+ children,
6
+ classname = "",
7
+ ...props
8
+ }) => /* @__PURE__ */ jsx(
9
+ "button",
10
+ {
11
+ type: "submit",
12
+ disabled: loading || props.disabled,
13
+ className: `px-4 py-2 text-sm bg-[#6A8A82] text-white rounded-lg hover:bg-[#5A7A72] transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex justify-center items-center ${classname}`,
14
+ ...props,
15
+ children: loading ? "Connexion en cours..." : children
16
+ }
17
+ );
18
+ var SecondaryButton = ({
19
+ loading = false,
20
+ children,
21
+ ...props
22
+ }) => /* @__PURE__ */ jsx(
23
+ "button",
24
+ {
25
+ type: "button",
26
+ disabled: loading || props.disabled,
27
+ className: "px-4 py-2 bg-[#B87333] text-white rounded-lg hover:bg-[#A66B2A] transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center",
28
+ ...props,
29
+ children: loading ? "Connexion en cours..." : children
30
+ }
31
+ );
32
+ var Buttons_default = PrimaryButton;
33
+
34
+ // src/components/layout/ModernDoubleSidebarLayout.tsx
35
+ import React2, { useState as useState2, useEffect as useEffect2 } from "react";
36
+ import { useLocation, useNavigate } from "react-router-dom";
37
+ import {
38
+ Settings,
39
+ ChevronLeft,
40
+ ChevronRight,
41
+ Search,
42
+ Bell,
43
+ User,
44
+ LogOut,
45
+ Menu,
46
+ X,
47
+ Palette,
48
+ DollarSign,
49
+ HelpCircle
50
+ } from "lucide-react";
51
+
52
+ // src/utils/utils.ts
53
+ import { clsx } from "clsx";
54
+ import { twMerge } from "tailwind-merge";
55
+ function cn(...inputs) {
56
+ return twMerge(clsx(inputs));
57
+ }
58
+
59
+ // src/contexts/ThemeContext.tsx
60
+ import { createContext, useContext, useState, useEffect } from "react";
61
+
62
+ // src/styles/theme.ts
63
+ var elegantTheme = {
64
+ name: "\xC9l\xE9gance Sobre",
65
+ description: "Finance traditionnelle moderne - s\xE9rieux, luxe discret, rassurant",
66
+ colors: {
67
+ primary: "#2E7D69",
68
+ // Vert émeraude
69
+ primaryHover: "#246456",
70
+ primaryLight: "rgba(46, 125, 105, 0.1)",
71
+ secondary: "#D4AF37",
72
+ // Or pâle
73
+ accent: "#D4AF37",
74
+ background: "#F5F5F7",
75
+ // Gris clair neutre
76
+ surface: "#FFFFFF",
77
+ surfaceHover: "#FAFAFA",
78
+ text: {
79
+ primary: "#1E1E2F",
80
+ // Charbon profond
81
+ secondary: "#4A4A5C",
82
+ tertiary: "#C2C7CE",
83
+ // Gris moyen
84
+ inverse: "#FFFFFF"
85
+ },
86
+ border: "#E5E5E7",
87
+ borderLight: "#F0F0F2",
88
+ success: "#2E7D69",
89
+ successLight: "rgba(46, 125, 105, 0.1)",
90
+ error: "#DC3545",
91
+ errorLight: "rgba(220, 53, 69, 0.1)",
92
+ warning: "#D4AF37",
93
+ warningLight: "rgba(212, 175, 55, 0.1)",
94
+ info: "#5B9BD5",
95
+ infoLight: "rgba(91, 155, 213, 0.1)",
96
+ sidebar: {
97
+ bg: "#1E1E2F",
98
+ bgHover: "#252538",
99
+ text: "#C2C7CE",
100
+ textHover: "#FFFFFF",
101
+ border: "rgba(194, 199, 206, 0.1)",
102
+ active: "#2E7D69",
103
+ activeBg: "rgba(46, 125, 105, 0.1)"
104
+ },
105
+ card: {
106
+ bg: "#FFFFFF",
107
+ border: "#E5E5E7",
108
+ shadow: "rgba(30, 30, 47, 0.05)"
109
+ }
110
+ },
111
+ shadows: {
112
+ sm: "0 1px 3px rgba(30, 30, 47, 0.05)",
113
+ md: "0 4px 6px rgba(30, 30, 47, 0.07)",
114
+ lg: "0 10px 15px rgba(30, 30, 47, 0.1)",
115
+ xl: "0 20px 25px rgba(30, 30, 47, 0.12)"
116
+ },
117
+ transitions: {
118
+ fast: "150ms ease",
119
+ normal: "250ms ease",
120
+ slow: "350ms ease"
121
+ },
122
+ borderRadius: {
123
+ sm: "4px",
124
+ md: "8px",
125
+ lg: "12px",
126
+ xl: "16px",
127
+ full: "9999px"
128
+ }
129
+ };
130
+ var fintechTheme = {
131
+ name: "Modern Fintech",
132
+ description: "Moderne, clair, orient\xE9 tableau de bord financier",
133
+ colors: {
134
+ primary: "#27AE60",
135
+ // Vert doux
136
+ primaryHover: "#219A52",
137
+ primaryLight: "rgba(39, 174, 96, 0.1)",
138
+ secondary: "#2C3E50",
139
+ // Bleu nuit désaturé
140
+ accent: "#3498DB",
141
+ background: "#FAFAFA",
142
+ // Blanc cassé
143
+ surface: "#FFFFFF",
144
+ surfaceHover: "#F8F9FA",
145
+ text: {
146
+ primary: "#2C3E50",
147
+ secondary: "#7F8C8D",
148
+ // Gris ardoise
149
+ tertiary: "#95A5A6",
150
+ inverse: "#FFFFFF"
151
+ },
152
+ border: "#E0E6ED",
153
+ borderLight: "#F1F4F7",
154
+ success: "#27AE60",
155
+ successLight: "rgba(39, 174, 96, 0.1)",
156
+ error: "#C0392B",
157
+ // Rouge bourgogne
158
+ errorLight: "rgba(192, 57, 43, 0.1)",
159
+ warning: "#F39C12",
160
+ warningLight: "rgba(243, 156, 18, 0.1)",
161
+ info: "#3498DB",
162
+ infoLight: "rgba(52, 152, 219, 0.1)",
163
+ sidebar: {
164
+ bg: "#2C3E50",
165
+ bgHover: "#34495E",
166
+ text: "#95A5A6",
167
+ textHover: "#FFFFFF",
168
+ border: "rgba(149, 165, 166, 0.1)",
169
+ active: "#27AE60",
170
+ activeBg: "rgba(39, 174, 96, 0.1)"
171
+ },
172
+ card: {
173
+ bg: "#FFFFFF",
174
+ border: "#E0E6ED",
175
+ shadow: "rgba(44, 62, 80, 0.04)"
176
+ }
177
+ },
178
+ shadows: {
179
+ sm: "0 1px 3px rgba(44, 62, 80, 0.04)",
180
+ md: "0 4px 6px rgba(44, 62, 80, 0.06)",
181
+ lg: "0 10px 15px rgba(44, 62, 80, 0.08)",
182
+ xl: "0 20px 25px rgba(44, 62, 80, 0.1)"
183
+ },
184
+ transitions: {
185
+ fast: "150ms ease",
186
+ normal: "250ms ease",
187
+ slow: "350ms ease"
188
+ },
189
+ borderRadius: {
190
+ sm: "4px",
191
+ md: "8px",
192
+ lg: "12px",
193
+ xl: "16px",
194
+ full: "9999px"
195
+ }
196
+ };
197
+ var minimalistTheme = {
198
+ name: "Minimaliste Premium",
199
+ description: "\xC9l\xE9gance minimaliste avec touche premium",
200
+ colors: {
201
+ primary: "#6A8A82",
202
+ // Vert sauge
203
+ primaryHover: "#5A7A72",
204
+ primaryLight: "rgba(106, 138, 130, 0.1)",
205
+ secondary: "#B87333",
206
+ // Cuivre rosé
207
+ accent: "#B87333",
208
+ background: "#ECECEC",
209
+ // Gris clair perle
210
+ surface: "#FFFFFF",
211
+ surfaceHover: "#FAFAFA",
212
+ text: {
213
+ primary: "#191919",
214
+ // Noir fumé
215
+ secondary: "#444444",
216
+ // Anthracite doux
217
+ tertiary: "#767676",
218
+ inverse: "#FFFFFF"
219
+ },
220
+ border: "#D9D9D9",
221
+ borderLight: "#E8E8E8",
222
+ success: "#6A8A82",
223
+ successLight: "rgba(106, 138, 130, 0.1)",
224
+ error: "#B85450",
225
+ errorLight: "rgba(184, 84, 80, 0.1)",
226
+ warning: "#B87333",
227
+ warningLight: "rgba(184, 115, 51, 0.1)",
228
+ info: "#7A99AC",
229
+ infoLight: "rgba(122, 153, 172, 0.1)",
230
+ sidebar: {
231
+ bg: "#191919",
232
+ bgHover: "#242424",
233
+ text: "#999999",
234
+ textHover: "#FFFFFF",
235
+ border: "rgba(153, 153, 153, 0.1)",
236
+ active: "#B87333",
237
+ activeBg: "rgba(184, 115, 51, 0.1)"
238
+ },
239
+ card: {
240
+ bg: "#FFFFFF",
241
+ border: "#D9D9D9",
242
+ shadow: "rgba(25, 25, 25, 0.03)"
243
+ }
244
+ },
245
+ shadows: {
246
+ sm: "0 1px 3px rgba(25, 25, 25, 0.03)",
247
+ md: "0 4px 6px rgba(25, 25, 25, 0.05)",
248
+ lg: "0 10px 15px rgba(25, 25, 25, 0.07)",
249
+ xl: "0 20px 25px rgba(25, 25, 25, 0.09)"
250
+ },
251
+ transitions: {
252
+ fast: "150ms ease",
253
+ normal: "250ms ease",
254
+ slow: "350ms ease"
255
+ },
256
+ borderRadius: {
257
+ sm: "4px",
258
+ md: "8px",
259
+ lg: "12px",
260
+ xl: "16px",
261
+ full: "9999px"
262
+ }
263
+ };
264
+ var neutralOdysseyTheme = {
265
+ name: "Neutral Odyssey",
266
+ description: "Palette haut de gamme pour immobilier - \xE9l\xE9gance neutre et moderne",
267
+ colors: {
268
+ primary: "#373B4D",
269
+ // Gris profond, élégant - Actions fortes
270
+ primaryHover: "#2C2F3D",
271
+ // Version plus sombre pour hover
272
+ primaryLight: "rgba(55, 59, 77, 0.1)",
273
+ secondary: "#BDBFB7",
274
+ // Accents - éléments surlignés, cartes de projet
275
+ accent: "#BDBFB7",
276
+ background: "#ECEDEF",
277
+ // Fond clair principal
278
+ surface: "#ECECEF",
279
+ // Surface des cartes et panneaux
280
+ surfaceHover: "#E6E6E9",
281
+ text: {
282
+ primary: "#373B4D",
283
+ // Texte principal sur fond clair
284
+ secondary: "#949597",
285
+ // Texte secondaire / icônes
286
+ tertiary: "#BDBFB7",
287
+ // Texte tertiaire
288
+ inverse: "#ECECEF"
289
+ // Texte sur fond sombre
290
+ },
291
+ border: "#BDBFB7",
292
+ // Bordures principales
293
+ borderLight: "#E0E0E3",
294
+ // Bordures légères
295
+ success: "#6A8A82",
296
+ // Réutilisation du vert sauge pour succès
297
+ successLight: "rgba(106, 138, 130, 0.1)",
298
+ error: "#B85450",
299
+ errorLight: "rgba(184, 84, 80, 0.1)",
300
+ warning: "#D4AF37",
301
+ // Or pour les avertissements
302
+ warningLight: "rgba(212, 175, 55, 0.1)",
303
+ info: "#7A99AC",
304
+ infoLight: "rgba(122, 153, 172, 0.1)",
305
+ sidebar: {
306
+ bg: "linear-gradient(180deg, #ECECEF 0%, #ECEDEF 100%)",
307
+ // Dégradé vertical
308
+ bgHover: "#E6E6E9",
309
+ text: "#373B4D",
310
+ // Icônes et texte en gris profond
311
+ textHover: "#2C2F3D",
312
+ // Plus sombre au hover
313
+ border: "rgba(189, 191, 183, 0.2)",
314
+ active: "#373B4D",
315
+ // État actif en couleur principale
316
+ activeBg: "rgba(55, 59, 77, 0.1)"
317
+ },
318
+ card: {
319
+ bg: "#ECEDEF",
320
+ // Cartes sur fond légèrement différent
321
+ border: "#BDBFB7",
322
+ // Encadrement des cartes
323
+ shadow: "rgba(55, 59, 77, 0.08)"
324
+ }
325
+ },
326
+ shadows: {
327
+ sm: "0 1px 3px rgba(55, 59, 77, 0.08)",
328
+ md: "0 4px 6px rgba(55, 59, 77, 0.10)",
329
+ lg: "0 10px 15px rgba(55, 59, 77, 0.12)",
330
+ xl: "0 20px 25px rgba(55, 59, 77, 0.15)"
331
+ },
332
+ transitions: {
333
+ fast: "150ms ease",
334
+ normal: "250ms ease",
335
+ slow: "350ms ease"
336
+ },
337
+ borderRadius: {
338
+ sm: "4px",
339
+ md: "8px",
340
+ lg: "12px",
341
+ xl: "16px",
342
+ full: "9999px"
343
+ }
344
+ };
345
+ var themes = {
346
+ elegant: elegantTheme,
347
+ fintech: fintechTheme,
348
+ minimalist: minimalistTheme,
349
+ neutralOdyssey: neutralOdysseyTheme
350
+ };
351
+ var defaultTheme = minimalistTheme;
352
+ var getThemeCSSVariables = (theme) => {
353
+ return {
354
+ "--color-primary": theme.colors.primary,
355
+ "--color-primary-hover": theme.colors.primaryHover,
356
+ "--color-primary-light": theme.colors.primaryLight,
357
+ "--color-secondary": theme.colors.secondary,
358
+ "--color-accent": theme.colors.accent,
359
+ "--color-background": theme.colors.background,
360
+ "--color-surface": theme.colors.surface,
361
+ "--color-surface-hover": theme.colors.surfaceHover,
362
+ "--color-text-primary": theme.colors.text.primary,
363
+ "--color-text-secondary": theme.colors.text.secondary,
364
+ "--color-text-tertiary": theme.colors.text.tertiary,
365
+ "--color-text-inverse": theme.colors.text.inverse,
366
+ "--color-border": theme.colors.border,
367
+ "--color-border-light": theme.colors.borderLight,
368
+ "--color-success": theme.colors.success,
369
+ "--color-success-light": theme.colors.successLight,
370
+ "--color-error": theme.colors.error,
371
+ "--color-error-light": theme.colors.errorLight,
372
+ "--color-warning": theme.colors.warning,
373
+ "--color-warning-light": theme.colors.warningLight,
374
+ "--color-info": theme.colors.info,
375
+ "--color-info-light": theme.colors.infoLight,
376
+ "--shadow-sm": theme.shadows.sm,
377
+ "--shadow-md": theme.shadows.md,
378
+ "--shadow-lg": theme.shadows.lg,
379
+ "--shadow-xl": theme.shadows.xl,
380
+ "--transition-fast": theme.transitions.fast,
381
+ "--transition-normal": theme.transitions.normal,
382
+ "--transition-slow": theme.transitions.slow,
383
+ "--radius-sm": theme.borderRadius.sm,
384
+ "--radius-md": theme.borderRadius.md,
385
+ "--radius-lg": theme.borderRadius.lg,
386
+ "--radius-xl": theme.borderRadius.xl,
387
+ "--radius-full": theme.borderRadius.full
388
+ };
389
+ };
390
+
391
+ // src/contexts/ThemeContext.tsx
392
+ import { jsx as jsx2 } from "react/jsx-runtime";
393
+ var ThemeContext = createContext(void 0);
394
+ var useTheme = () => {
395
+ const context = useContext(ThemeContext);
396
+ if (!context) {
397
+ throw new Error("useTheme must be used within a ThemeProvider");
398
+ }
399
+ return context;
400
+ };
401
+ var ThemeProvider = ({ children }) => {
402
+ const [themeType, setThemeType] = useState(() => {
403
+ const saved = localStorage.getItem("wisebook-theme");
404
+ return saved && saved in themes ? saved : "minimalist";
405
+ });
406
+ const [theme, setThemeState] = useState(themes[themeType] || defaultTheme);
407
+ useEffect(() => {
408
+ const root = document.documentElement;
409
+ const cssVars = getThemeCSSVariables(theme);
410
+ Object.entries(cssVars).forEach(([key, value]) => {
411
+ root.style.setProperty(key, value);
412
+ });
413
+ root.style.backgroundColor = theme.colors.background;
414
+ root.style.color = theme.colors.text.primary;
415
+ localStorage.setItem("wisebook-theme", themeType);
416
+ }, [theme, themeType]);
417
+ const setTheme = (type) => {
418
+ if (type in themes) {
419
+ setThemeType(type);
420
+ setThemeState(themes[type]);
421
+ }
422
+ };
423
+ return /* @__PURE__ */ jsx2(ThemeContext.Provider, { value: { theme, themeType, setTheme }, children });
424
+ };
425
+ var ThemeContext_default = ThemeProvider;
426
+
427
+ // src/components/layout/ModernDoubleSidebarLayout.tsx
428
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
429
+ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "Description du module", primaryMenuItems, secondaryMenuItems }) => {
430
+ const location = useLocation();
431
+ const navigate = useNavigate();
432
+ const { theme, themeType, setTheme } = useTheme();
433
+ const [primaryCollapsed, setPrimaryCollapsed] = useState2(false);
434
+ const [secondaryCollapsed, setSecondaryCollapsed] = useState2(false);
435
+ const [mobileMenuOpen, setMobileMenuOpen] = useState2(false);
436
+ const [selectedModule, setSelectedModule] = useState2("dashboard");
437
+ const [searchQuery, setSearchQuery] = useState2("");
438
+ const [showNotifications, setShowNotifications] = useState2(false);
439
+ const [showUserMenu, setShowUserMenu] = useState2(false);
440
+ const [showThemeMenu, setShowThemeMenu] = useState2(false);
441
+ const [notifications, setNotifications] = useState2([
442
+ {
443
+ id: "1",
444
+ title: "Nouvelle facture",
445
+ message: "3 nouvelles factures en attente de validation",
446
+ type: "info",
447
+ timestamp: /* @__PURE__ */ new Date(),
448
+ read: false
449
+ },
450
+ {
451
+ id: "2",
452
+ title: "Cl\xF4ture mensuelle",
453
+ message: "La cl\xF4ture de janvier est pr\xEAte",
454
+ type: "success",
455
+ timestamp: /* @__PURE__ */ new Date(),
456
+ read: false
457
+ }
458
+ ]);
459
+ useEffect2(() => {
460
+ const handleKeyDown = (e) => {
461
+ if (e.altKey && e.key === "m") {
462
+ e.preventDefault();
463
+ setMobileMenuOpen((prev) => !prev);
464
+ }
465
+ if (e.altKey && e.key === "s") {
466
+ e.preventDefault();
467
+ document.getElementById("global-search")?.focus();
468
+ }
469
+ if (e.key === "Escape") {
470
+ setShowNotifications(false);
471
+ setShowUserMenu(false);
472
+ setShowThemeMenu(false);
473
+ setMobileMenuOpen(false);
474
+ }
475
+ };
476
+ document.addEventListener("keydown", handleKeyDown);
477
+ return () => document.removeEventListener("keydown", handleKeyDown);
478
+ }, []);
479
+ useEffect2(() => {
480
+ const path = location.pathname;
481
+ const moduleMatch = path.match(/^\/([^/]+)/);
482
+ if (moduleMatch) {
483
+ const moduleId = moduleMatch[1];
484
+ const routeMapping = {
485
+ "dashboard": "dashboard",
486
+ "organizations": "organizations",
487
+ "entities": "entities"
488
+ };
489
+ setSelectedModule(routeMapping[moduleId] || "dashboard");
490
+ }
491
+ }, [location]);
492
+ const handleThemeChange = (type) => {
493
+ setTheme(type);
494
+ setShowThemeMenu(false);
495
+ };
496
+ const isActive = (path) => location.pathname === path;
497
+ const isModuleActive = (moduleId) => selectedModule === moduleId;
498
+ const getBreadcrumbs = () => {
499
+ const paths = location.pathname.split("/").filter(Boolean);
500
+ const breadcrumbs = [{ label: "Accueil", path: "/" }];
501
+ paths.forEach((path, index) => {
502
+ const fullPath = "/" + paths.slice(0, index + 1).join("/");
503
+ const module = primaryMenuItems.find((m) => m.id === path);
504
+ const label = module ? module.label : path.charAt(0).toUpperCase() + path.slice(1);
505
+ breadcrumbs.push({ label, path: fullPath });
506
+ });
507
+ return breadcrumbs;
508
+ };
509
+ const markNotificationAsRead = (id) => {
510
+ setNotifications(
511
+ (prev) => prev.map((n) => n.id === id ? { ...n, read: true } : n)
512
+ );
513
+ };
514
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-screen bg-[var(--color-background)] overflow-hidden", children: [
515
+ /* @__PURE__ */ jsx3(
516
+ "a",
517
+ {
518
+ href: "#main-content",
519
+ className: "sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 z-50 bg-[var(--color-primary)] text-[var(--color-background)] px-4 py-2 rounded",
520
+ children: "Aller au contenu principal"
521
+ }
522
+ ),
523
+ /* @__PURE__ */ jsxs(
524
+ "aside",
525
+ {
526
+ className: cn(
527
+ "hidden lg:flex flex-col bg-[var(--color-sidebar-bg)] transition-all duration-300",
528
+ primaryCollapsed ? "w-20" : "w-64"
529
+ ),
530
+ role: "navigation",
531
+ "aria-label": "Navigation principale",
532
+ children: [
533
+ /* @__PURE__ */ jsxs("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-sidebar-border)]", children: [
534
+ /* @__PURE__ */ jsxs("div", { className: cn(
535
+ "flex items-center gap-3",
536
+ primaryCollapsed && "justify-center"
537
+ ), children: [
538
+ /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx3("span", { className: "text-[var(--color-background)] font-bold text-xl", children: "W" }) }),
539
+ !primaryCollapsed && /* @__PURE__ */ jsxs("div", { children: [
540
+ /* @__PURE__ */ jsx3("h1", { className: "text-[var(--color-sidebar-text)] font-bold text-lg", children: module_name }),
541
+ /* @__PURE__ */ jsx3("p", { className: "text-[var(--color-sidebar-text-secondary)] text-xs", children: module_description })
542
+ ] })
543
+ ] }),
544
+ /* @__PURE__ */ jsx3(
545
+ "button",
546
+ {
547
+ onClick: () => setPrimaryCollapsed(!primaryCollapsed),
548
+ className: "text-[var(--color-sidebar-text-secondary)] hover:text-[var(--color-sidebar-text)] transition-colors",
549
+ "aria-label": primaryCollapsed ? "D\xE9velopper le menu" : "R\xE9duire le menu",
550
+ "aria-expanded": !primaryCollapsed,
551
+ children: /* @__PURE__ */ jsx3(ChevronLeft, { className: cn(
552
+ "w-5 h-5 transition-transform",
553
+ primaryCollapsed && "rotate-180"
554
+ ) })
555
+ }
556
+ )
557
+ ] }),
558
+ /* @__PURE__ */ jsx3(
559
+ "nav",
560
+ {
561
+ className: "flex-1 py-4 overflow-y-auto",
562
+ role: "menubar",
563
+ "aria-label": "Modules principaux",
564
+ children: primaryMenuItems.map((item) => /* @__PURE__ */ jsxs(
565
+ "button",
566
+ {
567
+ onClick: () => {
568
+ if (item.path) {
569
+ navigate(item.path);
570
+ } else {
571
+ setSelectedModule(item.id);
572
+ }
573
+ },
574
+ className: cn(
575
+ "w-full flex items-center gap-3 px-4 py-3 transition-all duration-200",
576
+ "hover:bg-[var(--color-sidebar-hover)] relative group",
577
+ isModuleActive(item.id) && "bg-[var(--color-sidebar-active)] border-l-4 border-[var(--color-primary)]",
578
+ primaryCollapsed && "justify-center"
579
+ ),
580
+ role: "menuitem",
581
+ "aria-label": item.ariaLabel || item.label,
582
+ "aria-current": isModuleActive(item.id) ? "page" : void 0,
583
+ children: [
584
+ /* @__PURE__ */ jsx3("div", { className: cn(
585
+ "transition-colors",
586
+ isModuleActive(item.id) ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)] group-hover:text-[var(--color-sidebar-text)]"
587
+ ), children: item.icon }),
588
+ !primaryCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
589
+ /* @__PURE__ */ jsx3("span", { className: cn(
590
+ "flex-1 text-left text-sm font-medium transition-colors",
591
+ isModuleActive(item.id) ? "text-[var(--color-sidebar-text)]" : "text-[var(--color-sidebar-text-secondary)] group-hover:text-[var(--color-sidebar-text)]"
592
+ ), children: item.label }),
593
+ item.badge && /* @__PURE__ */ jsx3("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-[var(--color-background)] rounded-full", children: item.badge })
594
+ ] }),
595
+ primaryCollapsed && /* @__PURE__ */ jsx3("div", { className: "absolute left-full ml-2 px-2 py-1 bg-[var(--color-sidebar-active)] text-[var(--color-sidebar-text)] text-xs rounded opacity-0 group-hover:opacity-100 pointer-events-none whitespace-nowrap z-50", children: item.label })
596
+ ]
597
+ },
598
+ item.id
599
+ ))
600
+ }
601
+ ),
602
+ /* @__PURE__ */ jsx3("div", { className: "p-4 border-t border-[var(--color-sidebar-border)]", children: /* @__PURE__ */ jsxs("div", { className: cn(
603
+ "flex items-center gap-3",
604
+ primaryCollapsed && "justify-center"
605
+ ), children: [
606
+ /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 bg-[var(--color-sidebar-avatar-bg)] rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx3(User, { className: "w-5 h-5 text-[var(--color-sidebar-text-secondary)]" }) }),
607
+ !primaryCollapsed && /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
608
+ /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium text-[var(--color-sidebar-text)]", children: "Admin" }),
609
+ /* @__PURE__ */ jsx3("p", { className: "text-xs text-[var(--color-sidebar-text-secondary)]", children: "admin@wisebook.com" })
610
+ ] })
611
+ ] }) })
612
+ ]
613
+ }
614
+ ),
615
+ secondaryMenuItems[selectedModule] && /* @__PURE__ */ jsxs(Fragment, { children: [
616
+ secondaryCollapsed && /* @__PURE__ */ jsx3(
617
+ "button",
618
+ {
619
+ onClick: () => setSecondaryCollapsed(false),
620
+ className: "hidden lg:flex items-center justify-center w-12 h-full bg-[var(--color-background)] border-r border-[var(--color-border)] hover:bg-[var(--color-surface-hover)] transition-colors",
621
+ "aria-label": "Ouvrir le sous-menu",
622
+ children: /* @__PURE__ */ jsx3(ChevronRight, { className: "w-5 h-5 text-[var(--color-text-tertiary)]" })
623
+ }
624
+ ),
625
+ /* @__PURE__ */ jsxs(
626
+ "aside",
627
+ {
628
+ className: cn(
629
+ "hidden lg:flex flex-col bg-[var(--color-background)] border-r border-[var(--color-border)] transition-all duration-300",
630
+ secondaryCollapsed ? "w-0 overflow-hidden" : "w-64"
631
+ ),
632
+ role: "navigation",
633
+ "aria-label": "Navigation secondaire",
634
+ children: [
635
+ /* @__PURE__ */ jsxs("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-border)]", children: [
636
+ /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold text-[var(--color-text-secondary)] uppercase tracking-wider whitespace-nowrap", children: primaryMenuItems.find((item) => item.id === selectedModule)?.label }),
637
+ /* @__PURE__ */ jsx3(
638
+ "button",
639
+ {
640
+ onClick: () => setSecondaryCollapsed(!secondaryCollapsed),
641
+ className: "text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] flex-shrink-0",
642
+ "aria-label": secondaryCollapsed ? "D\xE9velopper le sous-menu" : "R\xE9duire le sous-menu",
643
+ children: /* @__PURE__ */ jsx3(ChevronLeft, { className: cn(
644
+ "w-4 h-4 transition-transform",
645
+ secondaryCollapsed && "rotate-180"
646
+ ) })
647
+ }
648
+ )
649
+ ] }),
650
+ /* @__PURE__ */ jsx3(
651
+ "nav",
652
+ {
653
+ className: "flex-1 py-4 overflow-y-auto",
654
+ role: "menu",
655
+ "aria-label": "Sous-navigation",
656
+ children: secondaryMenuItems[selectedModule]?.map((item) => /* @__PURE__ */ jsxs(
657
+ "button",
658
+ {
659
+ onClick: () => item.path && navigate(item.path),
660
+ className: cn(
661
+ "w-full flex items-center gap-3 px-4 py-2.5 transition-all duration-200",
662
+ "hover:bg-[var(--color-surface-hover)]",
663
+ isActive(item.path || "") && "bg-[var(--color-primary-light)] border-l-4 border-[var(--color-primary)]"
664
+ ),
665
+ role: "menuitem",
666
+ "aria-current": isActive(item.path || "") ? "page" : void 0,
667
+ children: [
668
+ item.icon && /* @__PURE__ */ jsx3("div", { className: cn(
669
+ "transition-colors",
670
+ isActive(item.path || "") ? "text-[var(--color-primary)]" : "text-[var(--color-text-tertiary)]"
671
+ ), children: item.icon }),
672
+ /* @__PURE__ */ jsx3("span", { className: cn(
673
+ "flex-1 text-left text-sm",
674
+ isActive(item.path || "") ? "text-[var(--color-primary)] font-medium" : "text-[var(--color-text-secondary)]"
675
+ ), children: item.label }),
676
+ item.badge && /* @__PURE__ */ jsx3("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-white rounded-full", children: item.badge })
677
+ ]
678
+ },
679
+ item.id
680
+ ))
681
+ }
682
+ )
683
+ ]
684
+ }
685
+ )
686
+ ] }),
687
+ mobileMenuOpen && /* @__PURE__ */ jsx3(
688
+ "div",
689
+ {
690
+ className: "fixed inset-0 bg-black bg-opacity-50 z-50 lg:hidden",
691
+ onClick: () => setMobileMenuOpen(false),
692
+ "aria-hidden": "true",
693
+ children: /* @__PURE__ */ jsxs(
694
+ "aside",
695
+ {
696
+ className: "w-80 h-full bg-[var(--color-sidebar-bg)]",
697
+ onClick: (e) => e.stopPropagation(),
698
+ role: "navigation",
699
+ "aria-label": "Navigation mobile",
700
+ children: [
701
+ /* @__PURE__ */ jsxs("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-sidebar-border)]", children: [
702
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
703
+ /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx3("span", { className: "text-[var(--color-background)] font-bold text-xl", children: "W" }) }),
704
+ /* @__PURE__ */ jsxs("div", { children: [
705
+ /* @__PURE__ */ jsx3("h1", { className: "text-white font-bold text-lg", children: "WiseBook" }),
706
+ /* @__PURE__ */ jsx3("p", { className: "text-gray-400 text-xs", children: "ERP Next-Gen" })
707
+ ] })
708
+ ] }),
709
+ /* @__PURE__ */ jsx3(
710
+ "button",
711
+ {
712
+ onClick: () => setMobileMenuOpen(false),
713
+ className: "text-[var(--color-sidebar-text-secondary)]",
714
+ "aria-label": "Fermer le menu",
715
+ children: /* @__PURE__ */ jsx3(X, { className: "w-6 h-6" })
716
+ }
717
+ )
718
+ ] }),
719
+ /* @__PURE__ */ jsx3("nav", { className: "py-4", role: "menubar", children: primaryMenuItems.map((item) => /* @__PURE__ */ jsxs("div", { children: [
720
+ /* @__PURE__ */ jsxs(
721
+ "button",
722
+ {
723
+ onClick: () => {
724
+ if (item.path) {
725
+ navigate(item.path);
726
+ setMobileMenuOpen(false);
727
+ } else {
728
+ setSelectedModule(item.id);
729
+ }
730
+ },
731
+ className: cn(
732
+ "w-full flex items-center gap-3 px-4 py-3 transition-all duration-200",
733
+ "hover:bg-[var(--color-sidebar-hover)]",
734
+ isModuleActive(item.id) && "bg-[var(--color-sidebar-active)] border-l-4 border-[var(--color-primary)]"
735
+ ),
736
+ role: "menuitem",
737
+ "aria-current": isModuleActive(item.id) ? "page" : void 0,
738
+ children: [
739
+ /* @__PURE__ */ jsx3("div", { className: cn(
740
+ "transition-colors",
741
+ isModuleActive(item.id) ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)]"
742
+ ), children: item.icon }),
743
+ /* @__PURE__ */ jsx3("span", { className: cn(
744
+ "flex-1 text-left text-sm font-medium",
745
+ isModuleActive(item.id) ? "text-[var(--color-sidebar-text)]" : "text-[var(--color-sidebar-text-secondary)]"
746
+ ), children: item.label }),
747
+ item.badge && /* @__PURE__ */ jsx3("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-[var(--color-background)] rounded-full", children: item.badge })
748
+ ]
749
+ }
750
+ ),
751
+ isModuleActive(item.id) && secondaryMenuItems[item.id] && /* @__PURE__ */ jsx3("div", { className: "bg-[var(--color-sidebar-submenu-bg)] py-2", children: secondaryMenuItems[item.id].map((subItem) => /* @__PURE__ */ jsxs(
752
+ "button",
753
+ {
754
+ onClick: () => {
755
+ if (subItem.path) {
756
+ navigate(subItem.path);
757
+ setMobileMenuOpen(false);
758
+ }
759
+ },
760
+ className: cn(
761
+ "w-full flex items-center gap-3 pl-12 pr-4 py-2 text-sm",
762
+ "hover:bg-[var(--color-sidebar-hover)]",
763
+ isActive(subItem.path || "") && "bg-[var(--color-sidebar-active)] text-[var(--color-primary)]"
764
+ ),
765
+ children: [
766
+ subItem.icon,
767
+ /* @__PURE__ */ jsx3("span", { className: cn(
768
+ isActive(subItem.path || "") ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)]"
769
+ ), children: subItem.label })
770
+ ]
771
+ },
772
+ subItem.id
773
+ )) })
774
+ ] }, item.id)) })
775
+ ]
776
+ }
777
+ )
778
+ }
779
+ ),
780
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
781
+ /* @__PURE__ */ jsxs(
782
+ "header",
783
+ {
784
+ className: "h-14 bg-[var(--color-background)] border-b border-[var(--color-border)] flex items-center justify-between px-3 lg:px-4",
785
+ role: "banner",
786
+ children: [
787
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 flex-1", children: [
788
+ /* @__PURE__ */ jsx3(
789
+ "button",
790
+ {
791
+ onClick: () => setMobileMenuOpen(true),
792
+ className: "lg:hidden text-[var(--color-text-primary)]",
793
+ "aria-label": "Ouvrir le menu mobile",
794
+ children: /* @__PURE__ */ jsx3(Menu, { className: "w-6 h-6" })
795
+ }
796
+ ),
797
+ /* @__PURE__ */ jsx3(
798
+ "nav",
799
+ {
800
+ className: "hidden sm:flex items-center gap-2 text-sm",
801
+ "aria-label": "Fil d'Ariane",
802
+ children: getBreadcrumbs().map((crumb, index) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
803
+ index > 0 && /* @__PURE__ */ jsx3(ChevronRight, { className: "w-4 h-4 text-[var(--color-text-tertiary)]" }),
804
+ /* @__PURE__ */ jsx3(
805
+ "button",
806
+ {
807
+ onClick: () => navigate(crumb.path),
808
+ className: cn(
809
+ "hover:text-[var(--color-primary)]",
810
+ index === getBreadcrumbs().length - 1 ? "text-[var(--color-text-primary)] font-medium" : "text-[var(--color-text-tertiary)]"
811
+ ),
812
+ children: crumb.label
813
+ }
814
+ )
815
+ ] }, crumb.path))
816
+ }
817
+ ),
818
+ /* @__PURE__ */ jsxs("div", { className: "relative max-w-md flex-1 hidden lg:block", children: [
819
+ /* @__PURE__ */ jsx3(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-tertiary)] w-5 h-5" }),
820
+ /* @__PURE__ */ jsx3(
821
+ "input",
822
+ {
823
+ id: "global-search",
824
+ type: "text",
825
+ placeholder: "Rechercher... (Alt+S)",
826
+ value: searchQuery,
827
+ onChange: (e) => setSearchQuery(e.target.value),
828
+ className: "w-full pl-10 pr-4 py-2 bg-[var(--color-surface-hover)] border border-[var(--color-border)] rounded-lg text-sm focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary-light)]",
829
+ "aria-label": "Recherche globale"
830
+ }
831
+ )
832
+ ] })
833
+ ] }),
834
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
835
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
836
+ /* @__PURE__ */ jsx3(
837
+ "button",
838
+ {
839
+ onClick: () => setShowThemeMenu(!showThemeMenu),
840
+ className: "p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
841
+ title: "Changer le th\xE8me",
842
+ "aria-label": "S\xE9lecteur de th\xE8me",
843
+ "aria-expanded": showThemeMenu,
844
+ children: /* @__PURE__ */ jsx3(Palette, { className: "w-5 h-5 text-[var(--color-text-secondary)]" })
845
+ }
846
+ ),
847
+ showThemeMenu && /* @__PURE__ */ jsx3(
848
+ "div",
849
+ {
850
+ className: "absolute right-0 mt-2 w-64 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50",
851
+ role: "menu",
852
+ "aria-label": "S\xE9lection du th\xE8me",
853
+ children: /* @__PURE__ */ jsxs("div", { className: "p-2", children: [
854
+ /* @__PURE__ */ jsx3("p", { className: "px-3 py-2 text-xs font-semibold text-[var(--color-text-tertiary)] uppercase", children: "Th\xE8mes disponibles" }),
855
+ /* @__PURE__ */ jsxs(
856
+ "button",
857
+ {
858
+ onClick: () => handleThemeChange("elegant"),
859
+ className: cn(
860
+ "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
861
+ themeType === "elegant" && "bg-[var(--color-primary-light)]"
862
+ ),
863
+ role: "menuitem",
864
+ children: [
865
+ /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-accent)]" }),
866
+ /* @__PURE__ */ jsxs("div", { className: "text-left", children: [
867
+ /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium", children: "\xC9l\xE9gance Sobre" }),
868
+ /* @__PURE__ */ jsx3("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "Finance traditionnelle" })
869
+ ] })
870
+ ]
871
+ }
872
+ ),
873
+ /* @__PURE__ */ jsxs(
874
+ "button",
875
+ {
876
+ onClick: () => handleThemeChange("fintech"),
877
+ className: cn(
878
+ "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
879
+ themeType === "fintech" && "bg-[var(--color-primary-light)]"
880
+ ),
881
+ role: "menuitem",
882
+ children: [
883
+ /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-success)] to-[var(--color-text-primary)]" }),
884
+ /* @__PURE__ */ jsxs("div", { className: "text-left", children: [
885
+ /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium", children: "Modern Fintech" }),
886
+ /* @__PURE__ */ jsx3("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "Tableau de bord moderne" })
887
+ ] })
888
+ ]
889
+ }
890
+ ),
891
+ /* @__PURE__ */ jsxs(
892
+ "button",
893
+ {
894
+ onClick: () => handleThemeChange("minimalist"),
895
+ className: cn(
896
+ "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
897
+ themeType === "minimalist" && "bg-[var(--color-primary-light)]"
898
+ ),
899
+ role: "menuitem",
900
+ children: [
901
+ /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-text-secondary)] to-[var(--color-accent)]" }),
902
+ /* @__PURE__ */ jsxs("div", { className: "text-left", children: [
903
+ /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium", children: "Minimaliste Premium" }),
904
+ /* @__PURE__ */ jsx3("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "\xC9l\xE9gance minimaliste" })
905
+ ] })
906
+ ]
907
+ }
908
+ )
909
+ ] })
910
+ }
911
+ )
912
+ ] }),
913
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center px-3 py-1.5 bg-[var(--color-surface)] rounded-lg border border-[var(--color-border)]", children: [
914
+ /* @__PURE__ */ jsx3(DollarSign, { className: "w-4 h-4 text-[var(--color-primary)] mr-2" }),
915
+ /* @__PURE__ */ jsx3("span", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: "FCFA" })
916
+ ] }),
917
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
918
+ /* @__PURE__ */ jsxs(
919
+ "button",
920
+ {
921
+ className: "relative p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
922
+ onClick: () => setShowNotifications(!showNotifications),
923
+ "aria-label": `Notifications ${notifications.filter((n) => !n.read).length > 0 ? `(${notifications.filter((n) => !n.read).length} non lues)` : ""}`,
924
+ "aria-expanded": showNotifications,
925
+ children: [
926
+ /* @__PURE__ */ jsx3(Bell, { className: "w-5 h-5 text-[var(--color-text-secondary)]" }),
927
+ notifications.filter((n) => !n.read).length > 0 && /* @__PURE__ */ jsx3("span", { className: "absolute top-1 right-1 w-2 h-2 bg-[var(--color-error)] rounded-full" })
928
+ ]
929
+ }
930
+ ),
931
+ showNotifications && /* @__PURE__ */ jsxs(
932
+ "div",
933
+ {
934
+ className: "absolute right-0 mt-2 w-80 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50 max-h-96 overflow-y-auto",
935
+ role: "region",
936
+ "aria-label": "Centre de notifications",
937
+ children: [
938
+ /* @__PURE__ */ jsx3("div", { className: "p-4 border-b border-[var(--color-border)]", children: /* @__PURE__ */ jsx3("h3", { className: "font-semibold text-[var(--color-text-primary)]", children: "Notifications" }) }),
939
+ /* @__PURE__ */ jsx3("div", { className: "divide-y divide-[var(--color-border)]", children: notifications.map((notif) => /* @__PURE__ */ jsx3(
940
+ "div",
941
+ {
942
+ className: cn(
943
+ "p-4 hover:bg-[var(--color-surface-hover)] cursor-pointer",
944
+ !notif.read && "bg-[var(--color-primary-light)] bg-opacity-10"
945
+ ),
946
+ onClick: () => markNotificationAsRead(notif.id),
947
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
948
+ /* @__PURE__ */ jsx3("div", { className: cn(
949
+ "w-2 h-2 rounded-full mt-2",
950
+ notif.type === "error" && "bg-[var(--color-error)]",
951
+ notif.type === "warning" && "bg-[var(--color-warning)]",
952
+ notif.type === "success" && "bg-[var(--color-success)]",
953
+ notif.type === "info" && "bg-[var(--color-info)]"
954
+ ) }),
955
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
956
+ /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: notif.title }),
957
+ /* @__PURE__ */ jsx3("p", { className: "text-xs text-[var(--color-text-secondary)] mt-1", children: notif.message }),
958
+ /* @__PURE__ */ jsx3("p", { className: "text-xs text-[var(--color-text-tertiary)] mt-2", children: notif.timestamp.toLocaleTimeString() })
959
+ ] })
960
+ ] })
961
+ },
962
+ notif.id
963
+ )) })
964
+ ]
965
+ }
966
+ )
967
+ ] }),
968
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
969
+ /* @__PURE__ */ jsx3(
970
+ "button",
971
+ {
972
+ onClick: () => setShowUserMenu(!showUserMenu),
973
+ className: "flex items-center gap-2 p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
974
+ "aria-label": "Menu utilisateur",
975
+ "aria-expanded": showUserMenu,
976
+ children: /* @__PURE__ */ jsx3("div", { className: "w-8 h-8 bg-[var(--color-primary)] rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx3(User, { className: "w-4 h-4 text-[var(--color-background)]" }) })
977
+ }
978
+ ),
979
+ showUserMenu && /* @__PURE__ */ jsx3(
980
+ "div",
981
+ {
982
+ className: "absolute right-0 mt-2 w-56 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50",
983
+ role: "menu",
984
+ "aria-label": "Menu utilisateur",
985
+ children: /* @__PURE__ */ jsxs("div", { className: "p-2", children: [
986
+ /* @__PURE__ */ jsxs(
987
+ "button",
988
+ {
989
+ className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
990
+ role: "menuitem",
991
+ children: [
992
+ /* @__PURE__ */ jsx3(User, { className: "w-4 h-4" }),
993
+ /* @__PURE__ */ jsx3("span", { className: "text-sm", children: "Mon profil" })
994
+ ]
995
+ }
996
+ ),
997
+ /* @__PURE__ */ jsxs(
998
+ "button",
999
+ {
1000
+ onClick: () => {
1001
+ navigate("/settings");
1002
+ setShowUserMenu(false);
1003
+ },
1004
+ className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
1005
+ role: "menuitem",
1006
+ children: [
1007
+ /* @__PURE__ */ jsx3(Settings, { className: "w-4 h-4" }),
1008
+ /* @__PURE__ */ jsx3("span", { className: "text-sm", children: "Param\xE8tres" })
1009
+ ]
1010
+ }
1011
+ ),
1012
+ /* @__PURE__ */ jsxs(
1013
+ "button",
1014
+ {
1015
+ className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
1016
+ role: "menuitem",
1017
+ children: [
1018
+ /* @__PURE__ */ jsx3(HelpCircle, { className: "w-4 h-4" }),
1019
+ /* @__PURE__ */ jsx3("span", { className: "text-sm", children: "Aide" })
1020
+ ]
1021
+ }
1022
+ ),
1023
+ /* @__PURE__ */ jsx3("hr", { className: "my-2 border-[var(--color-border)]" }),
1024
+ /* @__PURE__ */ jsxs(
1025
+ "button",
1026
+ {
1027
+ className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] text-[var(--color-error)] transition-colors",
1028
+ role: "menuitem",
1029
+ children: [
1030
+ /* @__PURE__ */ jsx3(LogOut, { className: "w-4 h-4" }),
1031
+ /* @__PURE__ */ jsx3("span", { className: "text-sm", children: "D\xE9connexion" })
1032
+ ]
1033
+ }
1034
+ )
1035
+ ] })
1036
+ }
1037
+ )
1038
+ ] })
1039
+ ] })
1040
+ ]
1041
+ }
1042
+ ),
1043
+ /* @__PURE__ */ jsx3(
1044
+ "main",
1045
+ {
1046
+ id: "main-content",
1047
+ className: "flex-1 overflow-y-auto bg-[var(--color-background)]",
1048
+ role: "main",
1049
+ children: /* @__PURE__ */ jsx3("div", { className: "p-3 lg:p-4", children })
1050
+ }
1051
+ )
1052
+ ] })
1053
+ ] });
1054
+ };
1055
+ var ModernDoubleSidebarLayout_default = RewiseLayout;
1056
+
1057
+ // src/components/ui/Toast.tsx
1058
+ import { useEffect as useEffect3, useState as useState4 } from "react";
1059
+
1060
+ // src/contexts/ToastContext.tsx
1061
+ import { createContext as createContext2, useContext as useContext2, useState as useState3, useCallback } from "react";
1062
+ import { jsx as jsx4 } from "react/jsx-runtime";
1063
+ var ToastContext = createContext2(void 0);
1064
+ var useToast = () => {
1065
+ const context = useContext2(ToastContext);
1066
+ if (!context) {
1067
+ throw new Error("useToast must be used within a ToastProvider");
1068
+ }
1069
+ return context;
1070
+ };
1071
+ var ToastProvider = ({ children }) => {
1072
+ const [toasts, setToasts] = useState3([]);
1073
+ const generateId = () => {
1074
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
1075
+ };
1076
+ const addToast = useCallback((toast) => {
1077
+ const id = generateId();
1078
+ const newToast = {
1079
+ id,
1080
+ duration: 5e3,
1081
+ ...toast
1082
+ };
1083
+ setToasts((prev) => [...prev, newToast]);
1084
+ if (newToast.duration && newToast.duration > 0) {
1085
+ setTimeout(() => {
1086
+ removeToast(id);
1087
+ }, newToast.duration);
1088
+ }
1089
+ }, []);
1090
+ const removeToast = useCallback((id) => {
1091
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
1092
+ }, []);
1093
+ const success = useCallback((message, duration) => {
1094
+ addToast({ message, type: "success", duration });
1095
+ }, [addToast]);
1096
+ const error = useCallback((message, duration) => {
1097
+ addToast({ message, type: "error", duration });
1098
+ }, [addToast]);
1099
+ const warning = useCallback((message, duration) => {
1100
+ addToast({ message, type: "warning", duration });
1101
+ }, [addToast]);
1102
+ const info = useCallback((message, duration) => {
1103
+ addToast({ message, type: "info", duration });
1104
+ }, [addToast]);
1105
+ const value = {
1106
+ toasts,
1107
+ addToast,
1108
+ removeToast,
1109
+ success,
1110
+ error,
1111
+ warning,
1112
+ info
1113
+ };
1114
+ return /* @__PURE__ */ jsx4(ToastContext.Provider, { value, children });
1115
+ };
1116
+
1117
+ // src/components/ui/Toast.tsx
1118
+ import { CheckCircle, XCircle, AlertTriangle, Info, X as X2 } from "lucide-react";
1119
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
1120
+ var ToastItem = ({ toast }) => {
1121
+ const { removeToast } = useToast();
1122
+ const [isVisible, setIsVisible] = useState4(false);
1123
+ const [isLeaving, setIsLeaving] = useState4(false);
1124
+ useEffect3(() => {
1125
+ const timer = setTimeout(() => setIsVisible(true), 10);
1126
+ return () => clearTimeout(timer);
1127
+ }, []);
1128
+ const handleClose = () => {
1129
+ setIsLeaving(true);
1130
+ setTimeout(() => {
1131
+ removeToast(toast.id);
1132
+ }, 300);
1133
+ };
1134
+ const getIcon = () => {
1135
+ switch (toast.type) {
1136
+ case "success":
1137
+ return /* @__PURE__ */ jsx5(CheckCircle, { className: "w-5 h-5 text-green-600" });
1138
+ case "error":
1139
+ return /* @__PURE__ */ jsx5(XCircle, { className: "w-5 h-5 text-red-600" });
1140
+ case "warning":
1141
+ return /* @__PURE__ */ jsx5(AlertTriangle, { className: "w-5 h-5 text-yellow-600" });
1142
+ case "info":
1143
+ return /* @__PURE__ */ jsx5(Info, { className: "w-5 h-5 text-blue-600" });
1144
+ }
1145
+ };
1146
+ const getBackgroundColor = () => {
1147
+ switch (toast.type) {
1148
+ case "success":
1149
+ return "bg-green-50 border-green-200";
1150
+ case "error":
1151
+ return "bg-red-50 border-red-200";
1152
+ case "warning":
1153
+ return "bg-yellow-50 border-yellow-200";
1154
+ case "info":
1155
+ return "bg-blue-50 border-blue-200";
1156
+ }
1157
+ };
1158
+ return /* @__PURE__ */ jsxs2(
1159
+ "div",
1160
+ {
1161
+ className: `
1162
+ transform transition-all duration-300 ease-in-out
1163
+ ${isVisible && !isLeaving ? "translate-x-0 opacity-100" : "translate-x-full opacity-0"}
1164
+ ${getBackgroundColor()}
1165
+ max-w-sm w-full border rounded-lg p-4 shadow-lg
1166
+ flex items-start space-x-3
1167
+ `,
1168
+ children: [
1169
+ /* @__PURE__ */ jsx5("div", { className: "flex-shrink-0", children: getIcon() }),
1170
+ /* @__PURE__ */ jsx5("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx5("p", { className: "text-sm text-gray-900 font-medium", children: toast.message }) }),
1171
+ /* @__PURE__ */ jsx5(
1172
+ "button",
1173
+ {
1174
+ onClick: handleClose,
1175
+ className: "flex-shrink-0 ml-4 text-gray-400 hover:text-gray-600 transition-colors",
1176
+ children: /* @__PURE__ */ jsx5(X2, { className: "w-4 h-4" })
1177
+ }
1178
+ )
1179
+ ]
1180
+ }
1181
+ );
1182
+ };
1183
+ var ToastContainer = () => {
1184
+ const { toasts } = useToast();
1185
+ return /* @__PURE__ */ jsx5("div", { className: "fixed top-4 right-4 z-50 space-y-3", children: toasts.map((toast) => /* @__PURE__ */ jsx5(ToastItem, { toast }, toast.id)) });
1186
+ };
1187
+ var Toast_default = ToastContainer;
1188
+
1189
+ // src/contexts/SessionContext.tsx
1190
+ import { createContext as createContext3, useContext as useContext3, useEffect as useEffect4, useState as useState5 } from "react";
1191
+
1192
+ // src/services/api.ts
1193
+ var ADDRESS_IP = "localhost:8000";
1194
+ var ADDRESS_IP_URL = `http://${ADDRESS_IP}/`;
1195
+ var API_URL = `${ADDRESS_IP_URL}api`;
1196
+
1197
+ // src/services/AuthServices.ts
1198
+ var API_BASE_URL = `${API_URL}/core/auth/`;
1199
+ var FetchApi = class {
1200
+ static async post(url, payload, token) {
1201
+ const headers = {
1202
+ "Content-Type": "application/json"
1203
+ };
1204
+ if (token) {
1205
+ headers["Authorization"] = `Token ${token}`;
1206
+ }
1207
+ const res = await fetch(url, {
1208
+ method: "POST",
1209
+ headers,
1210
+ body: payload ? JSON.stringify(payload) : void 0
1211
+ });
1212
+ if (!res.ok) throw new Error(await res.text());
1213
+ return res.json();
1214
+ }
1215
+ static async get(url, token) {
1216
+ const headers = {};
1217
+ if (token) {
1218
+ headers["Authorization"] = `Token ${token}`;
1219
+ }
1220
+ const res = await fetch(url, {
1221
+ method: "GET",
1222
+ headers
1223
+ });
1224
+ if (!res.ok) throw new Error(await res.text());
1225
+ return res.json();
1226
+ }
1227
+ };
1228
+ var AuthServices = {
1229
+ sendOtp: (payload) => FetchApi.post(`${API_BASE_URL}send-otp/`, payload),
1230
+ verifyOtp: (payload) => FetchApi.post(`${API_BASE_URL}verify-otp/`, payload),
1231
+ completeRegistration: (payload) => FetchApi.post(`${API_BASE_URL}complete-registration/`, payload),
1232
+ addUser: (payload) => FetchApi.post(`${API_BASE_URL}add-user/`, payload),
1233
+ login: (payload) => FetchApi.post(`${API_BASE_URL}login/`, payload),
1234
+ getUserInformations: (token) => FetchApi.get(`${API_BASE_URL}user-informations/`, token),
1235
+ logout: () => FetchApi.post(`${API_BASE_URL}logout/`)
1236
+ };
1237
+
1238
+ // src/contexts/SessionContext.tsx
1239
+ import { jsx as jsx6 } from "react/jsx-runtime";
1240
+ var SessionContext = createContext3(void 0);
1241
+ var SessionProvider = ({ children }) => {
1242
+ const [token, setToken] = useState5(localStorage.getItem("token"));
1243
+ const [loggedUser, setLoggedUser] = useState5(null);
1244
+ useEffect4(() => {
1245
+ const storedToken = localStorage.getItem("token");
1246
+ if (storedToken) {
1247
+ setToken(storedToken);
1248
+ }
1249
+ }, []);
1250
+ const login = (newToken) => {
1251
+ localStorage.setItem("token", newToken);
1252
+ setToken(newToken);
1253
+ };
1254
+ const logout = () => {
1255
+ localStorage.removeItem("token");
1256
+ setToken(null);
1257
+ };
1258
+ useEffect4(() => {
1259
+ if (token) {
1260
+ AuthServices.getUserInformations(token).then((res) => {
1261
+ const result = res;
1262
+ if (result.success === true) {
1263
+ setLoggedUser(result.data.user);
1264
+ } else {
1265
+ setLoggedUser(null);
1266
+ }
1267
+ }).catch(() => setLoggedUser(null));
1268
+ } else {
1269
+ setLoggedUser(null);
1270
+ }
1271
+ }, [token]);
1272
+ return /* @__PURE__ */ jsx6(SessionContext.Provider, { value: {
1273
+ isAuthenticated: !!token,
1274
+ loggedUser,
1275
+ token,
1276
+ login,
1277
+ logout
1278
+ }, children });
1279
+ };
1280
+
1281
+ // src/components/common/Pages.tsx
1282
+ import { ChevronLeft as ChevronLeft2, Download, Menu as Menu2, Settings as Settings2 } from "lucide-react";
1283
+ import { useState as useState6 } from "react";
1284
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1285
+ var Pages = ({
1286
+ title = "",
1287
+ description = "",
1288
+ sideAction,
1289
+ sidebar,
1290
+ tabs = [],
1291
+ children
1292
+ }) => {
1293
+ const [sidebarOpen, setSidebarOpen] = useState6(false);
1294
+ return /* @__PURE__ */ jsxs3("div", { className: "flex h-full bg-gray-50", children: [
1295
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 flex flex-col", children: [
1296
+ /* @__PURE__ */ jsxs3("div", { className: "bg-white border-b border-gray-200 p-6", children: [
1297
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
1298
+ /* @__PURE__ */ jsx7("div", { className: "flex items-center space-x-4", children: /* @__PURE__ */ jsxs3("div", { children: [
1299
+ /* @__PURE__ */ jsx7("h1", { className: "text-2xl font-bold text-gray-900", children: title }),
1300
+ /* @__PURE__ */ jsx7("p", { className: "text-sm text-gray-600", children: description })
1301
+ ] }) }),
1302
+ /* @__PURE__ */ jsx7("div", { className: "flex items-center space-x-3", children: sideAction })
1303
+ ] }),
1304
+ tabs.length > 0 && /* @__PURE__ */ jsx7("div", { className: "flex space-x-1 mt-4 overflow-x-auto", children: tabs.map((tab) => /* @__PURE__ */ jsx7(
1305
+ "button",
1306
+ {
1307
+ className: `px-4 py-2 text-sm rounded-lg transition-all whitespace-nowrap ${tab.id === "manual" ? "bg-[#6A8A82] text-white shadow-md" : "text-gray-600 hover:bg-gray-100"}`,
1308
+ children: tab.label
1309
+ },
1310
+ tab.id
1311
+ )) })
1312
+ ] }),
1313
+ /* @__PURE__ */ jsx7("div", { className: "flex-1 p-6 space-y-6", children })
1314
+ ] }),
1315
+ sidebar && /* @__PURE__ */ jsxs3("div", { className: `${sidebarOpen ? "w-80" : "w-16"} bg-[var(--color-surface)] border-r border-[var(--color-border)] transition-all duration-300 flex flex-col`, children: [
1316
+ /* @__PURE__ */ jsx7("div", { className: "p-4 ", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
1317
+ /* @__PURE__ */ jsx7("h2", { className: `font-semibold text-[var(--color-text-primary)] ${!sidebarOpen && "hidden"}`, children: "Classes SYSCOHADA" }),
1318
+ /* @__PURE__ */ jsx7(
1319
+ "button",
1320
+ {
1321
+ onClick: () => setSidebarOpen(!sidebarOpen),
1322
+ className: "p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
1323
+ "aria-label": sidebarOpen ? "R\xE9duire" : "Ouvrir",
1324
+ children: sidebarOpen ? /* @__PURE__ */ jsx7(ChevronLeft2, { className: "w-5 h-5" }) : /* @__PURE__ */ jsx7(Menu2, { className: "w-5 h-5" })
1325
+ }
1326
+ )
1327
+ ] }) }),
1328
+ /* @__PURE__ */ jsx7("div", { className: "flex-1 overflow-y-auto py-2", children: /* @__PURE__ */ jsx7(
1329
+ "button",
1330
+ {
1331
+ onClick: () => {
1332
+ },
1333
+ className: `w-full flex items-center gap-3 px-4 py-3 transition-all relative group hover:bg-[var(--color-surface-hover)]`,
1334
+ children: /* @__PURE__ */ jsx7(
1335
+ "div",
1336
+ {
1337
+ className: `flex-shrink-0 w-10 h-10 rounded-lg flex items-center justify-center transition-colors bg-[var(--color-background)]`,
1338
+ children: /* @__PURE__ */ jsx7("span", { className: "font-bold text-lg", children: 1 })
1339
+ }
1340
+ )
1341
+ }
1342
+ ) }),
1343
+ sidebarOpen && /* @__PURE__ */ jsx7("div", { className: "p-4 border-t border-[var(--color-border)]", children: /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
1344
+ /* @__PURE__ */ jsxs3("button", { className: "w-full px-3 py-2 bg-[var(--color-background)] rounded-lg text-sm text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors flex items-center gap-2", children: [
1345
+ /* @__PURE__ */ jsx7(Download, { className: "w-4 h-4" }),
1346
+ "Exporter le plan"
1347
+ ] }),
1348
+ /* @__PURE__ */ jsxs3("button", { className: "w-full px-3 py-2 bg-[var(--color-background)] rounded-lg text-sm text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors flex items-center gap-2", children: [
1349
+ /* @__PURE__ */ jsx7(Settings2, { className: "w-4 h-4" }),
1350
+ "Configuration"
1351
+ ] })
1352
+ ] }) })
1353
+ ] })
1354
+ ] });
1355
+ };
1356
+ var Pages_default = Pages;
1357
+ export {
1358
+ Pages_default as Pages,
1359
+ Buttons_default as PrimaryButton,
1360
+ ModernDoubleSidebarLayout_default as RewiseLayout,
1361
+ SecondaryButton,
1362
+ SessionProvider,
1363
+ ThemeContext_default as ThemeProvider,
1364
+ Toast_default as ToastContainer,
1365
+ ToastProvider
1366
+ };