flysoft-react-ui 1.2.4 → 1.2.6

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 (265) hide show
  1. package/AI_CONTEXT.md +1400 -217
  2. package/AI_INTEGRATION_GUIDE.md +343 -0
  3. package/INTEGRATION_GUIDE.md +60 -0
  4. package/README.md +5 -3
  5. package/dist/components/form-controls/Input.d.ts.map +1 -1
  6. package/dist/components/layout/Accordion.d.ts +1 -0
  7. package/dist/components/layout/Accordion.d.ts.map +1 -1
  8. package/dist/components/layout/DataTable.d.ts.map +1 -1
  9. package/dist/components/layout/DropdownMenu.d.ts +2 -1
  10. package/dist/components/layout/DropdownMenu.d.ts.map +1 -1
  11. package/dist/components/layout/DropdownPanel.d.ts +2 -1
  12. package/dist/components/layout/DropdownPanel.d.ts.map +1 -1
  13. package/dist/components/layout/Filter.d.ts +1 -0
  14. package/dist/components/layout/Filter.d.ts.map +1 -1
  15. package/dist/components/layout/Menu.d.ts +2 -1
  16. package/dist/components/layout/Menu.d.ts.map +1 -1
  17. package/dist/components/layout/TabsGroup.d.ts +1 -0
  18. package/dist/components/layout/TabsGroup.d.ts.map +1 -1
  19. package/dist/index.css +1 -1
  20. package/dist/index.d.ts +2 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +11190 -24
  23. package/dist/index.js.map +1 -1
  24. package/dist/templates/forms/ContactForm.d.ts +1 -0
  25. package/dist/templates/forms/ContactForm.d.ts.map +1 -1
  26. package/dist/templates/forms/LoginForm.d.ts +1 -0
  27. package/dist/templates/forms/LoginForm.d.ts.map +1 -1
  28. package/dist/templates/forms/RegistrationForm.d.ts +1 -0
  29. package/dist/templates/forms/RegistrationForm.d.ts.map +1 -1
  30. package/dist/templates/layouts/DashboardLayout.d.ts +1 -0
  31. package/dist/templates/layouts/DashboardLayout.d.ts.map +1 -1
  32. package/dist/templates/layouts/SidebarLayout.d.ts +1 -0
  33. package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
  34. package/dist/templates/patterns/FormPattern.d.ts +1 -0
  35. package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
  36. package/dist/templates/patterns/ListPattern.d.ts +77 -0
  37. package/dist/templates/patterns/ListPattern.d.ts.map +1 -0
  38. package/package.json +8 -4
  39. package/dist/App.d.ts +0 -4
  40. package/dist/App.d.ts.map +0 -1
  41. package/dist/App.js +0 -30
  42. package/dist/components/ThemeSwitcher.js +0 -12
  43. package/dist/components/form-controls/AutocompleteInput.js +0 -680
  44. package/dist/components/form-controls/Button.js +0 -211
  45. package/dist/components/form-controls/Checkbox.js +0 -79
  46. package/dist/components/form-controls/CurrencyInput.js +0 -106
  47. package/dist/components/form-controls/DateInput.js +0 -578
  48. package/dist/components/form-controls/DatePicker.js +0 -144
  49. package/dist/components/form-controls/Input.js +0 -35
  50. package/dist/components/form-controls/LinkButton.js +0 -248
  51. package/dist/components/form-controls/Pagination.js +0 -23
  52. package/dist/components/form-controls/RadioButtonGroup.js +0 -220
  53. package/dist/components/form-controls/SearchSelectInput.js +0 -336
  54. package/dist/components/form-controls/index.js +0 -11
  55. package/dist/components/index.js +0 -7
  56. package/dist/components/layout/Accordion.js +0 -67
  57. package/dist/components/layout/AppLayout.js +0 -230
  58. package/dist/components/layout/Card.js +0 -54
  59. package/dist/components/layout/Collection.js +0 -18
  60. package/dist/components/layout/DataField.js +0 -38
  61. package/dist/components/layout/DataTable.js +0 -164
  62. package/dist/components/layout/DropdownMenu.js +0 -176
  63. package/dist/components/layout/DropdownPanel.js +0 -162
  64. package/dist/components/layout/Filter.js +0 -629
  65. package/dist/components/layout/Menu.js +0 -21
  66. package/dist/components/layout/TabPanel.js +0 -11
  67. package/dist/components/layout/TabsGroup.js +0 -52
  68. package/dist/components/layout/index.js +0 -12
  69. package/dist/components/utils/Avatar.js +0 -77
  70. package/dist/components/utils/Badge.js +0 -151
  71. package/dist/components/utils/Dialog.js +0 -44
  72. package/dist/components/utils/FiltersDialog.js +0 -104
  73. package/dist/components/utils/Loader.js +0 -44
  74. package/dist/components/utils/RoadMap.js +0 -139
  75. package/dist/components/utils/Skeleton.js +0 -10
  76. package/dist/components/utils/Snackbar.js +0 -136
  77. package/dist/components/utils/SnackbarContainer.js +0 -26
  78. package/dist/components/utils/iconUtils.js +0 -40
  79. package/dist/components/utils/index.js +0 -9
  80. package/dist/contexts/AppLayoutContext.js +0 -104
  81. package/dist/contexts/AuthContext.js +0 -224
  82. package/dist/contexts/CrudContext.js +0 -333
  83. package/dist/contexts/SnackbarContext.js +0 -41
  84. package/dist/contexts/ThemeContext.js +0 -197
  85. package/dist/contexts/index.js +0 -13
  86. package/dist/contexts/presets.js +0 -311
  87. package/dist/contexts/types.js +0 -1
  88. package/dist/docs/AccordionDocs.d.ts +0 -4
  89. package/dist/docs/AccordionDocs.d.ts.map +0 -1
  90. package/dist/docs/AccordionDocs.js +0 -21
  91. package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts +0 -13
  92. package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts.map +0 -1
  93. package/dist/docs/AuthDocs.tsx/AuthDocs.js +0 -18
  94. package/dist/docs/AuthDocs.tsx/AuthDocsContent.d.ts +0 -2
  95. package/dist/docs/AuthDocs.tsx/AuthDocsContent.d.ts.map +0 -1
  96. package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +0 -22
  97. package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts +0 -24
  98. package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts.map +0 -1
  99. package/dist/docs/AuthDocs.tsx/mockAuthService.js +0 -78
  100. package/dist/docs/AutocompleteInputDocs.d.ts +0 -4
  101. package/dist/docs/AutocompleteInputDocs.d.ts.map +0 -1
  102. package/dist/docs/AutocompleteInputDocs.js +0 -84
  103. package/dist/docs/AvatarDocs.d.ts +0 -4
  104. package/dist/docs/AvatarDocs.d.ts.map +0 -1
  105. package/dist/docs/AvatarDocs.js +0 -7
  106. package/dist/docs/BadgeDocs.d.ts +0 -4
  107. package/dist/docs/BadgeDocs.d.ts.map +0 -1
  108. package/dist/docs/BadgeDocs.js +0 -9
  109. package/dist/docs/ButtonDocs.d.ts +0 -4
  110. package/dist/docs/ButtonDocs.d.ts.map +0 -1
  111. package/dist/docs/ButtonDocs.js +0 -7
  112. package/dist/docs/CardDocs.d.ts +0 -4
  113. package/dist/docs/CardDocs.d.ts.map +0 -1
  114. package/dist/docs/CardDocs.js +0 -22
  115. package/dist/docs/CheckboxDocs.d.ts +0 -4
  116. package/dist/docs/CheckboxDocs.d.ts.map +0 -1
  117. package/dist/docs/CheckboxDocs.js +0 -7
  118. package/dist/docs/CurrencyInputDocs.d.ts +0 -4
  119. package/dist/docs/CurrencyInputDocs.d.ts.map +0 -1
  120. package/dist/docs/CurrencyInputDocs.js +0 -22
  121. package/dist/docs/DataFieldDocs.d.ts +0 -4
  122. package/dist/docs/DataFieldDocs.d.ts.map +0 -1
  123. package/dist/docs/DataFieldDocs.js +0 -7
  124. package/dist/docs/DataTableDocs.d.ts +0 -4
  125. package/dist/docs/DataTableDocs.d.ts.map +0 -1
  126. package/dist/docs/DataTableDocs.js +0 -244
  127. package/dist/docs/DateInputDocs.d.ts +0 -5
  128. package/dist/docs/DateInputDocs.d.ts.map +0 -1
  129. package/dist/docs/DateInputDocs.js +0 -19
  130. package/dist/docs/DatePickerDocs.d.ts +0 -5
  131. package/dist/docs/DatePickerDocs.d.ts.map +0 -1
  132. package/dist/docs/DatePickerDocs.js +0 -16
  133. package/dist/docs/DialogDocs.d.ts +0 -4
  134. package/dist/docs/DialogDocs.d.ts.map +0 -1
  135. package/dist/docs/DialogDocs.js +0 -13
  136. package/dist/docs/DocAdmin.d.ts +0 -4
  137. package/dist/docs/DocAdmin.d.ts.map +0 -1
  138. package/dist/docs/DocAdmin.js +0 -68
  139. package/dist/docs/DocsMenu.d.ts +0 -2
  140. package/dist/docs/DocsMenu.d.ts.map +0 -1
  141. package/dist/docs/DocsMenu.js +0 -5
  142. package/dist/docs/DocsRouter.d.ts +0 -4
  143. package/dist/docs/DocsRouter.d.ts.map +0 -1
  144. package/dist/docs/DocsRouter.js +0 -39
  145. package/dist/docs/DropdownMenuDocs.d.ts +0 -4
  146. package/dist/docs/DropdownMenuDocs.d.ts.map +0 -1
  147. package/dist/docs/DropdownMenuDocs.js +0 -66
  148. package/dist/docs/DropdownPanelDocs.d.ts +0 -4
  149. package/dist/docs/DropdownPanelDocs.d.ts.map +0 -1
  150. package/dist/docs/DropdownPanelDocs.js +0 -7
  151. package/dist/docs/ExampleFormDocs.d.ts +0 -4
  152. package/dist/docs/ExampleFormDocs.d.ts.map +0 -1
  153. package/dist/docs/ExampleFormDocs.js +0 -153
  154. package/dist/docs/FilterDocs.d.ts +0 -4
  155. package/dist/docs/FilterDocs.d.ts.map +0 -1
  156. package/dist/docs/FilterDocs.js +0 -130
  157. package/dist/docs/InputDocs.d.ts +0 -4
  158. package/dist/docs/InputDocs.d.ts.map +0 -1
  159. package/dist/docs/InputDocs.js +0 -17
  160. package/dist/docs/LinkButtonDocs.d.ts +0 -4
  161. package/dist/docs/LinkButtonDocs.d.ts.map +0 -1
  162. package/dist/docs/LinkButtonDocs.js +0 -7
  163. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +0 -2
  164. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +0 -1
  165. package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +0 -47
  166. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts +0 -2
  167. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts.map +0 -1
  168. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.js +0 -34
  169. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts +0 -2
  170. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts.map +0 -1
  171. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.js +0 -66
  172. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +0 -2
  173. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +0 -1
  174. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +0 -7
  175. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts +0 -10
  176. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts.map +0 -1
  177. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.js +0 -39
  178. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +0 -2
  179. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +0 -1
  180. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +0 -57
  181. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +0 -9
  182. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +0 -1
  183. package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +0 -30
  184. package/dist/docs/LoaderDocs.d.ts +0 -4
  185. package/dist/docs/LoaderDocs.d.ts.map +0 -1
  186. package/dist/docs/LoaderDocs.js +0 -33
  187. package/dist/docs/MenuDocs.d.ts +0 -4
  188. package/dist/docs/MenuDocs.d.ts.map +0 -1
  189. package/dist/docs/MenuDocs.js +0 -26
  190. package/dist/docs/PaginationDocs.d.ts +0 -4
  191. package/dist/docs/PaginationDocs.d.ts.map +0 -1
  192. package/dist/docs/PaginationDocs.js +0 -38
  193. package/dist/docs/RadioButtonGroupDocs.d.ts +0 -4
  194. package/dist/docs/RadioButtonGroupDocs.d.ts.map +0 -1
  195. package/dist/docs/RadioButtonGroupDocs.js +0 -46
  196. package/dist/docs/RoadMapDocs.d.ts +0 -4
  197. package/dist/docs/RoadMapDocs.d.ts.map +0 -1
  198. package/dist/docs/RoadMapDocs.js +0 -171
  199. package/dist/docs/SearchSelectInputDocs.d.ts +0 -4
  200. package/dist/docs/SearchSelectInputDocs.d.ts.map +0 -1
  201. package/dist/docs/SearchSelectInputDocs.js +0 -168
  202. package/dist/docs/SkeletonDocs.d.ts +0 -4
  203. package/dist/docs/SkeletonDocs.d.ts.map +0 -1
  204. package/dist/docs/SkeletonDocs.js +0 -7
  205. package/dist/docs/SnackbarDocs.d.ts +0 -4
  206. package/dist/docs/SnackbarDocs.d.ts.map +0 -1
  207. package/dist/docs/SnackbarDocs.js +0 -69
  208. package/dist/docs/TabsGroupDocs.d.ts +0 -4
  209. package/dist/docs/TabsGroupDocs.d.ts.map +0 -1
  210. package/dist/docs/TabsGroupDocs.js +0 -38
  211. package/dist/docs/ThemeSwitcherDocs.d.ts +0 -4
  212. package/dist/docs/ThemeSwitcherDocs.d.ts.map +0 -1
  213. package/dist/docs/ThemeSwitcherDocs.js +0 -11
  214. package/dist/docs/docMockServices/empresaService.d.ts +0 -38
  215. package/dist/docs/docMockServices/empresaService.d.ts.map +0 -1
  216. package/dist/docs/docMockServices/empresaService.js +0 -125
  217. package/dist/docs/docMockServices/index.d.ts +0 -9
  218. package/dist/docs/docMockServices/index.d.ts.map +0 -1
  219. package/dist/docs/docMockServices/index.js +0 -8
  220. package/dist/docs/docMockServices/initialData.d.ts +0 -6
  221. package/dist/docs/docMockServices/initialData.d.ts.map +0 -1
  222. package/dist/docs/docMockServices/initialData.js +0 -132
  223. package/dist/docs/docMockServices/interfaces.d.ts +0 -38
  224. package/dist/docs/docMockServices/interfaces.d.ts.map +0 -1
  225. package/dist/docs/docMockServices/interfaces.js +0 -1
  226. package/dist/docs/docMockServices/personaEmpresaService.d.ts +0 -43
  227. package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +0 -1
  228. package/dist/docs/docMockServices/personaEmpresaService.js +0 -151
  229. package/dist/docs/docMockServices/personaService.d.ts +0 -39
  230. package/dist/docs/docMockServices/personaService.d.ts.map +0 -1
  231. package/dist/docs/docMockServices/personaService.js +0 -190
  232. package/dist/helpers/currencyFormat.js +0 -3
  233. package/dist/helpers/getErrorMessage.js +0 -13
  234. package/dist/helpers/getInitialLetters.js +0 -5
  235. package/dist/helpers/getQueryString.js +0 -13
  236. package/dist/helpers/index.js +0 -9
  237. package/dist/helpers/mappers.js +0 -27
  238. package/dist/helpers/nameValueArrayToObject.js +0 -3
  239. package/dist/helpers/objectToQueryString.js +0 -3
  240. package/dist/helpers/queryStringToObject.js +0 -13
  241. package/dist/helpers/regularExpressions.js +0 -5
  242. package/dist/hooks/index.js +0 -6
  243. package/dist/hooks/useAsyncRequest.js +0 -53
  244. package/dist/hooks/useBreakpoint.js +0 -59
  245. package/dist/hooks/useElementScroll.js +0 -58
  246. package/dist/hooks/useEnum.js +0 -21
  247. package/dist/hooks/useGlobalThemeStyles.js +0 -40
  248. package/dist/hooks/useThemeOverride.js +0 -99
  249. package/dist/interfaces/index.js +0 -1
  250. package/dist/interfaces/name-value.interface.js +0 -1
  251. package/dist/interfaces/pagination.interface.js +0 -1
  252. package/dist/main.d.ts +0 -2
  253. package/dist/main.d.ts.map +0 -1
  254. package/dist/main.js +0 -6
  255. package/dist/services/apiClient.js +0 -216
  256. package/dist/services/index.js +0 -1
  257. package/dist/styles.d.ts +0 -2
  258. package/dist/styles.d.ts.map +0 -1
  259. package/dist/styles.js +0 -3
  260. package/dist/templates/forms/ContactForm.js +0 -58
  261. package/dist/templates/forms/LoginForm.js +0 -36
  262. package/dist/templates/forms/RegistrationForm.js +0 -54
  263. package/dist/templates/layouts/DashboardLayout.js +0 -26
  264. package/dist/templates/layouts/SidebarLayout.js +0 -28
  265. package/dist/templates/patterns/FormPattern.js +0 -68
@@ -1,136 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useEffect, useState, useRef, useCallback } from "react";
3
- import { normalizeIconClass } from "./iconUtils";
4
- export const Snackbar = React.memo(({ id, message, variant, duration = 3000, icon, iconLabel, onClose }) => {
5
- const [progress, setProgress] = useState(100);
6
- const [isClosing, setIsClosing] = useState(false);
7
- const intervalRef = useRef(null);
8
- const startTimeRef = useRef(Date.now());
9
- const remainingTimeRef = useRef(duration);
10
- const closingRef = useRef(false);
11
- // Mapeo de variantes a colores y clases
12
- const variantConfig = {
13
- primary: {
14
- bg: "bg-[var(--color-primary-light)]",
15
- border: "border-[var(--color-primary)]",
16
- text: "text-gray-800",
17
- progressColor: "var(--color-primary)",
18
- },
19
- secondary: {
20
- bg: "bg-[var(--color-secondary-light)]",
21
- border: "border-[var(--color-secondary)]",
22
- text: "text-gray-800",
23
- progressColor: "var(--color-secondary)",
24
- },
25
- success: {
26
- bg: "bg-[var(--color-success-light)]",
27
- border: "border-[var(--color-success)]",
28
- text: "text-gray-800",
29
- progressColor: "var(--color-success)",
30
- },
31
- warning: {
32
- bg: "bg-[var(--color-warning-light)]",
33
- border: "border-[var(--color-warning)]",
34
- text: "text-gray-800",
35
- progressColor: "var(--color-warning)",
36
- },
37
- danger: {
38
- bg: "bg-[var(--color-danger-light)]",
39
- border: "border-[var(--color-danger)]",
40
- text: "text-gray-800",
41
- progressColor: "var(--color-danger)",
42
- },
43
- info: {
44
- bg: "bg-[var(--color-info-light)]",
45
- border: "border-[var(--color-info)]",
46
- text: "text-gray-800",
47
- progressColor: "var(--color-info)",
48
- },
49
- };
50
- const config = variantConfig[variant];
51
- // Función para cerrar el snackbar
52
- const handleClose = useCallback(() => {
53
- if (closingRef.current)
54
- return;
55
- closingRef.current = true;
56
- setIsClosing(true);
57
- // Limpiar intervalo inmediatamente
58
- if (intervalRef.current) {
59
- clearInterval(intervalRef.current);
60
- intervalRef.current = null;
61
- }
62
- // Esperar a que termine la animación antes de remover del estado global
63
- setTimeout(() => {
64
- onClose(id);
65
- }, 300);
66
- }, [id, onClose]);
67
- // Efecto para la barra de progreso
68
- useEffect(() => {
69
- if (duration <= 0)
70
- return;
71
- const updateProgress = () => {
72
- if (closingRef.current)
73
- return;
74
- const elapsed = Date.now() - startTimeRef.current;
75
- const newProgress = Math.max(0, 100 - (elapsed / duration) * 100);
76
- setProgress(newProgress);
77
- if (newProgress <= 0) {
78
- handleClose();
79
- }
80
- };
81
- intervalRef.current = window.setInterval(updateProgress, 50);
82
- return () => {
83
- if (intervalRef.current) {
84
- window.clearInterval(intervalRef.current);
85
- }
86
- };
87
- }, [duration, handleClose]);
88
- // Pausar el progreso cuando el mouse está sobre el snackbar
89
- const handleMouseEnter = () => {
90
- if (closingRef.current)
91
- return;
92
- if (intervalRef.current) {
93
- clearInterval(intervalRef.current);
94
- intervalRef.current = null;
95
- }
96
- const elapsed = Date.now() - startTimeRef.current;
97
- remainingTimeRef.current = duration - elapsed;
98
- };
99
- // Reanudar el progreso cuando el mouse sale del snackbar
100
- const handleMouseLeave = () => {
101
- if (closingRef.current)
102
- return;
103
- if (remainingTimeRef.current > 0) {
104
- startTimeRef.current = Date.now();
105
- const updateProgress = () => {
106
- if (closingRef.current)
107
- return;
108
- const elapsed = Date.now() - startTimeRef.current;
109
- const newProgress = Math.max(0, ((remainingTimeRef.current - elapsed) / duration) * 100);
110
- setProgress(newProgress);
111
- if (newProgress <= 0) {
112
- handleClose();
113
- }
114
- };
115
- intervalRef.current = window.setInterval(updateProgress, 50);
116
- }
117
- };
118
- // Íconos por defecto según la variante
119
- const defaultIcons = {
120
- primary: "fa-info-circle",
121
- secondary: "fa-info-circle",
122
- success: "fa-check-circle",
123
- warning: "fa-exclamation-triangle",
124
- danger: "fa-times-circle",
125
- info: "fa-info-circle",
126
- };
127
- const displayIcon = icon || defaultIcons[variant];
128
- return (_jsx("div", { className: `
129
- relative w-[18rem] bg-white rounded-md shadow-lg border border-gray-200
130
- overflow-hidden transition-all duration-300 ease-in-out
131
- ${isClosing ? "opacity-0 translate-x-full" : "opacity-100 translate-x-0"}
132
- `, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: "alert", "aria-live": "polite", children: _jsxs("div", { className: `${config.bg} ${config.text} p-4 flex items-start gap-3 relative`, children: [duration > 0 && (_jsx("div", { className: "absolute bottom-0 left-0 right-0 h-[3px] overflow-hidden", children: _jsx("div", { className: "h-full transition-all duration-50 ease-linear", style: {
133
- width: `${progress}%`,
134
- backgroundColor: "#00000050",
135
- } }) })), displayIcon && (_jsx("div", { className: "flex-shrink-0 -mt-0.5", children: _jsx("i", { className: `${normalizeIconClass(displayIcon)} text-base`, "aria-hidden": !iconLabel, "aria-label": iconLabel }) })), _jsx("div", { className: "flex-1 min-w-0", children: _jsx("p", { className: "text-sm font-medium break-words max-w-full", children: message }) }), _jsx("button", { onClick: handleClose, className: "flex-shrink-0 ml-2 text-gray-600 hover:text-gray-800 transition-colors cursor-pointer", "aria-label": "Cerrar notificaci\u00F3n", type: "button", children: _jsx("i", { className: `${normalizeIconClass("fa-times")} text-sm` }) })] }) }));
136
- });
@@ -1,26 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import React from "react";
3
- import { useSnackbarState, useSnackbar } from "../../contexts/SnackbarContext";
4
- import { Snackbar } from "./Snackbar";
5
- export const SnackbarContainer = ({ position = "top-right", maxSnackbars = 5, }) => {
6
- const snackbars = useSnackbarState();
7
- const { removeSnackbar } = useSnackbar();
8
- // Limitar el número de snackbars visibles
9
- const visibleSnackbars = snackbars.slice(-maxSnackbars);
10
- // Clases de posición
11
- const positionClasses = {
12
- "top-right": "top-4 right-4",
13
- "top-left": "top-4 left-4",
14
- "bottom-right": "bottom-4 right-4",
15
- "bottom-left": "bottom-4 left-4",
16
- "top-center": "top-4 left-1/2 -translate-x-1/2",
17
- "bottom-center": "bottom-4 left-1/2 -translate-x-1/2",
18
- };
19
- if (snackbars.length === 0) {
20
- return null;
21
- }
22
- return (_jsx("div", { className: `
23
- fixed z-50 pointer-events-none
24
- ${positionClasses[position]}
25
- `, "aria-live": "polite", "aria-atomic": "true", children: _jsx("div", { className: "flex flex-col gap-3 pointer-events-auto", children: visibleSnackbars.map((snackbar) => (_jsx(Snackbar, { id: snackbar.id, message: snackbar.message, variant: snackbar.variant, duration: snackbar.duration, icon: snackbar.icon, iconLabel: snackbar.iconLabel, onClose: removeSnackbar }, snackbar.id))) }) }));
26
- };
@@ -1,40 +0,0 @@
1
- /**
2
- * Normaliza las clases de iconos de FontAwesome para usar el estilo light (fal) por defecto
3
- *
4
- * Convierte:
5
- * - "fa fa-user" -> "fal fa-user"
6
- * - "fas fa-user" -> "fal fa-user"
7
- * - "far fa-user" -> "fal fa-user"
8
- * - "fal fa-user" -> "fal fa-user" (ya es light, se mantiene)
9
- * - "fa-user" -> "fal fa-user"
10
- * - "fa-spinner fa-spin" -> "fal fa-spinner fa-spin" (preserva clases adicionales)
11
- *
12
- * @param iconClass - La clase del icono a normalizar
13
- * @returns La clase del icono normalizada con el estilo light (fal)
14
- */
15
- export function normalizeIconClass(iconClass) {
16
- if (!iconClass)
17
- return "";
18
- // Dividir las clases por espacios
19
- const classes = iconClass.trim().split(/\s+/);
20
- // Buscar y reemplazar el prefijo de estilo
21
- const stylePrefixes = ["fas", "far", "fal", "fab"];
22
- let hasStylePrefix = false;
23
- const normalizedClasses = classes.map((cls) => {
24
- // Si es un prefijo de estilo, reemplazarlo por "fal"
25
- if (stylePrefixes.includes(cls)) {
26
- hasStylePrefix = true;
27
- return "fal";
28
- }
29
- return cls;
30
- });
31
- // Si no tenía prefijo de estilo y la primera clase empieza con "fa-", agregar "fal" al inicio
32
- if (!hasStylePrefix && classes[0]?.startsWith("fa-")) {
33
- normalizedClasses.unshift("fal");
34
- }
35
- // Si no tenía prefijo de estilo y ninguna clase es un prefijo, agregar "fal" al inicio
36
- else if (!hasStylePrefix && !classes.some(cls => stylePrefixes.includes(cls))) {
37
- normalizedClasses.unshift("fal");
38
- }
39
- return normalizedClasses.join(" ");
40
- }
@@ -1,9 +0,0 @@
1
- export { Badge } from "./Badge";
2
- export { Avatar } from "./Avatar";
3
- export { RoadMap } from "./RoadMap";
4
- export { Dialog } from "./Dialog";
5
- export { Loader } from "./Loader";
6
- export { FiltersDialog } from "./FiltersDialog";
7
- export { Snackbar } from "./Snackbar";
8
- export { SnackbarContainer } from "./SnackbarContainer";
9
- export { Skeleton } from "./Skeleton";
@@ -1,104 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { createContext, useContext, useState, useCallback, } from "react";
3
- import { ThemeProvider, useTheme } from "./ThemeContext";
4
- import { AppLayout } from "../components/layout/AppLayout";
5
- import { SnackbarProvider } from "./SnackbarContext";
6
- import { SnackbarContainer } from "../components/utils/SnackbarContainer";
7
- const AppLayoutContext = createContext(undefined);
8
- // Internal component that uses ThemeContext and provides AppLayoutContext
9
- const AppLayoutProviderInner = ({ children, initialNavbar, initialLeftDrawer, initialContentFooter, initialClassName, }) => {
10
- // Get theme context
11
- const themeContext = useTheme();
12
- // Layout state - ensure default height is set
13
- const [navbar, setNavbar] = useState(() => {
14
- const defaultNavbar = { fullWidthNavbar: true, height: "64px" };
15
- if (initialNavbar) {
16
- return { ...defaultNavbar, ...initialNavbar };
17
- }
18
- return defaultNavbar;
19
- });
20
- const [leftDrawer, setLeftDrawer] = useState(initialLeftDrawer || {});
21
- const [contentFooter, setContentFooter] = useState(initialContentFooter);
22
- const [className, setClassName] = useState(initialClassName || "");
23
- // Memoize setters to avoid unnecessary re-renders
24
- const handleSetNavbar = useCallback((newNavbar) => {
25
- setNavbar(newNavbar);
26
- }, []);
27
- const handleSetLeftDrawer = useCallback((newLeftDrawer) => {
28
- setLeftDrawer(newLeftDrawer);
29
- }, []);
30
- const handleSetClassName = useCallback((newClassName) => {
31
- setClassName(newClassName);
32
- }, []);
33
- const handleSetContentFooter = useCallback((node) => {
34
- setContentFooter(node);
35
- }, []);
36
- // Setters para actualizar solo los nodos del navbar
37
- const handleSetNavBarLeftNode = useCallback((node) => {
38
- setNavbar((prev) => {
39
- if (!prev) {
40
- // Si no hay navbar previo, crear uno nuevo con valores por defecto
41
- return {
42
- fullWidthNavbar: true,
43
- height: "64px",
44
- navBarLeftNode: node,
45
- };
46
- }
47
- return {
48
- ...prev,
49
- navBarLeftNode: node,
50
- };
51
- });
52
- }, []);
53
- const handleSetNavbarRightNode = useCallback((node) => {
54
- setNavbar((prev) => {
55
- if (!prev) {
56
- // Si no hay navbar previo, crear uno nuevo con valores por defecto
57
- return {
58
- fullWidthNavbar: true,
59
- height: "64px",
60
- navBarRightNode: node,
61
- };
62
- }
63
- return {
64
- ...prev,
65
- navBarRightNode: node,
66
- };
67
- });
68
- }, []);
69
- const value = {
70
- // Theme context values
71
- ...themeContext,
72
- // Layout state
73
- navbar,
74
- leftDrawer,
75
- contentFooter,
76
- className,
77
- // Layout setters
78
- setNavbar: handleSetNavbar,
79
- setLeftDrawer: handleSetLeftDrawer,
80
- setContentFooter: handleSetContentFooter,
81
- setClassName: handleSetClassName,
82
- setNavBarLeftNode: handleSetNavBarLeftNode,
83
- setNavbarRightNode: handleSetNavbarRightNode,
84
- };
85
- return (_jsx(AppLayoutContext.Provider, { value: value, children: _jsx(AppLayout, { navbar: navbar, leftDrawer: leftDrawer, contentFooter: contentFooter, className: className, children: children }) }));
86
- };
87
- export const AppLayoutProvider = ({ children, initialTheme = "light", storageKey = "flysoft-theme", forceInitialTheme = false, initialNavbar, initialLeftDrawer, initialContentFooter, className = "", }) => {
88
- return (_jsx(ThemeProvider, { initialTheme: initialTheme, storageKey: storageKey, forceInitialTheme: forceInitialTheme, children: _jsxs(SnackbarProvider, { children: [_jsx(AppLayoutProviderInner, { initialNavbar: initialNavbar, initialLeftDrawer: initialLeftDrawer, initialContentFooter: initialContentFooter, initialClassName: className, children: children }), _jsx(SnackbarContainer, { position: "bottom-right" })] }) }));
89
- };
90
- // Hook to use AppLayout context
91
- // eslint-disable-next-line react-refresh/only-export-components
92
- export const useAppLayout = () => {
93
- const context = useContext(AppLayoutContext);
94
- if (context === undefined) {
95
- throw new Error("useAppLayout must be used within an AppLayoutProvider");
96
- }
97
- return context;
98
- };
99
- // Hook to check if AppLayout context is available
100
- // eslint-disable-next-line react-refresh/only-export-components
101
- export const useAppLayoutContext = () => {
102
- const context = useContext(AppLayoutContext);
103
- return context !== undefined;
104
- };
@@ -1,224 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useEffect, useState } from "react";
3
- export const AuthContext = createContext({
4
- user: null,
5
- login: async () => { },
6
- logout: async () => { },
7
- isAuthenticated: false,
8
- isLoading: false,
9
- });
10
- const initAuth = () => {
11
- const authString = localStorage.getItem("auth");
12
- if (!authString)
13
- return {};
14
- return JSON.parse(authString);
15
- };
16
- const storeAuth = (auth) => {
17
- localStorage.setItem("auth", JSON.stringify(auth));
18
- };
19
- const removeStoredAuth = () => {
20
- localStorage.removeItem("auth");
21
- };
22
- /**
23
- * Verifica si un token ha expirado basándose en el string expires en formato ISO 8601
24
- * @param expires - String de fecha en formato ISO 8601
25
- * @returns true si el token ha expirado o si el formato es inválido, false si está vigente
26
- */
27
- const isTokenExpired = (expires) => {
28
- if (!expires) {
29
- return true; // Si no hay fecha de expiración, consideramos que está expirado
30
- }
31
- try {
32
- // Validar formato ISO 8601 básico (debe poder ser parseado por Date)
33
- const expirationDate = new Date(expires);
34
- // Verificar que la fecha sea válida
35
- if (isNaN(expirationDate.getTime())) {
36
- console.warn("Formato de fecha de expiración inválido:", expires);
37
- return true;
38
- }
39
- // Comparar con la fecha actual (agregamos un margen de 1 minuto para evitar problemas de precisión)
40
- const now = new Date();
41
- const oneMinuteInMs = 60 * 1000;
42
- return expirationDate.getTime() <= now.getTime() + oneMinuteInMs;
43
- }
44
- catch (error) {
45
- console.error("Error al verificar expiración del token:", error);
46
- return true; // En caso de error, considerar como expirado por seguridad
47
- }
48
- };
49
- /**
50
- * Valida que un usuario tenga un token vigente
51
- * @param user - Objeto de usuario a validar
52
- * @returns true si el usuario tiene un token válido y vigente, false en caso contrario
53
- */
54
- const isUserTokenValid = (user) => {
55
- if (!user || !user.id) {
56
- return false;
57
- }
58
- if (!user.token) {
59
- return false;
60
- }
61
- return !isTokenExpired(user.token.expires);
62
- };
63
- export const AuthProvider = ({ children, getToken, getUserData, refreshToken, removeToken, showLog = false, }) => {
64
- const [user, setUser] = useState(null);
65
- const [isAuthenticated, setIsAuthenticated] = useState(false);
66
- const [isLoading, setIsLoading] = useState(true);
67
- const log = (action, data, isError = false) => {
68
- if (isError) {
69
- console.error(`[AuthContext] ${action}: `, data);
70
- }
71
- else if (showLog) {
72
- console.log(`[AuthContext] ${action}: `, data);
73
- }
74
- };
75
- useEffect(() => {
76
- const auth = initAuth();
77
- log("Init Auth - Retrieved from storage", auth);
78
- // Verificar que el usuario tenga un token válido y vigente
79
- const isValid = isUserTokenValid(auth);
80
- log("Init Auth - Token valid check", { isValid, auth });
81
- if (isValid) {
82
- setUser(auth);
83
- setIsAuthenticated(true);
84
- log("Init Auth - User authenticated restored", auth);
85
- }
86
- else {
87
- // Si el token está expirado o es inválido, limpiar el almacenamiento
88
- if (auth.id && isTokenExpired(auth.token?.expires)) {
89
- log("Init Auth - Token expired or invalid, cleaning storage", auth);
90
- removeStoredAuth();
91
- }
92
- else {
93
- log("Init Auth - No valid session found", auth);
94
- }
95
- setUser(null);
96
- setIsAuthenticated(false);
97
- }
98
- setIsLoading(false);
99
- }, []);
100
- const login = async (username, password) => {
101
- setIsLoading(true);
102
- log("Login - Start", { username });
103
- try {
104
- const token = await getToken(username, password);
105
- log("Login - Token received", token);
106
- if (token.accessToken) {
107
- // Verificar que el token recibido no esté expirado antes de continuar
108
- const expired = isTokenExpired(token.expires);
109
- log("Login - Token expiration check", { expires: token.expires, expired });
110
- if (expired) {
111
- log("Login - Token expired upon receipt", token, true);
112
- setUser(null);
113
- setIsAuthenticated(false);
114
- setIsLoading(false);
115
- return;
116
- }
117
- const { id, name, aditionalData } = await getUserData(token);
118
- log("Login - User data received", { id, name, aditionalData });
119
- const userData = {
120
- id,
121
- name,
122
- aditionalData,
123
- token,
124
- };
125
- // Validar nuevamente antes de establecer el estado
126
- const isValid = isUserTokenValid(userData);
127
- log("Login - Final validation", { isValid, userData });
128
- if (isValid) {
129
- setUser(userData);
130
- storeAuth(userData);
131
- setIsAuthenticated(true);
132
- log("Login - Success", userData);
133
- }
134
- else {
135
- setUser(null);
136
- setIsAuthenticated(false);
137
- log("Login - Validation failed", userData, true);
138
- }
139
- }
140
- else {
141
- setUser(null);
142
- setIsAuthenticated(false);
143
- log("Login - No access token in response", token, true);
144
- }
145
- }
146
- catch (error) {
147
- setUser(null);
148
- setIsAuthenticated(false);
149
- log("Login - Error", error, true);
150
- throw error;
151
- }
152
- finally {
153
- setIsLoading(false);
154
- }
155
- };
156
- const logout = async () => {
157
- log("Logout - Start", { user });
158
- removeStoredAuth();
159
- setUser(null);
160
- if (removeToken && user?.token) {
161
- try {
162
- await removeToken(user.token);
163
- log("Logout - Token removed from server");
164
- }
165
- catch (e) {
166
- log("Logout - Error removing token", e, true);
167
- }
168
- }
169
- setIsAuthenticated(false);
170
- log("Logout - Completed");
171
- };
172
- // Validar el token periódicamente o cuando cambia el usuario
173
- // Esto asegura que si el token expira durante la sesión, se actualice el estado
174
- useEffect(() => {
175
- if (user && user.token?.expires) {
176
- const checkTokenExpiration = async () => {
177
- const expired = isTokenExpired(user.token?.expires);
178
- log("Token Check - Checking expiration", { expires: user.token?.expires, expired });
179
- if (expired) {
180
- let refreshed = false;
181
- // Si existe la función de refresco, intentar renovar el token antes de cerrar sesión
182
- if (refreshToken && user.token) {
183
- try {
184
- log("Token Check - Attempting refresh", { oldToken: user.token });
185
- const newToken = await refreshToken(user.token);
186
- log("Token Check - Refresh response", newToken);
187
- // Verificar que el nuevo token sea válido y no esté expirado
188
- if (newToken && newToken.accessToken && !isTokenExpired(newToken.expires)) {
189
- const newUser = { ...user, token: newToken };
190
- setUser(newUser);
191
- storeAuth(newUser);
192
- refreshed = true;
193
- log("Token Check - Refresh success", newUser);
194
- }
195
- else {
196
- log("Token Check - Refreshed token invalid or expired", newToken, true);
197
- }
198
- }
199
- catch (error) {
200
- console.error("Error al intentar refrescar el token:", error);
201
- log("Token Check - Refresh error", error, true);
202
- }
203
- }
204
- else {
205
- log("Token Check - No refresh logic available or token missing", { refreshToken: !!refreshToken, token: !!user.token });
206
- }
207
- if (!refreshed) {
208
- // Token expirado y no se pudo renovar, cerrar sesión
209
- log("Token Check - Session expired, logging out");
210
- removeStoredAuth();
211
- setUser(null);
212
- setIsAuthenticated(false);
213
- }
214
- }
215
- };
216
- // Verificar inmediatamente
217
- checkTokenExpiration();
218
- // Verificar cada minuto para detectar expiraciones
219
- const interval = setInterval(checkTokenExpiration, 60000);
220
- return () => clearInterval(interval);
221
- }
222
- }, [user, refreshToken]);
223
- return (_jsx(AuthContext.Provider, { value: { user, isAuthenticated, isLoading, login, logout }, children: children }));
224
- };