anima-ds-nucleus 1.0.2 → 1.0.4

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 (38) hide show
  1. package/dist/anima-ds-nucleus.css +1 -1
  2. package/dist/anima-ds.cjs.js +152 -34
  3. package/dist/anima-ds.esm.js +10124 -7528
  4. package/package.json +10 -2
  5. package/src/assets/nucleus-logo.svg +3 -0
  6. package/src/components/Atoms/LogoHexa/LogoHexa.jsx +34 -0
  7. package/src/components/Atoms/LogoHexa/LogoHexa.stories.jsx +36 -0
  8. package/src/components/Atoms/Typography/Typography.jsx +53 -18
  9. package/src/components/Atoms/Typography/Typography.stories.jsx +40 -4
  10. package/src/components/DataDisplay/Card/Card.jsx +117 -24
  11. package/src/components/DataDisplay/Card/Card.stories.jsx +119 -35
  12. package/src/components/DataDisplay/Card/CardError.jsx +142 -0
  13. package/src/components/DataDisplay/Card/CardSkeleton.jsx +96 -0
  14. package/src/components/DataDisplay/Card/CardTituloCorto.jsx +61 -0
  15. package/src/components/DataDisplay/Card/CardTituloCortoMasEstado.jsx +79 -0
  16. package/src/components/DataDisplay/Card/CardTituloLargo.jsx +61 -0
  17. package/src/components/DataDisplay/Card/CardTituloLargoMasEstado.jsx +77 -0
  18. package/src/components/DataDisplay/Card/CardVacia.jsx +111 -0
  19. package/src/components/Layout/Header/HeaderConBuscador.jsx +136 -0
  20. package/src/components/Layout/Header/HeaderConBuscador.stories.jsx +86 -0
  21. package/src/components/Layout/Header/HeaderCore.jsx +347 -0
  22. package/src/components/Layout/Header/HeaderCore.stories.jsx +59 -0
  23. package/src/components/Layout/Header/HeaderGeneral.jsx +92 -0
  24. package/src/components/Layout/Header/HeaderGeneral.stories.jsx +64 -0
  25. package/src/components/Layout/Header/HeaderPoint.jsx +120 -0
  26. package/src/components/Layout/Header/HeaderPoint.stories.jsx +110 -0
  27. package/src/components/Layout/NavPoint/NavPoint.jsx +64 -0
  28. package/src/components/Layout/NavPoint/NavPoint.stories.jsx +52 -0
  29. package/src/components/Layout/Sidebar/SidebarCore.jsx +779 -0
  30. package/src/components/Layout/Sidebar/SidebarCore.stories.jsx +167 -0
  31. package/src/components/Layout/Sidebar/SidebarPoint.jsx +645 -0
  32. package/src/components/Layout/Sidebar/SidebarPoint.stories.jsx +183 -0
  33. package/src/index.js +15 -2
  34. package/src/style.css +37 -0
  35. package/src/components/Layout/Header/Header.jsx +0 -50
  36. package/src/components/Layout/Header/Header.stories.jsx +0 -36
  37. package/src/components/Layout/Sidebar/Sidebar.jsx +0 -57
  38. package/src/components/Layout/Sidebar/Sidebar.stories.jsx +0 -51
@@ -0,0 +1,645 @@
1
+ import { useState } from 'react';
2
+ import { Icon } from '../../Atoms/Icon/Icon';
3
+ import { Typography } from '../../Atoms/Typography/Typography';
4
+ import { LogoHexa } from '../../Atoms/LogoHexa/LogoHexa';
5
+
6
+ // Mock data con 2 títulos y 2 secciones
7
+ const MOCK_SECTIONS = [
8
+ {
9
+ title: 'PERSONAS',
10
+ items: [
11
+ { id: 'empleados', label: 'Empleados', icon: 'UserGroupIcon' },
12
+ { id: 'organizacion', label: 'Organización', icon: 'BuildingOfficeIcon' },
13
+ ],
14
+ },
15
+ {
16
+ title: 'TALENTO',
17
+ items: [
18
+ { id: 'reclutamiento', label: 'Reclutamiento', icon: 'UserPlusIcon' },
19
+ { id: 'desarrollo', label: 'Desarrollo', icon: 'AcademicCapIcon' },
20
+ ],
21
+ },
22
+ ];
23
+
24
+ export const SidebarPoint = ({
25
+ sections = MOCK_SECTIONS,
26
+ activeItem,
27
+ onItemClick,
28
+ defaultCollapsed = false,
29
+ companyName = 'HEXA Point',
30
+ companyLogo,
31
+ onCompanyClick,
32
+ itemBadges = {}, // Objeto con { itemId: number } para los badges
33
+ footerText, // Texto del footer: puede ser string "v1.0 | Powered by Nucleus" o objeto { version: "v1.0", poweredBy: "Powered by", brand: "Nucleus" }
34
+ footerCollapsedContent, // Contenido a mostrar en el footer cuando está colapsado (puede ser string, ReactNode, o objeto con icon y text)
35
+ Client = false, // Propiedad booleana para mostrar el logo de la empresa en la parte superior
36
+ className = '',
37
+ ...props
38
+ }) => {
39
+ const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
40
+
41
+ const toggleCollapse = () => {
42
+ setIsCollapsed(!isCollapsed);
43
+ };
44
+
45
+ return (
46
+ <aside
47
+ className={`bg-white border-r border-gray-200 transition-all duration-300 ease-in-out h-full ${
48
+ isCollapsed ? 'w-20' : 'w-64'
49
+ } ${className}`}
50
+ {...props}
51
+ >
52
+ <nav className="h-full flex flex-col" style={{ overflow: 'hidden' }}>
53
+ {/* Barra superior con HEXA Point */}
54
+ {!isCollapsed && (
55
+ <div className="p-4 border-b border-gray-200 flex-shrink-0">
56
+ <button
57
+ onClick={onCompanyClick}
58
+ className="w-full bg-white rounded-lg px-3 py-2.5
59
+ flex items-center justify-between hover:bg-gray-50 transition-colors"
60
+ >
61
+ <div className="flex items-center space-x-3">
62
+ {/* Logo hexagonal */}
63
+ {companyLogo ? (
64
+ <img
65
+ src={companyLogo}
66
+ alt={companyName}
67
+ className="w-8 h-8 rounded"
68
+ />
69
+ ) : (
70
+ <LogoHexa width={36} height={40} />
71
+ )}
72
+ {/* Nombre de la empresa */}
73
+ <Typography
74
+ variant="body-md"
75
+ className="color-gray-900 font-medium"
76
+ >
77
+ {companyName}
78
+ </Typography>
79
+ </div>
80
+ </button>
81
+ </div>
82
+ )}
83
+
84
+ {/* Botón de colapsar/expandir - Solo visible cuando está expandido */}
85
+ {!isCollapsed && (
86
+ <div className="px-4 pt-2 pb-2 flex justify-end flex-shrink-0">
87
+ <button
88
+ onClick={toggleCollapse}
89
+ className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors"
90
+ aria-label="Colapsar sidebar"
91
+ style={{ marginRight: '10px' }}
92
+ >
93
+ <Icon
94
+ name="ChevronDoubleLeftIcon"
95
+ variant="24-outline"
96
+ size={20}
97
+ className="color-teal"
98
+ />
99
+ </button>
100
+ </div>
101
+ )}
102
+
103
+ {/* Header con logo de empresa cuando Client es true - entre botón colapsar y botón Inicio */}
104
+ {Client && companyLogo && !isCollapsed && (
105
+ <div className="flex-shrink-0 border-b border-gray-200" style={{ borderStyle: 'dashed' }}>
106
+ <div className="px-4 py-6 flex flex-col items-center justify-center">
107
+ <img
108
+ src={companyLogo}
109
+ alt={companyName || 'Company Logo'}
110
+ className="max-w-[200px] max-h-[80px] object-contain"
111
+ />
112
+ </div>
113
+ </div>
114
+ )}
115
+
116
+ {/* Logo cuando está colapsado */}
117
+ {isCollapsed && (
118
+ <div className="p-4 border-b border-gray-200 flex justify-center flex-shrink-0">
119
+ {companyLogo ? (
120
+ <img
121
+ src={companyLogo}
122
+ alt={companyName}
123
+ className="w-8 h-8 rounded"
124
+ />
125
+ ) : (
126
+ <LogoHexa width={36} height={40} />
127
+ )}
128
+ </div>
129
+ )}
130
+
131
+ {/* Botón para expandir - Solo visible cuando está colapsado */}
132
+ {isCollapsed && (
133
+ <div className="px-4 pt-2 pb-2 flex justify-center flex-shrink-0">
134
+ <button
135
+ onClick={toggleCollapse}
136
+ className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors"
137
+ aria-label="Expandir sidebar"
138
+ >
139
+ <Icon
140
+ name="ChevronDoubleRightIcon"
141
+ variant="24-outline"
142
+ size={20}
143
+ className="color-teal"
144
+ />
145
+ </button>
146
+ </div>
147
+ )}
148
+
149
+ {/* Contenido del sidebar - Wrapper para controlar el espacio */}
150
+ <div className="flex-1 min-h-0 flex flex-col overflow-hidden">
151
+ <div className={`flex-1 overflow-y-auto ${isCollapsed ? 'py-2' : 'py-4'}`} style={{ overflowX: 'hidden' }}>
152
+ {/* Item "Inicio" destacado */}
153
+ <div className="px-4 mb-4">
154
+ <button
155
+ onClick={() => onItemClick && onItemClick('inicio')}
156
+ className={`w-full flex items-center cursor-pointer ${
157
+ isCollapsed ? 'justify-center px-2' : 'px-4 justify-between'
158
+ } py-2.5 rounded-lg transition-all duration-200 ${
159
+ activeItem === 'inicio'
160
+ ? ''
161
+ : 'color-gray-700 hover:bg-gray-100'
162
+ }`}
163
+ style={
164
+ activeItem === 'inicio'
165
+ ? { backgroundColor: '#2D5C63' }
166
+ : {}
167
+ }
168
+ >
169
+ <Icon
170
+ name="HomeIcon"
171
+ variant="24-outline"
172
+ size={20}
173
+ className={`${isCollapsed ? '' : 'mr-3'} ${
174
+ activeItem === 'inicio' ? 'color-white' : 'color-gray-700'
175
+ }`}
176
+ />
177
+ {!isCollapsed && (
178
+ <Typography
179
+ variant="body-md"
180
+ className={`font-medium ${
181
+ activeItem === 'inicio' ? 'color-white' : 'color-gray-700'
182
+ }`}
183
+ >
184
+ Inicio
185
+ </Typography>
186
+ )}
187
+ {!isCollapsed && itemBadges['inicio'] !== undefined && itemBadges['inicio'] > 0 && (
188
+ <span
189
+ className="px-2 py-0.5 min-w-[20px] h-5
190
+ text-white rounded-full flex items-center justify-center
191
+ text-body-sm font-medium"
192
+ style={{
193
+ backgroundColor: '#6D3856',
194
+ borderRadius: '12px'
195
+ }}
196
+ >
197
+ {itemBadges['inicio'] > 9 ? '9+' : itemBadges['inicio']}
198
+ </span>
199
+ )}
200
+ </button>
201
+ </div>
202
+
203
+ {/* Secciones */}
204
+ {sections.map((section, sectionIndex) => (
205
+ <div key={sectionIndex} className="mb-6">
206
+ {/* Línea separadora cuando está colapsado - antes de cada sección */}
207
+ {isCollapsed && (
208
+ <div className="px-4 mb-4">
209
+ <div className="border-t" style={{ borderColor: '#2D5C63' }}></div>
210
+ </div>
211
+ )}
212
+
213
+ {/* Título de la sección - solo visible cuando NO está colapsado */}
214
+ {!isCollapsed && (
215
+ <div className="px-4 mb-2">
216
+ <Typography
217
+ variant="body-sm"
218
+ className="color-gray-500 uppercase font-medium tracking-wider"
219
+ >
220
+ {section.title}
221
+ </Typography>
222
+ </div>
223
+ )}
224
+
225
+ {/* Items de la sección */}
226
+ <div className="space-y-1">
227
+ {section.items.map((item) => (
228
+ <div key={item.id} className="px-4">
229
+ <button
230
+ onClick={() => onItemClick && onItemClick(item.id)}
231
+ className={`w-full flex items-center cursor-pointer ${
232
+ isCollapsed ? 'justify-center px-2' : 'px-4 justify-between'
233
+ } py-2.5 rounded-lg transition-all duration-200 ${
234
+ activeItem === item.id
235
+ ? ''
236
+ : 'color-gray-700 hover:bg-gray-100'
237
+ }`}
238
+ style={
239
+ activeItem === item.id
240
+ ? { backgroundColor: '#2D5C63' }
241
+ : {}
242
+ }
243
+ title={isCollapsed ? item.label : ''}
244
+ >
245
+ <div className="flex items-center">
246
+ <Icon
247
+ name={item.icon}
248
+ variant="24-outline"
249
+ size={20}
250
+ className={`${isCollapsed ? '' : 'mr-3'} ${
251
+ activeItem === item.id ? 'color-white' : 'color-gray-700'
252
+ }`}
253
+ />
254
+ {!isCollapsed && (
255
+ <Typography
256
+ variant="body-md"
257
+ className={`font-medium ${
258
+ activeItem === item.id ? 'color-white' : 'color-gray-700'
259
+ }`}
260
+ >
261
+ {item.label}
262
+ </Typography>
263
+ )}
264
+ </div>
265
+ {!isCollapsed && ((itemBadges[item.id] !== undefined && itemBadges[item.id] > 0) || (item.id === 'empleados' && 2)) && (
266
+ <span
267
+ className="px-2 py-0.5 min-w-[20px] h-5
268
+ text-white rounded-full flex items-center justify-center
269
+ text-body-sm font-medium"
270
+ style={{
271
+ backgroundColor: '#6D3856',
272
+ borderRadius: '12px'
273
+ }}
274
+ >
275
+ {item.id === 'empleados' ? 2 : (itemBadges[item.id] > 9 ? '9+' : itemBadges[item.id])}
276
+ </span>
277
+ )}
278
+ </button>
279
+ </div>
280
+ ))}
281
+ </div>
282
+ </div>
283
+ ))}
284
+ </div>
285
+ </div>
286
+
287
+ {/* Footer con texto configurable - cuando está expandido */}
288
+ {footerText && !isCollapsed && (
289
+ <div className="px-4 pb-4 flex-shrink-0">
290
+ <div
291
+ className="bg-white border rounded-lg px-3 py-2 flex items-center justify-center"
292
+ style={{
293
+ borderColor: '#2D5C63',
294
+ borderRadius: '8px'
295
+ }}
296
+ >
297
+ {typeof footerText === 'string' ? (
298
+ <Typography
299
+ variant="body-sm"
300
+ style={{ color: '#2D5C63' }}
301
+ className="text-center"
302
+ >
303
+ {(() => {
304
+ const parts = footerText.split('|');
305
+ if (parts.length === 2) {
306
+ const leftPart = parts[0].trim();
307
+ const rightPart = parts[1].trim();
308
+ // Si contiene "Powered by", separar y poner la marca en bold
309
+ if (rightPart.includes('Powered by')) {
310
+ const poweredByMatch = rightPart.match(/Powered by (.+)/);
311
+ if (poweredByMatch) {
312
+ return (
313
+ <>
314
+ {leftPart} | Powered by <span className="font-bold">{poweredByMatch[1]}</span>
315
+ </>
316
+ );
317
+ }
318
+ }
319
+ return `${leftPart} | ${rightPart}`;
320
+ }
321
+ return footerText;
322
+ })()}
323
+ </Typography>
324
+ ) : (
325
+ <Typography
326
+ variant="body-sm"
327
+ style={{ color: '#2D5C63' }}
328
+ className="text-center"
329
+ >
330
+ {footerText.version && `${footerText.version}`}
331
+ {footerText.version && (footerText.poweredBy || footerText.brand) && ' | '}
332
+ {footerText.poweredBy && `${footerText.poweredBy} `}
333
+ {footerText.brand && <span className="font-bold">{footerText.brand}</span>}
334
+ </Typography>
335
+ )}
336
+ </div>
337
+ </div>
338
+ )}
339
+
340
+ {/* Footer cuando está colapsado */}
341
+ {footerCollapsedContent && isCollapsed && (
342
+ <div className="px-1 pt-2 pb-2 flex justify-center flex-shrink-0" style={{ zIndex: 10 }}>
343
+ <div
344
+ className="bg-white border rounded px-1 py-0.5 flex items-center justify-center"
345
+ style={{
346
+ borderColor: '#2D5C63',
347
+ borderRadius: '4px',
348
+ width: 'calc(100% - 8px)',
349
+ minHeight: '20px'
350
+ }}
351
+ >
352
+ {typeof footerCollapsedContent === 'string' ? (
353
+ <span
354
+ style={{
355
+ color: '#2D5C63',
356
+ fontSize: '9px',
357
+ lineHeight: '1.2',
358
+ fontWeight: '600',
359
+ textAlign: 'center',
360
+ whiteSpace: 'nowrap',
361
+ overflow: 'hidden',
362
+ textOverflow: 'ellipsis',
363
+ maxWidth: '100%'
364
+ }}
365
+ >
366
+ {footerCollapsedContent}
367
+ </span>
368
+ ) : typeof footerCollapsedContent === 'object' && footerCollapsedContent.icon ? (
369
+ <div className="flex items-center justify-center">
370
+ {footerCollapsedContent.icon && (
371
+ <Icon
372
+ name={footerCollapsedContent.icon}
373
+ variant="24-outline"
374
+ size={14}
375
+ style={{ color: '#2D5C63' }}
376
+ />
377
+ )}
378
+ {footerCollapsedContent.text && (
379
+ <span
380
+ style={{
381
+ color: '#2D5C63',
382
+ fontSize: '10px',
383
+ marginLeft: footerCollapsedContent.icon ? '4px' : '0'
384
+ }}
385
+ >
386
+ {footerCollapsedContent.text}
387
+ </span>
388
+ )}
389
+ </div>
390
+ ) : (
391
+ footerCollapsedContent
392
+ )}
393
+ </div>
394
+ </div>
395
+ )}
396
+ </nav>
397
+ </aside>
398
+ );
399
+ };
400
+
401
+ // Componente SidebarPoint Mobile
402
+ const SidebarPointMobile = ({
403
+ sections = MOCK_SECTIONS,
404
+ activeItem,
405
+ onItemClick,
406
+ companyName = 'HEXA Point',
407
+ companyLogo,
408
+ onCompanyClick,
409
+ itemBadges = {},
410
+ className = '',
411
+ ...props
412
+ }) => {
413
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
414
+
415
+ const toggleMobileMenu = () => {
416
+ setIsMobileMenuOpen(!isMobileMenuOpen);
417
+ };
418
+
419
+ // Formatear fecha de hoy
420
+ const formattedDate = new Date().toLocaleDateString('es-AR', {
421
+ weekday: 'long',
422
+ year: 'numeric',
423
+ month: 'long',
424
+ day: 'numeric',
425
+ });
426
+ const capitalizedDate = formattedDate.charAt(0).toUpperCase() + formattedDate.slice(1);
427
+
428
+ return (
429
+ <>
430
+ <style>{`
431
+ .sidebar-point-mobile {
432
+ width: 100%;
433
+ transform: ${isMobileMenuOpen ? 'translateX(0)' : 'translateX(-100%)'};
434
+ position: fixed;
435
+ left: 0;
436
+ top: 0;
437
+ height: 100vh;
438
+ z-index: 50;
439
+ transition: transform 0.3s ease-in-out;
440
+ }
441
+ `}</style>
442
+ {/* Botón hamburguesa - solo visible cuando el menú está cerrado */}
443
+ {!isMobileMenuOpen && (
444
+ <button
445
+ onClick={toggleMobileMenu}
446
+ className="fixed top-4 left-4 z-50 p-2 bg-white border border-gray-200 rounded-lg shadow-md
447
+ hover:bg-gray-50 transition-colors"
448
+ aria-label="Toggle menu"
449
+ >
450
+ <Icon
451
+ name="Bars3Icon"
452
+ variant="24-outline"
453
+ size={24}
454
+ className="color-gray-700"
455
+ />
456
+ </button>
457
+ )}
458
+ {/* Overlay para cerrar el menú */}
459
+ {isMobileMenuOpen && (
460
+ <div
461
+ className="fixed inset-0 bg-black bg-opacity-50 z-40"
462
+ onClick={toggleMobileMenu}
463
+ />
464
+ )}
465
+ <aside
466
+ className={`bg-gray-100 border-r border-gray-200 sidebar-point-mobile ${className}`}
467
+ {...props}
468
+ >
469
+ <nav className="h-full flex flex-col">
470
+ {/* Header verde con "Point" y botón X */}
471
+ <div className="bg-brand px-4 py-4 flex items-center justify-between" style={{ backgroundColor: '#56B676' }}>
472
+ <Typography
473
+ variant="h5"
474
+ className="color-white font-bold"
475
+ >
476
+ Point
477
+ </Typography>
478
+ <button
479
+ onClick={toggleMobileMenu}
480
+ className="p-1 hover:bg-opacity-80 rounded transition-colors"
481
+ aria-label="Cerrar menú"
482
+ >
483
+ <Icon
484
+ name="XMarkIcon"
485
+ variant="24-outline"
486
+ size={24}
487
+ className="color-white"
488
+ />
489
+ </button>
490
+ </div>
491
+ {/* Sección gris con fecha */}
492
+ <div className="bg-gray-100 px-4 py-3 border-b border-gray-200">
493
+ <Typography
494
+ variant="body-md"
495
+ className="color-gray-700"
496
+ >
497
+ {capitalizedDate}
498
+ </Typography>
499
+ </div>
500
+ {/* Logo de empresa (si se proporciona) */}
501
+ {companyLogo && (
502
+ <div className="bg-gray-100 px-4 py-6 flex justify-center border-b border-gray-200">
503
+ <img
504
+ src={companyLogo}
505
+ alt={companyName || 'Company Logo'}
506
+ className="max-w-[120px] max-h-[120px] object-contain"
507
+ />
508
+ </div>
509
+ )}
510
+ {/* Contenido del sidebar mobile */}
511
+ <div className="flex-1 overflow-y-auto py-4">
512
+ {/* Item "Inicio" destacado */}
513
+ <div className="px-4 mb-4">
514
+ <button
515
+ onClick={() => {
516
+ onItemClick && onItemClick('inicio');
517
+ toggleMobileMenu();
518
+ }}
519
+ className={`w-full flex items-center cursor-pointer px-4 justify-between py-2.5 rounded-lg transition-all duration-200 ${
520
+ activeItem === 'inicio'
521
+ ? ''
522
+ : 'color-gray-700 hover:bg-gray-100'
523
+ }`}
524
+ style={
525
+ activeItem === 'inicio'
526
+ ? { backgroundColor: '#2D5C63' }
527
+ : {}
528
+ }
529
+ >
530
+ <div className="flex items-center">
531
+ <Icon
532
+ name="HomeIcon"
533
+ variant="24-outline"
534
+ size={20}
535
+ className={`mr-3 ${
536
+ activeItem === 'inicio' ? 'color-white' : 'color-gray-700'
537
+ }`}
538
+ />
539
+ <Typography
540
+ variant="body-md"
541
+ className={`font-medium ${
542
+ activeItem === 'inicio' ? 'color-white' : 'color-gray-700'
543
+ }`}
544
+ >
545
+ Inicio
546
+ </Typography>
547
+ </div>
548
+ {itemBadges['inicio'] !== undefined && itemBadges['inicio'] > 0 && (
549
+ <span
550
+ className="px-2 py-0.5 min-w-[20px] h-5
551
+ text-white rounded-full flex items-center justify-center
552
+ text-body-sm font-medium"
553
+ style={{
554
+ backgroundColor: '#6D3856',
555
+ borderRadius: '12px'
556
+ }}
557
+ >
558
+ {itemBadges['inicio'] > 9 ? '9+' : itemBadges['inicio']}
559
+ </span>
560
+ )}
561
+ </button>
562
+ </div>
563
+
564
+ {/* Secciones */}
565
+ {sections.map((section, sectionIndex) => (
566
+ <div key={sectionIndex} className="mb-6">
567
+ {/* Título de la sección */}
568
+ <div className="px-4 mb-2">
569
+ <Typography
570
+ variant="body-sm"
571
+ className="color-gray-500 uppercase font-medium tracking-wider"
572
+ >
573
+ {section.title}
574
+ </Typography>
575
+ </div>
576
+
577
+ {/* Items de la sección */}
578
+ <div className="space-y-1">
579
+ {section.items.map((item) => (
580
+ <div key={item.id} className="px-4">
581
+ <button
582
+ onClick={() => {
583
+ onItemClick && onItemClick(item.id);
584
+ toggleMobileMenu();
585
+ }}
586
+ className={`w-full flex items-center cursor-pointer px-4 justify-between py-2.5 rounded-lg transition-all duration-200 ${
587
+ activeItem === item.id
588
+ ? ''
589
+ : 'color-gray-700 hover:bg-gray-100'
590
+ }`}
591
+ style={
592
+ activeItem === item.id
593
+ ? { backgroundColor: '#2D5C63' }
594
+ : {}
595
+ }
596
+ >
597
+ <div className="flex items-center">
598
+ <Icon
599
+ name={item.icon}
600
+ variant="24-outline"
601
+ size={20}
602
+ className={`mr-3 ${
603
+ activeItem === item.id ? 'color-white' : 'color-gray-700'
604
+ }`}
605
+ />
606
+ <Typography
607
+ variant="body-md"
608
+ className={`font-medium ${
609
+ activeItem === item.id ? 'color-white' : 'color-gray-700'
610
+ }`}
611
+ >
612
+ {item.label}
613
+ </Typography>
614
+ </div>
615
+ {((itemBadges[item.id] !== undefined && itemBadges[item.id] > 0) || (item.id === 'empleados' && 2)) && (
616
+ <span
617
+ className="px-2 py-0.5 min-w-[20px] h-5
618
+ text-white rounded-full flex items-center justify-center
619
+ text-body-sm font-medium"
620
+ style={{
621
+ backgroundColor: '#6D3856',
622
+ borderRadius: '12px'
623
+ }}
624
+ >
625
+ {item.id === 'empleados' ? 2 : (itemBadges[item.id] > 9 ? '9+' : itemBadges[item.id])}
626
+ </span>
627
+ )}
628
+ </button>
629
+ </div>
630
+ ))}
631
+ </div>
632
+ </div>
633
+ ))}
634
+ </div>
635
+ </nav>
636
+ </aside>
637
+ </>
638
+ );
639
+ };
640
+
641
+ // Exportar ambos componentes
642
+ export { SidebarPointMobile };
643
+ export default SidebarPoint;
644
+
645
+