prometeo-design-system 1.2.9 → 1.3.1

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/README.md CHANGED
@@ -1,796 +0,0 @@
1
- # Desing components
2
-
3
- ## Button Component
4
-
5
- ```tsx
6
- import Button from "./components/Button";
7
- import type {
8
- ButtonVariant,
9
- ButtonColor,
10
- ButtonSize,
11
- ButtonState,
12
- } from "./components/Button";
13
- ```
14
-
15
- ```tsx
16
- import Button from "./components/Button";
17
-
18
- function App() {
19
- return (
20
- <div>
21
- {/* Botón básico */}
22
- <Button label="Click me" onClick={() => console.log("Clicked!")} />
23
-
24
- {/* Botón con icono */}
25
- <Button
26
- label="Guardar"
27
- icon={<SaveIcon />}
28
- variant="filled"
29
- color="primary"
30
- />
31
-
32
- {/* Botón de carga */}
33
- <Button
34
- label="Enviando..."
35
- isLoading={true}
36
- Spinner={<CustomSpinner />}
37
- />
38
- </div>
39
- );
40
- }
41
- ```
42
-
43
- ## 📋 API Reference
44
-
45
- ### Props
46
-
47
- | Prop | Tipo | Default | Descripción |
48
- | ----------------- | --------------------------------- | ----------- | ----------------------------------------------- |
49
- | `label` | `string` | `undefined` | Texto a mostrar en el botón |
50
- | `onClick` | `() => void` | `undefined` | Función ejecutada al hacer click |
51
- | `icon` | `React.ReactNode` | `undefined` | Icono a mostrar (se anima en hover) |
52
- | `classButton` | `string` | `undefined` | Clases CSS personalizadas para el botón |
53
- | `classButtonText` | `string` | `undefined` | Clases CSS personalizadas para el texto |
54
- | `animate` | `boolean` | `true` | Habilita/deshabilita animaciones del botón |
55
- | `animateIcon` | `boolean` | `true` | Habilita/deshabilita animaciones del icono |
56
- | `isLoading` | `boolean` | `false` | Muestra estado de carga |
57
- | `disabled` | `boolean` | `false` | Deshabilita el botón |
58
- | `type` | `"button" \| "submit" \| "reset"` | `"button"` | Tipo de botón HTML |
59
- | `variant` | `ButtonVariant` | `"filled"` | Estilo visual del botón |
60
- | `color` | `ButtonColor` | `"primary"` | Esquema de colores |
61
- | `size` | `ButtonSize` | `"medium"` | Tamaño del botón |
62
- | `children` | `React.ReactNode` | `undefined` | Contenido personalizado (anula label e icon) |
63
- | `Spinner` | `React.ReactNode` | `undefined` | Spinner personalizado para estado loading |
64
- | `forceState` | `ButtonState` | `undefined` | Fuerza un estado específico (útil para testing) |
65
-
66
- ### Tipos Exportados
67
-
68
- ```tsx
69
- type ButtonVariant = "filled" | "outline" | "text";
70
- type ButtonColor = "primary" | "secondary";
71
- type ButtonSize = "small" | "medium" | "large";
72
- type ButtonState = "enabled" | "hovered" | "focused" | "pressed" | "disabled";
73
- ```
74
-
75
- ## Variantes
76
-
77
- ### Filled (Default)
78
-
79
- Botones con fondo sólido, ideales para acciones primarias.
80
-
81
- ```tsx
82
- <Button variant="filled" color="primary" label="Primary Filled" />
83
- <Button variant="filled" color="secondary" label="Secondary Filled" />
84
- ```
85
-
86
- ### Outline
87
-
88
- Botones con bordes y fondo transparente, ideales para acciones secundarias.
89
-
90
- ```tsx
91
- <Button variant="outline" color="primary" label="Primary Outline" />
92
- ```
93
-
94
- ### Text
95
-
96
- Botones solo con texto, ideales para acciones terciarias o enlaces.
97
-
98
- ```tsx
99
- <Button variant="text" color="primary" label="Primary Text" />
100
- <Button variant="text" color="secondary" label="Secondary Text" />
101
- ```
102
-
103
- ## Colores
104
-
105
- ### Primary
106
-
107
- Color principal usado para acciones importantes.
108
-
109
- ```tsx
110
- <Button color="primary" label="Primary Action" />
111
- ```
112
-
113
- ### Secondary
114
-
115
- Color secundario usado para acciones menos importantes.
116
-
117
- ```tsx
118
- <Button color="secondary" label="Secondary Action" />
119
- ```
120
-
121
- ## Tamaños
122
-
123
- ### Small (40px)
124
-
125
- ```tsx
126
- <Button size="small" label="Small Button" />
127
- // Dimensiones: h-[40px] min-w-[123px] px-2 text-sm
128
- ```
129
-
130
- ### Medium (48px) - Default
131
-
132
- ```tsx
133
- <Button size="medium" label="Medium Button" />
134
- // Dimensiones: h-[48px] min-w-[134px] px-2 text-base
135
- ```
136
-
137
- ### Large (56px)
138
-
139
- ```tsx
140
- <Button size="large" label="Large Button" />
141
- // Dimensiones: h-[56px] min-w-[145px] px-4 py-3 text-base
142
- ```
143
-
144
- ## ⚡ Animaciones
145
-
146
- El componente incluye varias animaciones por defecto:
147
-
148
- ### Animaciones del Botón
149
-
150
- - **Hover**: Escala a 1.05x
151
- - **Tap**: Escala a 0.98x
152
- - **Transición**: Spring animation con stiffness: 400, damping: 17
153
-
154
- ### Animaciones del Icono
155
-
156
- - **Hover**: Rotación de 90 grados (si `animateIcon` está habilitado)
157
- - **Transición**: Spring animation suave
158
-
159
- ```tsx
160
- {
161
- /* Deshabilitar todas las animaciones */
162
- }
163
- <Button animate={false} animateIcon={false} />;
164
-
165
- {
166
- /* Solo deshabilitar animación del icono */
167
- }
168
- <Button animateIcon={false} icon={<Icon />} label="Icono estático" />;
169
- ```
170
-
171
- ## 🔄 Estado de Carga
172
-
173
- ```tsx
174
- const [loading, setLoading] = useState(false);
175
-
176
- const handleSubmit = async () => {
177
- setLoading(true);
178
- try {
179
- await submitForm();
180
- } finally {
181
- setLoading(false);
182
- }
183
- };
184
-
185
- return (
186
- <Button
187
- label="Enviar Formulario"
188
- isLoading={loading}
189
- onClick={handleSubmit}
190
- Spinner={<CustomSpinner />} // Spinner personalizado
191
- />
192
- );
193
- ```
194
-
195
- **Comportamiento del Loading:**
196
-
197
- - Muestra un spinner (personalizable)
198
- - En tamaño `small` solo muestra el spinner
199
- - En tamaños `medium` y `large` muestra spinner + texto "Cargando..."
200
- - Deshabilita automáticamente el botón
201
- - Detiene todas las animaciones
202
-
203
- ### Clases Personalizadas
204
-
205
- ```tsx
206
- <Button
207
- classButton="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600"
208
- classButtonText="font-bold text-lg"
209
- label="Botón Gradient"
210
- />
211
- ```
212
-
213
- ### Contenido Personalizado Ejemplo
214
-
215
- ```tsx
216
- <Button onClick={handleClick}>
217
- <div className="flex items-center gap-3">
218
- <Avatar src="/user.jpg" size="sm" />
219
- <div className="text-left">
220
- <p className="font-semibold">John Doe</p>
221
- <p className="text-xs opacity-70">Desarrollador</p>
222
- </div>
223
- <ChevronDownIcon className="w-4 h-4" />
224
- </div>
225
- </Button>
226
- ```
227
-
228
- ## Uso Comunes
229
-
230
- ### Botón de Envío de Formulario
231
-
232
- ```tsx
233
- <Button
234
- type="submit"
235
- variant="filled"
236
- color="primary"
237
- size="medium"
238
- label="Enviar"
239
- isLoading={isSubmitting}
240
- disabled={!isFormValid}
241
- />
242
- ```
243
-
244
- ### Botón de Acción con Icono
245
-
246
- ```tsx
247
- <Button
248
- label="Descargar PDF"
249
- icon={<DownloadIcon />}
250
- variant="outline"
251
- onClick={downloadPDF}
252
- />
253
- ```
254
-
255
- ### Botón de Cancelar
256
-
257
- ```tsx
258
- <Button label="Cancelar" variant="text" color="secondary" onClick={onCancel} />
259
- ```
260
-
261
- ### Botón de Eliminar
262
-
263
- ```tsx
264
- <Button
265
- label="Eliminar"
266
- variant="outline"
267
- color="primary"
268
- icon={<TrashIcon />}
269
- classButton="border-red-500 text-red-500 hover:bg-red-50"
270
- onClick={handleDelete}
271
- />
272
- ```
273
-
274
- ## Sistema de Colores (Design Tokens)
275
-
276
- El componente utiliza un sistema de design tokens de Tailwind CSS. Los colores se mapean así:
277
-
278
- ### Primary Colors
279
-
280
- ```css
281
- /* Filled Primary */
282
- bg-primary-default-default
283
- text-neutral-strong-default
284
- hover:bg-primary-default-hover
285
-
286
- /* Outline Primary */
287
- border-primary-medium-default
288
- text-primary-medium-default
289
- hover:border-primary-medium-hover
290
- ```
291
-
292
- ### Secondary Colors
293
-
294
- ```css
295
- /* Filled Secondary */
296
- bg-neutral-strong-medium-default
297
- text-neutral-strong-default
298
-
299
- /* Text Secondary */
300
- text-neutral-strong-default
301
- hover:text-primary-default-hover
302
- ```
303
-
304
- ---
305
-
306
- # Sidebar Component
307
-
308
- Un componente de barra lateral completo y altamente funcional con soporte para navegación, perfil de usuario, gestión de sesiones múltiples, notificaciones y estados colapsables. Diseñado para aplicaciones empresariales con múltiples usuarios y funcionalidades avanzadas.
309
-
310
- ## 🚀 Características Principales
311
-
312
- - ✅ **Navegación colapsable** con animaciones suaves
313
- - ✅ **Perfil de usuario** con gestión de sesiones múltiples
314
- - ✅ **Sistema de notificaciones** con badge
315
- - ✅ **Logo de empresa** dinámico
316
- - ✅ **Enlaces de navegación** categorizados (páginas y utilidades)
317
- - ✅ **Menú contextual** para usuarios en modo colapsado
318
- - ✅ **Detección de clicks externos** para cerrar menús
319
- - ✅ **Estados activos** para navegación actual
320
- - ✅ **Responsive** y accesible
321
-
322
- ## 📦 Dependencias
323
-
324
- ```bash
325
- npm install react-router-dom framer-motion
326
- # o
327
- yarn add react-router-dom framer-motion
328
- ```
329
-
330
- #### nota: No es necesario instalarlo, seguramente en el template del proyecto ya este instalado.
331
-
332
- ## 📋 Importaciones Requeridas
333
-
334
- ```tsx
335
- import type { SessionLocalStorage } from "@/interfaces/User/SessionLocalStorage";
336
- import type { IUser } from "shared-dependencies-tickets";
337
- import Menu from "../Menu/Menu";
338
- import { Badge } from "./components/badge";
339
- import { NavbarCollapseButton } from "./components/collapse-button";
340
- import { CompanyLogo } from "./components/company-logo";
341
- import { NavbarLinks } from "./components/nav-links";
342
- import { UserProfile } from "./components/user-profile";
343
- import { useNavbarCollapse } from "./hooks/useNavBarCollapse";
344
- import { useNavbarLinks, type INavLink } from "./hooks/useNavLinks";
345
- import { useNavbarAnimations } from "./ui/useNavbarAnimation";
346
- ```
347
-
348
- ## 🎯 Uso Básico
349
-
350
- ```tsx
351
- import Sidebar from "./components/Sidebar";
352
-
353
- function App() {
354
- const user = {
355
- id: 1,
356
- name: "Juan Pérez",
357
- email: "juan@empresa.com",
358
- company_id: {
359
- name: "Mi Empresa",
360
- logo: "/logo-empresa.png",
361
- },
362
- };
363
-
364
- const sessions = [
365
- { token: "token1", user_id: 1, email: "juan@empresa.com" },
366
- { token: "token2", user_id: 2, email: "maria@empresa.com" },
367
- ];
368
-
369
- const links = {
370
- pages: [
371
- {
372
- id: "dashboard",
373
- label: "Dashboard",
374
- path: "/dashboard",
375
- icon: <DashboardIcon />,
376
- },
377
- {
378
- id: "projects",
379
- label: "Proyectos",
380
- path: "/projects",
381
- icon: <ProjectIcon />,
382
- },
383
- ],
384
- utils: [
385
- {
386
- id: "notifications",
387
- label: "Notificaciones",
388
- path: "/notifications",
389
- icon: <BellIcon />,
390
- },
391
- ],
392
- };
393
-
394
- return (
395
- <div className="flex h-screen">
396
- <Sidebar
397
- user={user}
398
- sessions={sessions}
399
- handleLogout={(user) => console.log("Logout", user)}
400
- handleTokenLogin={(token) => console.log("Switch user", token)}
401
- links={links}
402
- isActiveModalNotification={false}
403
- setIsActiveModalNotification={() => {}}
404
- handleNotificationClick={() => console.log("Notifications")}
405
- handleProfileClick={() => console.log("Profile")}
406
- />
407
- <main className="flex-1">{/* Contenido principal */}</main>
408
- </div>
409
- );
410
- }
411
- ```
412
-
413
- ## 📋 API Reference
414
-
415
- ### Props Principales
416
-
417
- | Prop | Tipo | Requerido | Descripción |
418
- | ------------------------------ | ---------------------------------------- | --------- | ----------------------------------------------------------- |
419
- | `user` | `IUser` | ✅ | Información del usuario actual |
420
- | `sessions` | `SessionLocalStorage[]` | ✅ | Lista de sesiones activas disponibles |
421
- | `handleLogout` | `(user: IUser) => void` | ✅ | Función para cerrar sesión |
422
- | `handleTokenLogin` | `(token: string) => void` | ✅ | Función para cambiar entre sesiones |
423
- | `links` | `Record<"pages" \| "utils", INavLink[]>` | ✅ | Enlaces de navegación categorizados |
424
- | `isActiveModalNotification` | `boolean` | ✅ | Estado del modal de notificaciones |
425
- | `setIsActiveModalNotification` | `(state: boolean) => void` | ✅ | Función para controlar modal de notificaciones |
426
- | `handleNotificationClick` | `() => void` | ✅ | Función ejecutada al hacer click en notificaciones |
427
- | `handleProfileClick` | `() => void` | ❌ | Función ejecutada al hacer click en perfil (modo expandido) |
428
-
429
- ### Tipos de Datos
430
-
431
- ```tsx
432
- interface IUser {
433
- id: number;
434
- name: string;
435
- email: string;
436
- company_id: {
437
- name: string;
438
- logo: string;
439
- };
440
- // ... otros campos del usuario
441
- }
442
-
443
- interface SessionLocalStorage {
444
- token: string;
445
- user_id: number;
446
- email: string;
447
- // ... otros campos de sesión
448
- }
449
-
450
- interface INavLink {
451
- id: string;
452
- label: string;
453
- path: string;
454
- icon: React.ReactNode;
455
- badge?: number; // Para mostrar contadores
456
- disabled?: boolean;
457
- }
458
- ```
459
-
460
- ## 🏗️ Estructura del Componente
461
-
462
- ### Layout Principal
463
-
464
- ```
465
- ┌─────────────────────────┐
466
- │ [Collapse Button] │
467
- ├─────────────────────────┤
468
- │ [Company Logo] │
469
- ├─────────────────────────┤
470
- │ ───────────────── │ ← Separador
471
- ├─────────────────────────┤
472
- │ │
473
- │ [Navigation Links] │
474
- │ • Dashboard │
475
- │ • Proyectos │
476
- │ • Reportes │
477
- │ │
478
- ├─────────────────────────┤ ← Flex Grow
479
- │ │
480
- │ [Utility Links] │
481
- │ • Notificaciones [2] │
482
- │ • Configuración │
483
- │ │
484
- ├─────────────────────────┤
485
- │ ───────────────── │ ← Separador
486
- ├─────────────────────────┤
487
- │ [User Profile] │
488
- │ • Avatar + Nombre │
489
- │ • Sesiones múltiples │
490
- └─────────────────────────┘
491
- ```
492
-
493
- ### Estados del Sidebar
494
-
495
- #### 1. **Expandido** (w-64 / 256px)
496
-
497
- - Muestra todos los elementos con texto
498
- - Logo completo de la empresa
499
- - Enlaces con iconos y etiquetas
500
- - Perfil de usuario completo
501
-
502
- #### 2. **Colapsado** (w-16 / 64px)
503
-
504
- - Solo muestra iconos
505
- - Logo reducido
506
- - Enlaces solo con iconos
507
- - Avatar de usuario solamente
508
-
509
- #### 3. **Colapsado + Menú Contextual**
510
-
511
- - Sidebar colapsado
512
- - Menú flotante con opciones de usuario
513
- - Cambio de sesiones disponible
514
-
515
- ## 🎨 Componentes Internos
516
-
517
- ### NavbarCollapseButton
518
-
519
- Botón para alternar entre estado expandido y colapsado.
520
-
521
- ```tsx
522
- <NavbarCollapseButton isCollapsed={isCollapsed} onToggle={toggleCollapse} />
523
- ```
524
-
525
- ### CompanyLogo
526
-
527
- Muestra el logo y nombre de la empresa del usuario.
528
-
529
- ```tsx
530
- <CompanyLogo
531
- logoUrl={user?.company_id.logo || ""}
532
- companyName={user?.company_id.name}
533
- />
534
- ```
535
-
536
- ```tsx
537
-
538
- <NavbarLinks
539
- links={pageLinks}
540
- isLinkActive={isLinkActive}
541
- />
542
-
543
-
544
- <NavbarLinks
545
- links={utilLinks}
546
- componentBadge={() => <Badge notificationsCount={0} />}
547
- onClick={handleNotificationClick}
548
- isLinkActive={isLinkActive}
549
- activeModal={isActiveModalNotification}
550
- />
551
- ```
552
-
553
- ### UserProfile
554
-
555
- Perfil de usuario con gestión de sesiones múltiples.
556
-
557
- ```tsx
558
- <UserProfile
559
- sessions={sessions}
560
- user={user}
561
- isExpanded={isExpanded}
562
- showOptions={true}
563
- onProfileClick={handleProfileClick}
564
- onClick={toggleExpandedUserConfig}
565
- onClickLogout={handleLogout}
566
- handleTokenLogin={handleTokenLogin}
567
- />
568
- ```
569
-
570
- ## Estados
571
-
572
- ### Estados Internos
573
-
574
- ```tsx
575
- const [isCollapsed, setIsCollapsed] = useState(false); // Sidebar colapsado
576
- const [isExpanded, setIsExpanded] = useState(false); // Menú de usuario expandido
577
- const [isExpandedUserConfig, setIsExpandedUserConfig] = useState(false); // Config de usuario
578
- ```
579
-
580
- ### Comportamientos Automáticos
581
-
582
- 1. **Click fuera del menú**: Cierra automáticamente el menú de configuración de usuario
583
- 2. **Colapsar sidebar**: Automáticamente cierra los menús expandidos
584
- 3. **Cambio de sesión**: Cierra el menú de usuario tras cambiar sesión
585
-
586
- ### Lógica de Interacciones
587
-
588
- ```tsx
589
- // Alternar colapso del sidebar
590
- const toggleCollapse = () => {
591
- setIsExpandedUserConfig(false); // Cierra menú de usuario
592
- setIsCollapsed(!isCollapsed);
593
- };
594
-
595
- // Manejar click en perfil (diferentes comportamientos según estado)
596
- const handleLocalProfileClick = () => {
597
- setIsExpandedUserConfig(!isExpandedUserConfig);
598
- };
599
-
600
- // Click externo para cerrar menú
601
- useEffect(() => {
602
- const handleClickOutside = (event: MouseEvent) => {
603
- if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
604
- setIsExpandedUserConfig(false);
605
- }
606
- };
607
-
608
- if (isExpandedUserConfig) {
609
- document.addEventListener("mousedown", handleClickOutside);
610
- }
611
-
612
- return () => document.removeEventListener("mousedown", handleClickOutside);
613
- }, [isExpandedUserConfig]);
614
- ```
615
-
616
- ### Clases CSS Base
617
-
618
- ```tsx
619
- className={`
620
- bg-neutral-default-default
621
- overflow-hidden
622
- h-full
623
- flex
624
- flex-col
625
- border-r
626
- border-neutral-strong-default
627
- transition-all
628
- duration-300
629
- ${isCollapsed ? 'w-16' : 'w-64'}
630
- `}
631
- ```
632
-
633
- ### Badges
634
-
635
- ```tsx
636
- const CustomBadge = ({ count }: { count: number }) => (
637
- <div className="bg-red-500 text-white rounded-full w-5 h-5 flex items-center justify-center text-xs">
638
- {count > 99 ? "99+" : count}
639
- </div>
640
- );
641
-
642
- <NavbarLinks
643
- links={utilLinks}
644
- componentBadge={() => <CustomBadge count={notificationCount} />}
645
- // ... otras props
646
- />;
647
- ```
648
-
649
- ### Enlaces Dinámicos por Rol
650
-
651
- ```tsx
652
- const getLinksForUser = (user: IUser) => {
653
- const baseLinks = [
654
- {
655
- id: "dashboard",
656
- label: "Dashboard",
657
- path: "/dashboard",
658
- icon: <HomeIcon />,
659
- },
660
- ];
661
-
662
- if (user.role === "admin") {
663
- baseLinks.push(
664
- { id: "users", label: "Usuarios", path: "/users", icon: <UsersIcon /> },
665
- {
666
- id: "settings",
667
- label: "Configuración",
668
- path: "/settings",
669
- icon: <SettingsIcon />,
670
- }
671
- );
672
- }
673
-
674
- return { pages: baseLinks, utils: [] };
675
- };
676
- ```
677
-
678
- ## Ejemplo de uso
679
-
680
- ### Navbar completo
681
-
682
- ```tsx
683
- import { useState, useEffect } from "react";
684
- import { useNavigate, useLocation } from "react-router-dom";
685
- import Sidebar from "./components/Sidebar";
686
-
687
- function Navbar() {
688
- const navigate = useNavigate();
689
- const location = useLocation();
690
- const [user, setUser] = useState(null);
691
- const [sessions, setSessions] = useState([]);
692
- const [notificationCount, setNotificationCount] = useState(0);
693
- const [showNotifications, setShowNotifications] = useState(false);
694
-
695
- const links = {
696
- pages: [
697
- {
698
- id: "dashboard",
699
- label: "Dashboard",
700
- path: "/dashboard",
701
- icon: <HomeIcon className="w-5 h-5" />,
702
- },
703
- {
704
- id: "tickets",
705
- label: "Tickets",
706
- path: "/tickets",
707
- icon: <TicketIcon className="w-5 h-5" />,
708
- },
709
- {
710
- id: "projects",
711
- label: "Proyectos",
712
- path: "/projects",
713
- icon: <FolderIcon className="w-5 h-5" />,
714
- },
715
- {
716
- id: "reports",
717
- label: "Reportes",
718
- path: "/reports",
719
- icon: <ChartIcon className="w-5 h-5" />,
720
- },
721
- ],
722
- utils: [
723
- {
724
- id: "notifications",
725
- label: "Notificaciones",
726
- path: "/notifications",
727
- icon: <BellIcon className="w-5 h-5" />,
728
- badge: notificationCount,
729
- },
730
- {
731
- id: "settings",
732
- label: "Configuración",
733
- path: "/settings",
734
- icon: <SettingsIcon className="w-5 h-5" />,
735
- },
736
- ],
737
- };
738
-
739
- const handleLogout = async (user) => {
740
- try {
741
- await logoutUser(user);
742
- navigate("/login");
743
- } catch (error) {
744
- console.error("Error al cerrar sesión:", error);
745
- }
746
- };
747
-
748
- const handleTokenLogin = async (token) => {
749
- try {
750
- const newUser = await switchUserSession(token);
751
- setUser(newUser);
752
- navigate("/dashboard");
753
- } catch (error) {
754
- console.error("Error al cambiar sesión:", error);
755
- }
756
- };
757
-
758
- const handleNotificationClick = () => {
759
- setShowNotifications(true);
760
- setNotificationCount(0);
761
- };
762
-
763
- return (
764
- <div className="flex h-screen bg-gray-50">
765
- <Sidebar
766
- user={user}
767
- sessions={sessions}
768
- handleLogout={handleLogout}
769
- handleTokenLogin={handleTokenLogin}
770
- links={links}
771
- isActiveModalNotification={showNotifications}
772
- setIsActiveModalNotification={setShowNotifications}
773
- handleNotificationClick={handleNotificationClick}
774
- handleProfileClick={() => navigate("/profile")}
775
- />
776
- </div>
777
- );
778
- }
779
-
780
- export default Navbar;
781
-
782
- //<!--- En otro lugar de nuestra app>
783
-
784
- /* REACT ROUTER */
785
- <main className="flex-1 overflow-auto p-6">
786
- <Routes>
787
- <Route path="/dashboard" element={<DashboardContent />} />
788
- <Route path="/tickets" element={<TicketsContent />} />
789
- <Route path="/projects" element={<ProjectsContent />} />
790
- <Route path="/reports" element={<ReportsContent />} />
791
- <Route path="/notifications" element={<NotificationsContent />} />
792
- <Route path="/settings" element={<SettingsContent />} />
793
- <Route path="/profile" element={<ProfileContent />} />
794
- </Routes>
795
- </main>;
796
- ```