flysoft-react-ui 0.5.2 → 0.5.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.
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +5 -6
- package/dist/components/form-controls/AutocompleteInput.d.ts.map +1 -1
- package/dist/components/form-controls/AutocompleteInput.js +2 -1
- package/dist/components/form-controls/Button.d.ts +3 -0
- package/dist/components/form-controls/Button.d.ts.map +1 -1
- package/dist/components/form-controls/Button.js +160 -19
- package/dist/components/form-controls/Checkbox.d.ts.map +1 -1
- package/dist/components/form-controls/Checkbox.js +3 -1
- package/dist/components/form-controls/DateInput.d.ts +5 -1
- package/dist/components/form-controls/DateInput.d.ts.map +1 -1
- package/dist/components/form-controls/DateInput.js +94 -27
- package/dist/components/form-controls/Input.d.ts.map +1 -1
- package/dist/components/form-controls/Input.js +2 -1
- package/dist/components/form-controls/LinkButton.d.ts +15 -0
- package/dist/components/form-controls/LinkButton.d.ts.map +1 -0
- package/dist/components/form-controls/LinkButton.js +248 -0
- package/dist/components/form-controls/SearchSelectInput-OLD.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput-OLD.js +3 -2
- package/dist/components/form-controls/SearchSelectInput.d.ts.map +1 -1
- package/dist/components/form-controls/SearchSelectInput.js +2 -1
- package/dist/components/form-controls/index.d.ts +2 -0
- package/dist/components/form-controls/index.d.ts.map +1 -1
- package/dist/components/form-controls/index.js +1 -0
- package/dist/components/layout/Accordion.d.ts +13 -0
- package/dist/components/layout/Accordion.d.ts.map +1 -0
- package/dist/components/layout/Accordion.js +67 -0
- package/dist/components/layout/AppLayout.js +1 -1
- package/dist/components/layout/Card.d.ts +8 -3
- package/dist/components/layout/Card.d.ts.map +1 -1
- package/dist/components/layout/Card.js +18 -19
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/components/layout/index.js +1 -0
- package/dist/components/utils/Badge.d.ts.map +1 -1
- package/dist/components/utils/Badge.js +3 -2
- package/dist/components/utils/Dialog.d.ts.map +1 -1
- package/dist/components/utils/Dialog.js +2 -1
- package/dist/components/utils/Filter.d.ts.map +1 -1
- package/dist/components/utils/Filter.js +2 -1
- package/dist/components/utils/Loader.js +1 -1
- package/dist/components/utils/RoadMap.d.ts.map +1 -1
- package/dist/components/utils/RoadMap.js +2 -1
- package/dist/components/utils/Snackbar.d.ts.map +1 -1
- package/dist/components/utils/Snackbar.js +2 -1
- package/dist/components/utils/iconUtils.d.ts +16 -0
- package/dist/components/utils/iconUtils.d.ts.map +1 -0
- package/dist/components/utils/iconUtils.js +40 -0
- package/dist/contexts/ListCrudContext.d.ts +28 -7
- package/dist/contexts/ListCrudContext.d.ts.map +1 -1
- package/dist/contexts/ListCrudContext.js +100 -56
- package/dist/docs/AccordionDocs.d.ts +4 -0
- package/dist/docs/AccordionDocs.d.ts.map +1 -0
- package/dist/docs/AccordionDocs.js +21 -0
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +3 -5
- package/dist/docs/AutocompleteInputDocs.js +1 -1
- package/dist/docs/ButtonDocs.d.ts.map +1 -1
- package/dist/docs/ButtonDocs.js +1 -1
- package/dist/docs/CardDocs.d.ts.map +1 -1
- package/dist/docs/CardDocs.js +17 -8
- package/dist/docs/DataTableDocs.js +3 -3
- package/dist/docs/DialogDocs.js +1 -1
- package/dist/docs/DocAdmin.js +1 -1
- package/dist/docs/DocsMenu.d.ts.map +1 -1
- package/dist/docs/DocsMenu.js +3 -3
- package/dist/docs/DocsRouter.d.ts.map +1 -1
- package/dist/docs/DocsRouter.js +3 -1
- package/dist/docs/DropdownMenuDocs.js +1 -1
- package/dist/docs/LinkButtonDocs.d.ts +4 -0
- package/dist/docs/LinkButtonDocs.d.ts.map +1 -0
- package/dist/docs/LinkButtonDocs.js +7 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +0 -9
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +16 -12
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +2 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +7 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +1 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +32 -26
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +9 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +1 -0
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +30 -0
- package/dist/docs/SearchSelectInputDocs.js +1 -1
- package/dist/docs/docMockServices/empresaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/empresaService.js +2 -1
- package/dist/docs/docMockServices/personaService.d.ts +1 -1
- package/dist/docs/docMockServices/personaService.d.ts.map +1 -1
- package/dist/docs/docMockServices/personaService.js +3 -2
- package/dist/index.css +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/templates/forms/ContactForm.js +2 -2
- package/dist/templates/forms/LoginForm.js +1 -1
- package/dist/templates/forms/RegistrationForm.js +1 -1
- package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
- package/dist/templates/layouts/SidebarLayout.js +3 -2
- package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
- package/dist/templates/patterns/FormPattern.js +4 -3
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useEffect } from "react";
|
|
3
|
+
import { normalizeIconClass } from "./iconUtils";
|
|
3
4
|
export const Dialog = ({ isOpen, title, dialogBody, dialogActions, onClose, closeOnOverlayClick = false, }) => {
|
|
4
5
|
// Prevenir scroll del body cuando el dialog está abierto
|
|
5
6
|
useEffect(() => {
|
|
@@ -35,7 +36,7 @@ export const Dialog = ({ isOpen, title, dialogBody, dialogActions, onClose, clos
|
|
|
35
36
|
onClose();
|
|
36
37
|
}
|
|
37
38
|
};
|
|
38
|
-
return (_jsxs("div", { className: "fixed inset-0 z-[2000] flex items-center justify-center p-4", role: "dialog", "aria-modal": "true", "aria-labelledby": "dialog-title", children: [_jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: handleOverlayClick }), _jsxs("div", { className: "relative w-auto max-w-lg min-w-[400px] bg-[var(--color-bg-default)] rounded-lg shadow-[var(--shadow-xl)] border border-[var(--color-border-default)] font-[var(--font-default)] max-h-[90vh] flex flex-col", onClick: (e) => e.stopPropagation(), style: { overflow: "visible" }, children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-[var(--color-border-default)] flex-shrink-0", children: [_jsx("h2", { id: "dialog-title", className: "text-lg font-semibold text-[var(--color-text-primary)]", children: title }), onClose && (_jsx("button", { onClick: onClose, className: "ml-4 p-1 rounded-md text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-bg-hover)] transition-colors cursor-pointer", "aria-label": "Cerrar dialog", children: _jsx("i", { className: "fa
|
|
39
|
+
return (_jsxs("div", { className: "fixed inset-0 z-[2000] flex items-center justify-center p-4", role: "dialog", "aria-modal": "true", "aria-labelledby": "dialog-title", children: [_jsx("div", { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", onClick: handleOverlayClick }), _jsxs("div", { className: "relative w-auto max-w-lg min-w-[400px] bg-[var(--color-bg-default)] rounded-lg shadow-[var(--shadow-xl)] border border-[var(--color-border-default)] font-[var(--font-default)] max-h-[90vh] flex flex-col", onClick: (e) => e.stopPropagation(), style: { overflow: "visible" }, children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-[var(--color-border-default)] flex-shrink-0", children: [_jsx("h2", { id: "dialog-title", className: "text-lg font-semibold text-[var(--color-text-primary)]", children: title }), onClose && (_jsx("button", { onClick: onClose, className: "ml-4 p-1 rounded-md text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] hover:bg-[var(--color-bg-hover)] transition-colors cursor-pointer", "aria-label": "Cerrar dialog", children: _jsx("i", { className: normalizeIconClass("fa-times") }) }))] }), _jsx("div", { className: "px-6 py-4 flex-1 text-[var(--color-text-primary)] min-w-0", style: {
|
|
39
40
|
overflowY: "auto",
|
|
40
41
|
overflowX: "visible",
|
|
41
42
|
maxHeight: "calc(90vh - 200px)"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Filter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Filter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAIvE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAGD,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,UAAU,EAAE,QAAQ,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACzE,SAAQ,eAAe;IACvB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,UAAU,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,MAAM,CACzE,SAAQ,eAAe;IACvB,UAAU,EAAE,cAAc,CAAC;IAC3B,iBAAiB,EAAE,CACjB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,uBAAuB,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC9D,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,uBAAuB,GACvB,iBAAiB,GACjB,uBAAuB,CAAC;AAE5B,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA68BxC,CAAC"}
|
|
@@ -9,6 +9,7 @@ import { DateInput } from "../form-controls/DateInput";
|
|
|
9
9
|
import { AutocompleteInput } from "../form-controls/AutocompleteInput";
|
|
10
10
|
import { SearchSelectInput } from "../form-controls/SearchSelectInput";
|
|
11
11
|
import { DataField } from "../layout/DataField";
|
|
12
|
+
import { normalizeIconClass } from "./iconUtils";
|
|
12
13
|
export const Filter = (props) => {
|
|
13
14
|
const { paramName, label, staticOptions, inputWidth, value: propValue, onChange, hideEmpty = false, } = props;
|
|
14
15
|
const filterType = props.filterType || "text";
|
|
@@ -499,7 +500,7 @@ export const Filter = (props) => {
|
|
|
499
500
|
}
|
|
500
501
|
// Contenedor tipo badge con diseño similar al Input
|
|
501
502
|
// Altura ajustada para coincidir con input sm: py-1.5 (6px arriba y abajo) + text-sm (14px línea) = ~26px total
|
|
502
|
-
const badgeContainer = (_jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1.5 h-[2.1rem] rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-default)] text-[var(--color-text-primary)] font-[var(--font-default)] cursor-pointer text-sm transition-colors", onClick: handleTogglePanel, children: [_jsx("span", { className: "text-sm min-w-[1rem]", children: getDisplayValue() || "\u00A0" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "p-0.5 hover:bg-[var(--color-bg-secondary)] rounded transition-colors flex items-center justify-center", children: _jsx("i", { className:
|
|
503
|
+
const badgeContainer = (_jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1.5 h-[2.1rem] rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-default)] text-[var(--color-text-primary)] font-[var(--font-default)] cursor-pointer text-sm transition-colors", onClick: handleTogglePanel, children: [_jsx("span", { className: "text-sm min-w-[1rem]", children: getDisplayValue() || "\u00A0" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "p-0.5 hover:bg-[var(--color-bg-secondary)] rounded transition-colors flex items-center justify-center", children: _jsx("i", { className: `${normalizeIconClass("fa-chevron-down")} text-xs text-[var(--color-text-muted)] hover:text-[var(--color-primary)] transition-all ${isOpen ? "rotate-180" : ""}` }) }), currentValue && (_jsx("button", { onClick: handleClearFilter, className: "p-0.5 hover:bg-[var(--color-bg-secondary)] rounded transition-colors flex items-center justify-center", "aria-label": "Borrar filtro", type: "button", children: _jsx("i", { className: `${normalizeIconClass("fa-times")} text-xs text-[var(--color-text-muted)] hover:text-[var(--color-primary)] transition-colors` }) }))] })] }));
|
|
503
504
|
// Renderizar según el tipo de filtro
|
|
504
505
|
if (filterType === "autocomplete") {
|
|
505
506
|
return (_jsxs("div", { ref: containerRef, className: "relative inline-block", children: [_jsx(DataField, { label: label, value: badgeContainer, className: "inline-block" }), isOpen &&
|
|
@@ -3,7 +3,7 @@ import React from "react";
|
|
|
3
3
|
import { useTheme } from "../../contexts/ThemeContext";
|
|
4
4
|
export const Loader = ({ isLoading = false, text, children, keepContentWhileLoading, contentLoadingNode, overlayClassName, }) => {
|
|
5
5
|
const { theme } = useTheme();
|
|
6
|
-
const displayText = text
|
|
6
|
+
const displayText = text;
|
|
7
7
|
// Clases por defecto del overlay (negro semitransparente con blur)
|
|
8
8
|
const defaultOverlayClasses = "bg-black/50 backdrop-blur-sm";
|
|
9
9
|
// Combinar clases por defecto con las personalizadas
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoadMap.d.ts","sourceRoot":"","sources":["../../../src/components/utils/RoadMap.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"RoadMap.d.ts","sourceRoot":"","sources":["../../../src/components/utils/RoadMap.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA6E1B,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC9E;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAgH1C,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { normalizeIconClass } from "./iconUtils";
|
|
3
4
|
/**
|
|
4
5
|
* Helper function to convert color names to CSS values
|
|
5
6
|
*/
|
|
@@ -127,7 +128,7 @@ export const RoadMap = ({ stages, className = "", }) => {
|
|
|
127
128
|
`, style: {
|
|
128
129
|
backgroundColor: bgColor,
|
|
129
130
|
color: "#ffffff",
|
|
130
|
-
}, children: stage.icon ? (_jsx("i", { className:
|
|
131
|
+
}, children: stage.icon ? (_jsx("i", { className: `${normalizeIconClass(stage.icon)} text-xs` })) : null }), !isLast && (_jsx("div", { className: "w-0.5 h-4 flex-shrink-0", style: {
|
|
131
132
|
background: connectorGradient || undefined,
|
|
132
133
|
} }))] }), _jsxs("div", { className: `
|
|
133
134
|
flex-1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/utils/Snackbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAqM5C,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useEffect, useState, useRef, useCallback } from "react";
|
|
3
|
+
import { normalizeIconClass } from "./iconUtils";
|
|
3
4
|
export const Snackbar = ({ id, message, variant, duration = 3000, icon, iconLabel, onClose, }) => {
|
|
4
5
|
const [progress, setProgress] = useState(100);
|
|
5
6
|
const [isClosing, setIsClosing] = useState(false);
|
|
@@ -117,5 +118,5 @@ export const Snackbar = ({ id, message, variant, duration = 3000, icon, iconLabe
|
|
|
117
118
|
`, 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: {
|
|
118
119
|
width: `${progress}%`,
|
|
119
120
|
backgroundColor: "#00000050",
|
|
120
|
-
} }) })), displayIcon && (_jsx("div", { className: "flex-shrink-0 -mt-0.5", children: _jsx("i", { className:
|
|
121
|
+
} }) })), 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` }) })] }) }));
|
|
121
122
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
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 declare function normalizeIconClass(iconClass: string | undefined): string;
|
|
16
|
+
//# sourceMappingURL=iconUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iconUtils.d.ts","sourceRoot":"","sources":["../../../src/components/utils/iconUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CA6BxE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
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
|
+
}
|
|
@@ -9,21 +9,42 @@ export interface ListCrudContextType<T> {
|
|
|
9
9
|
isLoading: boolean;
|
|
10
10
|
pagination: ReactNode;
|
|
11
11
|
params: Record<string, any>;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
fetchItems: {
|
|
13
|
+
execute: (params?: Record<string, any>) => Promise<void>;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
};
|
|
16
|
+
createItem: {
|
|
17
|
+
execute: (item: T) => Promise<T | undefined | null>;
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
};
|
|
20
|
+
updateItem: {
|
|
21
|
+
execute: (item: T) => Promise<T | undefined | null>;
|
|
22
|
+
isLoading: boolean;
|
|
23
|
+
};
|
|
24
|
+
deleteItem: {
|
|
25
|
+
execute: (item: T) => Promise<void>;
|
|
26
|
+
isLoading: boolean;
|
|
27
|
+
};
|
|
15
28
|
}
|
|
16
29
|
export declare const ListCrudContext: import("react").Context<ListCrudContextType<any> | undefined>;
|
|
30
|
+
export interface PromiseWithOptions<TResult, TParams extends any[] = []> {
|
|
31
|
+
execute: (...params: TParams) => Promise<TResult>;
|
|
32
|
+
successMessage?: string;
|
|
33
|
+
errorMessage?: string;
|
|
34
|
+
}
|
|
17
35
|
interface ListCrudProviderProps<T> {
|
|
18
36
|
children: ReactNode;
|
|
19
|
-
getPromise: (params?: Record<string, any>) => Promise<Array<T> | PaginationInterface<T> | undefined
|
|
20
|
-
|
|
21
|
-
|
|
37
|
+
getPromise: ((params?: Record<string, any>) => Promise<Array<T> | PaginationInterface<T> | undefined>) | PromiseWithOptions<Array<T> | PaginationInterface<T> | undefined, [
|
|
38
|
+
params?: Record<string, any>
|
|
39
|
+
]>;
|
|
40
|
+
postPromise?: ((item: T) => Promise<T | undefined | null>) | PromiseWithOptions<T | undefined | null, [item: T]>;
|
|
41
|
+
putPromise?: ((item: T) => Promise<T | undefined | null>) | PromiseWithOptions<T | undefined | null, [item: T]>;
|
|
42
|
+
deletePromise?: ((item: T) => Promise<void>) | PromiseWithOptions<void, [item: T]>;
|
|
22
43
|
urlParams?: Array<string>;
|
|
23
44
|
limit?: number;
|
|
24
45
|
pageParam?: string;
|
|
25
46
|
}
|
|
26
|
-
export declare function ListCrudProvider<T>({ children, getPromise, postPromise, deletePromise, limit, pageParam, urlParams, }: ListCrudProviderProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
export declare function ListCrudProvider<T>({ children, getPromise, postPromise, putPromise, deletePromise, limit, pageParam, urlParams, }: ListCrudProviderProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
27
48
|
export declare function useListCrud<T>(): ListCrudContextType<T>;
|
|
28
49
|
export {};
|
|
29
50
|
//# sourceMappingURL=ListCrudContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListCrudContext.d.ts","sourceRoot":"","sources":["../../src/contexts/ListCrudContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,wCAAwC,CAAC;AAGhD,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ListCrudContext.d.ts","sourceRoot":"","sources":["../../src/contexts/ListCrudContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,wCAAwC,CAAC;AAGhD,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,UAAU,EAAE;QACV,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACzD,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;QACpD,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;QACpD,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAQD,eAAO,MAAM,eAAe,+DAA+B,CAAC;AAE5D,MAAM,WAAW,kBAAkB,CAAC,OAAO,EAAE,OAAO,SAAS,GAAG,EAAE,GAAG,EAAE;IACrE,OAAO,EAAE,CAAC,GAAG,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,qBAAqB,CAAC,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,EACN,CAAC,CACC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KACzB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAC5D,kBAAkB,CAChB,KAAK,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,SAAS,EAC7C;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;KAAC,CAC/B,CAAC;IACN,WAAW,CAAC,EACR,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,GAC5C,kBAAkB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,UAAU,CAAC,EACP,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,GAC5C,kBAAkB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,aAAa,CAAC,EACV,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAC5B,kBAAkB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,EAClC,QAAQ,EACR,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,KAAU,EACV,SAAoB,EACpB,SAAc,GACf,EAAE,qBAAqB,CAAC,CAAC,CAAC,2CAqT1B;AAID,wBAAgB,WAAW,CAAC,CAAC,KAAK,mBAAmB,CAAC,CAAC,CAAC,CAMvD"}
|
|
@@ -9,29 +9,74 @@ const createListCrudContext = () => {
|
|
|
9
9
|
// Crear el contexto con un tipo genérico por defecto
|
|
10
10
|
// Los usuarios pueden crear su propio contexto con su tipo específico
|
|
11
11
|
export const ListCrudContext = createListCrudContext();
|
|
12
|
-
export function ListCrudProvider({ children, getPromise, postPromise, deletePromise, limit = 15, pageParam = "pagina", urlParams = [], }) {
|
|
12
|
+
export function ListCrudProvider({ children, getPromise, postPromise, putPromise, deletePromise, limit = 15, pageParam = "pagina", urlParams = [], }) {
|
|
13
13
|
const [list, setList] = useState(undefined);
|
|
14
14
|
const [page, setPage] = useState(1);
|
|
15
15
|
const [pages, setPages] = useState(1);
|
|
16
16
|
const [total, setTotal] = useState(0);
|
|
17
|
-
const getPromiseRef = useRef(getPromise);
|
|
18
17
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
19
18
|
const lastFetchParamsRef = useRef("");
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
19
|
+
// Extraer funciones execute y opciones de las promises
|
|
20
|
+
const getPromiseExecute = typeof getPromise === "function" ? getPromise : getPromise.execute;
|
|
21
|
+
const getPromiseSuccessMessage = typeof getPromise === "function" ? undefined : getPromise.successMessage;
|
|
22
|
+
const getPromiseErrorMessage = typeof getPromise === "function" ? undefined : getPromise.errorMessage;
|
|
23
|
+
const postPromiseExecute = postPromise
|
|
24
|
+
? typeof postPromise === "function"
|
|
25
|
+
? postPromise
|
|
26
|
+
: postPromise.execute
|
|
27
|
+
: undefined;
|
|
28
|
+
const postPromiseSuccessMessage = postPromise && typeof postPromise === "object"
|
|
29
|
+
? postPromise.successMessage
|
|
30
|
+
: undefined;
|
|
31
|
+
const postPromiseErrorMessage = postPromise && typeof postPromise === "object"
|
|
32
|
+
? postPromise.errorMessage
|
|
33
|
+
: undefined;
|
|
34
|
+
const putPromiseExecute = putPromise
|
|
35
|
+
? typeof putPromise === "function"
|
|
36
|
+
? putPromise
|
|
37
|
+
: putPromise.execute
|
|
38
|
+
: undefined;
|
|
39
|
+
const putPromiseSuccessMessage = putPromise && typeof putPromise === "object"
|
|
40
|
+
? putPromise.successMessage
|
|
41
|
+
: undefined;
|
|
42
|
+
const putPromiseErrorMessage = putPromise && typeof putPromise === "object"
|
|
43
|
+
? putPromise.errorMessage
|
|
44
|
+
: undefined;
|
|
45
|
+
const deletePromiseExecute = deletePromise
|
|
46
|
+
? typeof deletePromise === "function"
|
|
47
|
+
? deletePromise
|
|
48
|
+
: deletePromise.execute
|
|
49
|
+
: undefined;
|
|
50
|
+
const deletePromiseSuccessMessage = deletePromise && typeof deletePromise === "object"
|
|
51
|
+
? deletePromise.successMessage
|
|
52
|
+
: undefined;
|
|
53
|
+
const deletePromiseErrorMessage = deletePromise && typeof deletePromise === "object"
|
|
54
|
+
? deletePromise.errorMessage
|
|
55
|
+
: undefined;
|
|
56
|
+
const getPromiseRef = useRef(getPromiseExecute);
|
|
57
|
+
// Hooks para manejar las peticiones asíncronas con mensajes opcionales
|
|
58
|
+
const fetchDataAsync = useAsyncRequest({
|
|
59
|
+
successMessage: getPromiseSuccessMessage,
|
|
60
|
+
errorMessage: getPromiseErrorMessage,
|
|
26
61
|
});
|
|
27
|
-
const createItemAsync = useAsyncRequest(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
62
|
+
const createItemAsync = useAsyncRequest({
|
|
63
|
+
successMessage: postPromiseSuccessMessage,
|
|
64
|
+
errorMessage: postPromiseErrorMessage,
|
|
65
|
+
});
|
|
66
|
+
const updateItemAsync = useAsyncRequest({
|
|
67
|
+
successMessage: putPromiseSuccessMessage,
|
|
68
|
+
errorMessage: putPromiseErrorMessage,
|
|
69
|
+
});
|
|
70
|
+
const deleteItemAsync = useAsyncRequest({
|
|
71
|
+
successMessage: deletePromiseSuccessMessage,
|
|
72
|
+
errorMessage: deletePromiseErrorMessage,
|
|
73
|
+
});
|
|
74
|
+
// El isLoading del contexto usa el hook de fetchData
|
|
75
|
+
const isLoading = fetchDataAsync.isLoading;
|
|
31
76
|
// Actualizar la referencia cuando cambie getPromise
|
|
32
77
|
useEffect(() => {
|
|
33
|
-
getPromiseRef.current =
|
|
34
|
-
}, [
|
|
78
|
+
getPromiseRef.current = getPromiseExecute;
|
|
79
|
+
}, [getPromiseExecute]);
|
|
35
80
|
// Función para obtener los parámetros de la URL
|
|
36
81
|
const getUrlParams = useCallback(() => {
|
|
37
82
|
const params = { limit };
|
|
@@ -53,35 +98,15 @@ export function ListCrudProvider({ children, getPromise, postPromise, deleteProm
|
|
|
53
98
|
return params;
|
|
54
99
|
}, [searchParams, pageParam, urlParams, limit]);
|
|
55
100
|
// Función para obtener los datos
|
|
56
|
-
const fetchData = useCallback(async (params
|
|
57
|
-
const asyncRequest = showSuccessMessage
|
|
58
|
-
? fetchDataAsyncManual
|
|
59
|
-
: fetchDataAsync;
|
|
101
|
+
const fetchData = useCallback(async (params) => {
|
|
60
102
|
// Obtener los parámetros que se van a usar
|
|
61
103
|
const requestParams = params || getUrlParams();
|
|
62
104
|
// Crear una clave única para estos parámetros
|
|
63
|
-
const paramsKey = JSON.stringify(
|
|
64
|
-
...requestParams,
|
|
65
|
-
showSuccessMessage,
|
|
66
|
-
});
|
|
67
|
-
// Evitar ejecuciones duplicadas con los mismos parámetros
|
|
68
|
-
if (!showSuccessMessage && lastFetchParamsRef.current === paramsKey) {
|
|
69
|
-
console.log("Skipping duplicate fetchData call");
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
105
|
+
const paramsKey = JSON.stringify(requestParams);
|
|
72
106
|
lastFetchParamsRef.current = paramsKey;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
isLoading: asyncRequest.isLoading,
|
|
76
|
-
params: requestParams,
|
|
77
|
-
});
|
|
78
|
-
const result = await asyncRequest.execute(async () => {
|
|
79
|
-
console.log("Executing promise with params:", requestParams);
|
|
80
|
-
const promiseResult = await getPromiseRef.current(requestParams);
|
|
81
|
-
console.log("Promise result:", promiseResult);
|
|
82
|
-
return promiseResult;
|
|
107
|
+
const result = await fetchDataAsync.execute(async () => {
|
|
108
|
+
return await getPromiseRef.current(requestParams);
|
|
83
109
|
});
|
|
84
|
-
console.log("fetchData result:", result);
|
|
85
110
|
// Solo procesar el resultado si no es undefined (undefined significa error)
|
|
86
111
|
if (result !== undefined) {
|
|
87
112
|
if (result && typeof result === "object" && "list" in result) {
|
|
@@ -107,10 +132,7 @@ export function ListCrudProvider({ children, getPromise, postPromise, deleteProm
|
|
|
107
132
|
setTotal(0);
|
|
108
133
|
}
|
|
109
134
|
}
|
|
110
|
-
|
|
111
|
-
console.log("Result is undefined, not processing");
|
|
112
|
-
}
|
|
113
|
-
}, [getUrlParams, limit, fetchDataAsync, fetchDataAsyncManual]);
|
|
135
|
+
}, [getUrlParams, limit, fetchDataAsync]);
|
|
114
136
|
// Ref para almacenar los valores anteriores de urlParams
|
|
115
137
|
const prevUrlParamsValuesRef = useRef({});
|
|
116
138
|
// Memoizar los valores actuales de los urlParams
|
|
@@ -128,27 +150,36 @@ export function ListCrudProvider({ children, getPromise, postPromise, deleteProm
|
|
|
128
150
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
129
151
|
[searchParams, pageParam, urlParamsKey, limit, urlParams]);
|
|
130
152
|
// Función para recargar los datos
|
|
131
|
-
const
|
|
132
|
-
await fetchData(params
|
|
153
|
+
const fetchItemsExecute = useCallback(async (params) => {
|
|
154
|
+
await fetchData(params);
|
|
133
155
|
}, [fetchData]);
|
|
134
156
|
// Función para crear un item
|
|
135
|
-
const
|
|
136
|
-
if (!
|
|
157
|
+
const createItemExecute = useCallback(async (item) => {
|
|
158
|
+
if (!postPromiseExecute) {
|
|
137
159
|
throw new Error("postPromise is not defined. Please provide postPromise to ListCrudProvider.");
|
|
138
160
|
}
|
|
139
161
|
return await createItemAsync.execute(async () => {
|
|
140
|
-
return await
|
|
162
|
+
return await postPromiseExecute(item);
|
|
163
|
+
});
|
|
164
|
+
}, [postPromiseExecute, createItemAsync]);
|
|
165
|
+
// Función para actualizar un item
|
|
166
|
+
const updateItemExecute = useCallback(async (item) => {
|
|
167
|
+
if (!putPromiseExecute) {
|
|
168
|
+
throw new Error("putPromise is not defined. Please provide putPromise to ListCrudProvider.");
|
|
169
|
+
}
|
|
170
|
+
return await updateItemAsync.execute(async () => {
|
|
171
|
+
return await putPromiseExecute(item);
|
|
141
172
|
});
|
|
142
|
-
}, [
|
|
173
|
+
}, [putPromiseExecute, updateItemAsync]);
|
|
143
174
|
// Función para eliminar un item
|
|
144
|
-
const
|
|
145
|
-
if (!
|
|
175
|
+
const deleteItemExecute = useCallback(async (item) => {
|
|
176
|
+
if (!deletePromiseExecute) {
|
|
146
177
|
throw new Error("deletePromise is not defined. Please provide deletePromise to ListCrudProvider.");
|
|
147
178
|
}
|
|
148
179
|
await deleteItemAsync.execute(async () => {
|
|
149
|
-
await
|
|
180
|
+
await deletePromiseExecute(item);
|
|
150
181
|
});
|
|
151
|
-
}, [
|
|
182
|
+
}, [deletePromiseExecute, deleteItemAsync]);
|
|
152
183
|
// useEffect para resetear pageParam a 1 cuando cambien los urlParams
|
|
153
184
|
useEffect(() => {
|
|
154
185
|
// Verificar si hay algún urlParam definido
|
|
@@ -182,7 +213,7 @@ export function ListCrudProvider({ children, getPromise, postPromise, deleteProm
|
|
|
182
213
|
}, 0);
|
|
183
214
|
return () => clearTimeout(timeoutId);
|
|
184
215
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
185
|
-
}, [
|
|
216
|
+
}, [getPromiseExecute, searchParams, pageParam, urlParamsKey]);
|
|
186
217
|
const value = {
|
|
187
218
|
list,
|
|
188
219
|
page,
|
|
@@ -191,9 +222,22 @@ export function ListCrudProvider({ children, getPromise, postPromise, deleteProm
|
|
|
191
222
|
limit,
|
|
192
223
|
isLoading,
|
|
193
224
|
params: currentParams,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
225
|
+
fetchItems: {
|
|
226
|
+
execute: fetchItemsExecute,
|
|
227
|
+
isLoading: fetchDataAsync.isLoading,
|
|
228
|
+
},
|
|
229
|
+
createItem: {
|
|
230
|
+
execute: createItemExecute,
|
|
231
|
+
isLoading: createItemAsync.isLoading,
|
|
232
|
+
},
|
|
233
|
+
updateItem: {
|
|
234
|
+
execute: updateItemExecute,
|
|
235
|
+
isLoading: updateItemAsync.isLoading,
|
|
236
|
+
},
|
|
237
|
+
deleteItem: {
|
|
238
|
+
execute: deleteItemExecute,
|
|
239
|
+
isLoading: deleteItemAsync.isLoading,
|
|
240
|
+
},
|
|
197
241
|
pagination: (_jsx(Pagination, { page: page, pages: pages, total: total, fieldName: pageParam, isLoading: isLoading })),
|
|
198
242
|
};
|
|
199
243
|
return (_jsx(ListCrudContext.Provider, { value: value, children: children }));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccordionDocs.d.ts","sourceRoot":"","sources":["../../src/docs/AccordionDocs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAwuB1B,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { Accordion, Card, Badge, Input } from "../index";
|
|
4
|
+
const AccordionDocs = () => {
|
|
5
|
+
const [openAccordions, setOpenAccordions] = useState(new Set());
|
|
6
|
+
const handleToggle = (id, isOpen) => {
|
|
7
|
+
const newSet = new Set(openAccordions);
|
|
8
|
+
if (isOpen) {
|
|
9
|
+
newSet.add(id);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
newSet.delete(id);
|
|
13
|
+
}
|
|
14
|
+
setOpenAccordions(newSet);
|
|
15
|
+
};
|
|
16
|
+
return (_jsx("div", { className: "max-w-5xl mx-auto space-y-8", children: _jsx(Card, { title: "Accordion - Variantes y Ejemplos", children: _jsxs("div", { className: "space-y-10", children: [_jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Variantes" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "El componente Accordion soporta tres variantes visuales: default, elevated (con sombra) y outlined (con borde destacado)." }), _jsxs("div", { className: "space-y-3", children: [_jsx(Accordion, { variant: "default", title: "Default", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con variante por defecto." }) }), _jsx(Accordion, { variant: "elevated", title: "Elevated", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con sombra elevada." }) }), _jsx(Accordion, { variant: "outlined", title: "Outlined", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con borde destacado." }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Uso b\u00E1sico" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "El componente Accordion permite mostrar contenido colapsable con una animaci\u00F3n suave de expandir/contraer. Haz clic en el header para abrir o cerrar el contenido." }), _jsxs("div", { className: "space-y-3", children: [_jsx(Accordion, { title: "Informaci\u00F3n General", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Este es un accordion b\u00E1sico sin icono ni elementos adicionales. El contenido se muestra cuando el accordion est\u00E1 abierto y se oculta con una animaci\u00F3n suave cuando est\u00E1 cerrado." }) }), _jsx(Accordion, { title: "Detalles del Producto", defaultOpen: true, children: _jsxs("div", { className: "space-y-2", children: [_jsxs("p", { style: { color: "var(--flysoft-text-secondary)" }, children: ["Este accordion est\u00E1 abierto por defecto usando la propiedad", " ", _jsx("code", { className: "px-1 py-0.5 bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded text-xs", children: "defaultOpen" }), "."] }), _jsxs("ul", { className: "list-disc list-inside space-y-1 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsx("li", { children: "Caracter\u00EDstica 1: Descripci\u00F3n detallada" }), _jsx("li", { children: "Caracter\u00EDstica 2: M\u00E1s informaci\u00F3n" }), _jsx("li", { children: "Caracter\u00EDstica 3: Detalles adicionales" })] })] }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Con icono" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["Puedes agregar un icono FontAwesome 5 del lado izquierdo del t\u00EDtulo usando la propiedad ", _jsx("code", { children: "icon" }), "."] }), _jsxs("div", { className: "space-y-3", children: [_jsx(Accordion, { title: "Configuraci\u00F3n", icon: "fa-cog", children: _jsxs("div", { className: "space-y-2", children: [_jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Este accordion tiene un icono de configuraci\u00F3n en el lado izquierdo." }), _jsx(Input, { label: "Nombre", placeholder: "Ingresa un nombre" }), _jsx(Input, { label: "Email", type: "email", placeholder: "correo@ejemplo.com" })] }) }), _jsx(Accordion, { title: "Informaci\u00F3n de Usuario", icon: "fa-user", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con icono de usuario. Los iconos ayudan a identificar visualmente el tipo de contenido." }) }), _jsx(Accordion, { title: "Notificaciones", icon: "fa-bell", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con icono de notificaciones. Puedes usar cualquier icono de FontAwesome 5." }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Con rightNode" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["La propiedad ", _jsx("code", { children: "rightNode" }), " permite agregar contenido personalizado del lado derecho, antes del chevron. \u00DAtil para badges, botones peque\u00F1os, contadores, etc."] }), _jsxs("div", { className: "space-y-3", children: [_jsx(Accordion, { title: "Mensajes", icon: "fa-envelope", rightNode: _jsx(Badge, { variant: "info", children: "3" }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Este accordion muestra un badge con el n\u00FAmero de mensajes no le\u00EDdos en el lado derecho." }) }), _jsx(Accordion, { title: "Tareas Pendientes", icon: "fa-tasks", rightNode: _jsx(Badge, { variant: "warning", children: "5" }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con badge de tareas pendientes. El rightNode puede contener cualquier ReactNode." }) }), _jsx(Accordion, { title: "Configuraci\u00F3n Avanzada", icon: "fa-sliders-h", rightNode: _jsxs("div", { className: "flex items-center gap-2 px-2 py-1 text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)] cursor-pointer rounded transition-colors", onClick: (e) => {
|
|
17
|
+
e.stopPropagation();
|
|
18
|
+
console.log("Editar configuración");
|
|
19
|
+
}, children: [_jsx("i", { className: "fal fa-edit" }), _jsx("span", { children: "Editar" })] }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Este accordion incluye un elemento de acci\u00F3n en el rightNode, permitiendo acciones r\u00E1pidas sin abrir el accordion. Nota: No uses componentes Button dentro de rightNode ya que causar\u00EDa un error de anidaci\u00F3n de botones." }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Con callback onToggle" }), _jsxs("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: ["La propiedad ", _jsx("code", { children: "onToggle" }), " permite ejecutar una funci\u00F3n cuando el accordion se abre o cierra. \u00DAtil para sincronizar estado externo o realizar acciones al cambiar el estado."] }), _jsxs("div", { className: "space-y-3", children: [openAccordions.size > 0 && (_jsx("div", { className: "p-3 bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded", children: _jsxs("p", { className: "text-sm", children: [_jsx("span", { className: "font-semibold", children: "Accordions abiertos:" }), " ", _jsx("span", { style: { color: "var(--flysoft-text-secondary)" }, children: Array.from(openAccordions).join(", ") || "Ninguno" })] }) })), _jsx(Accordion, { title: "Secci\u00F3n 1", icon: "fa-folder", onToggle: (isOpen) => handleToggle("seccion1", isOpen), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Este accordion notifica cuando se abre o cierra mediante el callback onToggle." }) }), _jsx(Accordion, { title: "Secci\u00F3n 2", icon: "fa-folder", onToggle: (isOpen) => handleToggle("seccion2", isOpen), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Otro accordion que tambi\u00E9n notifica su estado mediante onToggle." }) }), _jsx(Accordion, { title: "Secci\u00F3n 3", icon: "fa-folder", onToggle: (isOpen) => handleToggle("seccion3", isOpen), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Un tercer accordion para demostrar el seguimiento de m\u00FAltiples accordions." }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Ejemplo completo con m\u00FAltiples accordions" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Ejemplo pr\u00E1ctico usando m\u00FAltiples accordions para organizar informaci\u00F3n en secciones colapsables." }), _jsxs("div", { className: "space-y-3", children: [_jsx(Accordion, { title: "Informaci\u00F3n Personal", icon: "fa-user-circle", rightNode: _jsx(Badge, { variant: "success", children: "Completo" }), children: _jsxs("div", { className: "space-y-3", children: [_jsx(Input, { label: "Nombre", placeholder: "Juan", icon: "fa-user" }), _jsx(Input, { label: "Apellido", placeholder: "P\u00E9rez", icon: "fa-user" }), _jsx(Input, { label: "Fecha de Nacimiento", type: "date", icon: "fa-calendar" })] }) }), _jsx(Accordion, { title: "Informaci\u00F3n de Contacto", icon: "fa-address-book", rightNode: _jsx(Badge, { variant: "warning", children: "Pendiente" }), children: _jsxs("div", { className: "space-y-3", children: [_jsx(Input, { label: "Email", type: "email", placeholder: "juan@ejemplo.com", icon: "fa-envelope" }), _jsx(Input, { label: "Tel\u00E9fono", type: "tel", placeholder: "+34 600 000 000", icon: "fa-phone" })] }) }), _jsx(Accordion, { title: "Configuraci\u00F3n de Seguridad", icon: "fa-shield-alt", rightNode: _jsx(Badge, { variant: "info", children: "Recomendado" }), children: _jsxs("div", { className: "space-y-3", children: [_jsx(Input, { label: "Contrase\u00F1a Actual", type: "password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", icon: "fa-lock" }), _jsx(Input, { label: "Nueva Contrase\u00F1a", type: "password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", icon: "fa-key" })] }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Background Personalizado" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "El componente detecta autom\u00E1ticamente las clases de background (bg-*) desde la prop className y las aplica al background del accordion. Las dem\u00E1s clases se aplican normalmente al contenedor." }), _jsxs("div", { className: "space-y-3", children: [_jsx(Accordion, { title: "Accordion con bg-blue-50", className: "bg-blue-50", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con background personalizado usando clases de Tailwind." }) }), _jsx(Accordion, { title: "Accordion con bg-gradient", className: "bg-gradient-to-br from-purple-100 to-pink-100", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Accordion con gradiente personalizado." }) }), _jsx(Accordion, { title: "Accordion con bg y otras clases", className: "bg-green-50", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Puedes combinar clases de background con otras clases de Tailwind." }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Title como ReactNode" }), _jsx("p", { className: "mb-4 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "El t\u00EDtulo puede ser un ReactNode, permitiendo incluir contenido personalizado como badges, iconos adicionales, o cualquier otro componente." }), _jsxs("div", { className: "space-y-3", children: [_jsx(Accordion, { title: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { children: "Proyecto Importante" }), _jsx(Badge, { variant: "danger", size: "sm", children: "Urgente" })] }), icon: "fa-project-diagram", children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "Este accordion tiene un t\u00EDtulo personalizado con un badge integrado." }) }), _jsx(Accordion, { title: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("i", { className: "fal fa-star text-yellow-500" }), _jsx("span", { children: "Favoritos" })] }), children: _jsx("p", { style: { color: "var(--flysoft-text-secondary)" }, children: "T\u00EDtulo personalizado con un icono de estrella integrado." }) })] })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Caracter\u00EDsticas" }), _jsx("div", { className: "space-y-3", children: _jsx("div", { className: "p-3 bg-[var(--color-bg-default)] border border-[var(--color-border-default)] rounded", children: _jsxs("ul", { className: "list-disc list-inside space-y-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: [_jsxs("li", { children: [_jsx("strong", { children: "Animaci\u00F3n suave:" }), " El contenido se expande y contrae con una animaci\u00F3n CSS de 300ms."] }), _jsxs("li", { children: [_jsx("strong", { children: "Icono opcional:" }), " Soporta iconos FontAwesome 5 del lado izquierdo del t\u00EDtulo."] }), _jsxs("li", { children: [_jsx("strong", { children: "RightNode:" }), " Permite agregar contenido personalizado (badges, botones, etc.) del lado derecho antes del chevron."] }), _jsxs("li", { children: [_jsx("strong", { children: "Estado controlado:" }), " Soporta estado controlado mediante ", _jsx("code", { children: "defaultOpen" }), " y", " ", _jsx("code", { children: "onToggle" }), "."] }), _jsxs("li", { children: [_jsx("strong", { children: "Title flexible:" }), " El t\u00EDtulo puede ser un string o un ReactNode, permitiendo contenido personalizado."] }), _jsxs("li", { children: [_jsx("strong", { children: "Accesibilidad:" }), " Incluye atributos ARIA para mejor accesibilidad."] }), _jsxs("li", { children: [_jsx("strong", { children: "Chevron din\u00E1mico:" }), " El chevron cambia autom\u00E1ticamente entre arriba (abierto) y abajo (cerrado)."] }), _jsxs("li", { children: [_jsx("strong", { children: "Variantes:" }), " Soporta tres variantes: default, elevated (con sombra) y outlined (con borde destacado)."] }), _jsxs("li", { children: [_jsx("strong", { children: "Background personalizado:" }), " El componente detecta autom\u00E1ticamente las clases de background (bg-*) y las aplica correctamente."] })] }) }) })] }), _jsxs("section", { children: [_jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: "var(--flysoft-text-primary)" }, children: "Props" }), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("th", { className: "px-4 py-2 text-left text-sm font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Prop" }), _jsx("th", { className: "px-4 py-2 text-left text-sm font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Tipo" }), _jsx("th", { className: "px-4 py-2 text-left text-sm font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Requerido" }), _jsx("th", { className: "px-4 py-2 text-left text-sm font-semibold", style: { color: "var(--flysoft-text-primary)" }, children: "Descripci\u00F3n" })] }) }), _jsxs("tbody", { children: [_jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "title" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "string | ReactNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "S\u00ED" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "T\u00EDtulo del accordion. Puede ser un string o un ReactNode." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "children" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "ReactNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "S\u00ED" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Contenido que se muestra cuando el accordion est\u00E1 abierto." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "icon" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "string" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Clase de icono FontAwesome 5 (ej: \"fa-user\", \"fa-cog\") que se muestra del lado izquierdo del t\u00EDtulo." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "rightNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "ReactNode" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Contenido personalizado que se muestra del lado derecho, antes del chevron. \u00DAtil para badges, botones, contadores, etc." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "defaultOpen" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "boolean" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Si es true, el accordion estar\u00E1 abierto por defecto. Por defecto es false." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "onToggle" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "(isOpen: boolean) => void" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Callback que se ejecuta cuando el accordion se abre o cierra. Recibe un boolean indicando si est\u00E1 abierto (true) o cerrado (false)." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "variant" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "\"default\" | \"elevated\" | \"outlined\"" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Variante visual del accordion. Por defecto es \"default\"." })] }), _jsxs("tr", { className: "border-b border-[var(--color-border-default)]", children: [_jsx("td", { className: "px-4 py-2 text-sm font-mono", style: { color: "var(--flysoft-text-primary)" }, children: "className" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "string" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "No" }), _jsx("td", { className: "px-4 py-2 text-sm", style: { color: "var(--flysoft-text-secondary)" }, children: "Clases CSS adicionales. Las clases de background (bg-*) se aplican autom\u00E1ticamente al background del accordion." })] })] })] }) })] })] }) }) }));
|
|
20
|
+
};
|
|
21
|
+
export default AccordionDocs;
|
|
@@ -13,12 +13,10 @@ export const AuthDocsContent = () => {
|
|
|
13
13
|
// Sección de documentación de interfaces (siempre visible)
|
|
14
14
|
const InterfacesDocumentation = () => (_jsx("div", { className: "space-y-4 mb-6", children: _jsx(Card, { title: "Interfaces de TypeScript", subtitle: "Estructuras de datos utilizadas por el AuthContext", children: _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx(Badge, { variant: "primary", icon: "fa-code", size: "sm", children: "Interface" }), _jsx("code", { className: "text-sm font-mono text-[var(--color-primary)] font-semibold", children: "AuthTokenInterface" })] }), _jsx("p", { className: "text-sm text-[var(--color-text-secondary)] mb-3", children: "Define la estructura de los datos del token de autenticaci\u00F3n devueltos por el servicio de autenticaci\u00F3n." }), _jsx("div", { className: "bg-[var(--color-bg-secondary)] rounded-lg p-4 border border-[var(--color-border-default)]", children: _jsxs("div", { className: "space-y-2", children: [_jsx(DataField, { label: "accessToken", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Token de acceso utilizado para autenticar las solicitudes HTTP." }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "tokenType", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Tipo de token (generalmente \"Bearer\")." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "expires", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Fecha de expiraci\u00F3n del token en formato ISO 8601." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "refreshToken", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Token de actualizaci\u00F3n utilizado para obtener un nuevo token de acceso cuando el actual expira." })] })] }) })] }), _jsxs("div", { className: "pt-4 border-t border-[var(--color-border-default)]", children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx(Badge, { variant: "primary", icon: "fa-code", size: "sm", children: "Interface" }), _jsx("code", { className: "text-sm font-mono text-[var(--color-primary)] font-semibold", children: "AuthContextUserInterface" })] }), _jsx("p", { className: "text-sm text-[var(--color-text-secondary)] mb-3", children: "Define la estructura de los datos del usuario autenticado que se almacenan en el contexto." }), _jsx("div", { className: "bg-[var(--color-bg-secondary)] rounded-lg p-4 border border-[var(--color-border-default)]", children: _jsxs("div", { className: "space-y-2", children: [_jsx(DataField, { label: "id", value: _jsx("span", { className: "text-xs font-mono", children: "number | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Identificador \u00FAnico del usuario." }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "name", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Nombre del usuario." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "aditionalData", value: _jsx("span", { className: "text-xs font-mono", children: "any | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Objeto que puede contener datos adicionales del usuario (roles, permisos, email, etc.). Es flexible y puede adaptarse a las necesidades espec\u00EDficas de cada aplicaci\u00F3n." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "token", value: _jsx("span", { className: "text-xs font-mono", children: "AuthTokenInterface | undefined" }) }), _jsxs("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: ["Objeto de token que contiene el", " ", _jsx("code", { className: "text-xs bg-white/50 px-1 rounded", children: "AuthTokenInterface" }), " ", "con la informaci\u00F3n de autenticaci\u00F3n."] })] })] }) })] })] }) }) }));
|
|
15
15
|
if (isLoading) {
|
|
16
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { children: _jsx("div", { className: "flex items-center justify-center py-8", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("i", { className: "
|
|
16
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { children: _jsx("div", { className: "flex items-center justify-center py-8", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("i", { className: "fal fa-spinner fa-spin text-[var(--color-primary)] text-xl" }), _jsx("span", { className: "text-[var(--color-text-secondary)]", children: "Iniciando sesi\u00F3n..." })] }) }) })] }));
|
|
17
17
|
}
|
|
18
18
|
if (isAuthenticated && user) {
|
|
19
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Sesi\u00F3n Activa", subtitle: "Informaci\u00F3n del usuario autenticado", headerActions: () => [
|
|
20
|
-
_jsx(Badge, { variant: "success", icon: "fa-check-circle", iconPosition: "left", children: "Autenticado" }),
|
|
21
|
-
], children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "ID de Usuario", value: user.id }), _jsx(DataField, { label: "Nombre", value: user.name || "No disponible" })] }), user.aditionalData && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Datos Adicionales" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [user.aditionalData.role && (_jsx(DataField, { label: "Rol", value: _jsx(Badge, { variant: "primary", icon: "fa-user-shield", children: user.aditionalData.role }) })), user.aditionalData.email && (_jsx(DataField, { label: "Email", value: user.aditionalData.email })), user.aditionalData.createdAt && (_jsx(DataField, { label: "Fecha de Creaci\u00F3n", value: new Date(user.aditionalData.createdAt).toLocaleString() })), user.aditionalData.permissions && (_jsx(DataField, { label: "Permisos", value: _jsx("div", { className: "flex flex-wrap gap-2", children: user.aditionalData.permissions.map((permission, index) => (_jsx(Badge, { variant: "info", size: "sm", icon: "fa-key", children: permission }, index))) }) }))] })] })), user.token && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Informaci\u00F3n del Token" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "Tipo de Token", value: _jsx(Badge, { variant: "secondary", icon: "fa-tag", children: user.token.tokenType || "Bearer" }) }), user.token.expires && (_jsx(DataField, { label: "Expira", value: new Date(user.token.expires).toLocaleString() })), user.token.accessToken && (_jsx(DataField, { label: "Access Token", value: _jsxs("code", { className: "text-xs bg-[var(--color-bg-secondary)] px-2 py-1 rounded break-all", children: [user.token.accessToken.substring(0, 30), "..."] }) }))] })] })), _jsx("div", { className: "mt-6 pt-4 border-t border-[var(--color-border-default)]", children: _jsx(Button, { variant: "outline", icon: "fa-sign-out-alt", iconPosition: "left", onClick: handleLogout, className: "w-full md:w-auto", children: "Cerrar Sesi\u00F3n" }) })] }) })] }));
|
|
19
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Sesi\u00F3n Activa", subtitle: "Informaci\u00F3n del usuario autenticado", headerActions: _jsx(Badge, { variant: "success", icon: "fa-check-circle", iconPosition: "left", children: "Autenticado" }), children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "ID de Usuario", value: user.id }), _jsx(DataField, { label: "Nombre", value: user.name || "No disponible" })] }), user.aditionalData && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Datos Adicionales" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [user.aditionalData.role && (_jsx(DataField, { label: "Rol", value: _jsx(Badge, { variant: "primary", icon: "fa-user-shield", children: user.aditionalData.role }) })), user.aditionalData.email && (_jsx(DataField, { label: "Email", value: user.aditionalData.email })), user.aditionalData.createdAt && (_jsx(DataField, { label: "Fecha de Creaci\u00F3n", value: new Date(user.aditionalData.createdAt).toLocaleString() })), user.aditionalData.permissions && (_jsx(DataField, { label: "Permisos", value: _jsx("div", { className: "flex flex-wrap gap-2", children: user.aditionalData.permissions.map((permission, index) => (_jsx(Badge, { variant: "info", size: "sm", icon: "fa-key", children: permission }, index))) }) }))] })] })), user.token && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Informaci\u00F3n del Token" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "Tipo de Token", value: _jsx(Badge, { variant: "secondary", icon: "fa-tag", children: user.token.tokenType || "Bearer" }) }), user.token.expires && (_jsx(DataField, { label: "Expira", value: new Date(user.token.expires).toLocaleString() })), user.token.accessToken && (_jsx(DataField, { label: "Access Token", value: _jsxs("code", { className: "text-xs bg-[var(--color-bg-secondary)] px-2 py-1 rounded break-all", children: [user.token.accessToken.substring(0, 30), "..."] }) }))] })] })), _jsx("div", { className: "mt-6 pt-4 border-t border-[var(--color-border-default)]", children: _jsx(Button, { variant: "outline", icon: "fa-sign-out-alt", iconPosition: "left", onClick: handleLogout, className: "w-full md:w-auto", children: "Cerrar Sesi\u00F3n" }) })] }) })] }));
|
|
22
20
|
}
|
|
23
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Autenticaci\u00F3n", subtitle: "Inicia sesi\u00F3n para ver el AuthContext en acci\u00F3n", children: _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "bg-[var(--color-info-light)] border border-[var(--color-info)] rounded-lg p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("i", { className: "
|
|
21
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Autenticaci\u00F3n", subtitle: "Inicia sesi\u00F3n para ver el AuthContext en acci\u00F3n", children: _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "bg-[var(--color-info-light)] border border-[var(--color-info)] rounded-lg p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("i", { className: "fal fa-info-circle text-[var(--color-info)] mt-1" }), _jsx("div", { className: "flex-1", children: _jsxs("p", { className: "text-sm text-[var(--color-text-primary)]", children: ["Esta es una demostraci\u00F3n del", " ", _jsx("code", { className: "text-xs bg-white/50 px-1 rounded", children: "AuthContext" }), " ", "usando un servicio mock. Haz clic en el bot\u00F3n para simular un inicio de sesi\u00F3n."] }) })] }) }), _jsx("div", { className: "flex justify-center pt-4", children: _jsx(Button, { variant: "primary", size: "lg", icon: "fa-sign-in-alt", iconPosition: "left", onClick: handleLogin, children: "Iniciar Sesi\u00F3n" }) })] }) })] }));
|
|
24
22
|
};
|