flysoft-react-ui 1.2.4 → 1.2.5
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/AI_CONTEXT.md +1400 -217
- package/AI_INTEGRATION_GUIDE.md +343 -0
- package/INTEGRATION_GUIDE.md +60 -0
- package/README.md +5 -3
- package/dist/components/form-controls/Input.d.ts.map +1 -1
- package/dist/components/layout/Accordion.d.ts +1 -0
- package/dist/components/layout/Accordion.d.ts.map +1 -1
- package/dist/components/layout/DataTable.d.ts.map +1 -1
- package/dist/components/layout/DropdownMenu.d.ts +2 -1
- package/dist/components/layout/DropdownMenu.d.ts.map +1 -1
- package/dist/components/layout/DropdownPanel.d.ts +2 -1
- package/dist/components/layout/DropdownPanel.d.ts.map +1 -1
- package/dist/components/layout/Filter.d.ts +1 -0
- package/dist/components/layout/Filter.d.ts.map +1 -1
- package/dist/components/layout/Menu.d.ts +2 -1
- package/dist/components/layout/Menu.d.ts.map +1 -1
- package/dist/components/layout/TabsGroup.d.ts +1 -0
- package/dist/components/layout/TabsGroup.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11889 -24
- package/dist/index.js.map +1 -1
- package/dist/templates/forms/ContactForm.d.ts +1 -0
- package/dist/templates/forms/ContactForm.d.ts.map +1 -1
- package/dist/templates/forms/LoginForm.d.ts +1 -0
- package/dist/templates/forms/LoginForm.d.ts.map +1 -1
- package/dist/templates/forms/RegistrationForm.d.ts +1 -0
- package/dist/templates/forms/RegistrationForm.d.ts.map +1 -1
- package/dist/templates/layouts/DashboardLayout.d.ts +1 -0
- package/dist/templates/layouts/DashboardLayout.d.ts.map +1 -1
- package/dist/templates/layouts/SidebarLayout.d.ts +1 -0
- package/dist/templates/layouts/SidebarLayout.d.ts.map +1 -1
- package/dist/templates/patterns/FormPattern.d.ts +1 -0
- package/dist/templates/patterns/FormPattern.d.ts.map +1 -1
- package/dist/templates/patterns/ListPattern.d.ts +77 -0
- package/dist/templates/patterns/ListPattern.d.ts.map +1 -0
- package/package.json +6 -3
- package/dist/App.d.ts +0 -4
- package/dist/App.d.ts.map +0 -1
- package/dist/App.js +0 -30
- package/dist/components/ThemeSwitcher.js +0 -12
- package/dist/components/form-controls/AutocompleteInput.js +0 -680
- package/dist/components/form-controls/Button.js +0 -211
- package/dist/components/form-controls/Checkbox.js +0 -79
- package/dist/components/form-controls/CurrencyInput.js +0 -106
- package/dist/components/form-controls/DateInput.js +0 -578
- package/dist/components/form-controls/DatePicker.js +0 -144
- package/dist/components/form-controls/Input.js +0 -35
- package/dist/components/form-controls/LinkButton.js +0 -248
- package/dist/components/form-controls/Pagination.js +0 -23
- package/dist/components/form-controls/RadioButtonGroup.js +0 -220
- package/dist/components/form-controls/SearchSelectInput.js +0 -336
- package/dist/components/form-controls/index.js +0 -11
- package/dist/components/index.js +0 -7
- package/dist/components/layout/Accordion.js +0 -67
- package/dist/components/layout/AppLayout.js +0 -230
- package/dist/components/layout/Card.js +0 -54
- package/dist/components/layout/Collection.js +0 -18
- package/dist/components/layout/DataField.js +0 -38
- package/dist/components/layout/DataTable.js +0 -164
- package/dist/components/layout/DropdownMenu.js +0 -176
- package/dist/components/layout/DropdownPanel.js +0 -162
- package/dist/components/layout/Filter.js +0 -629
- package/dist/components/layout/Menu.js +0 -21
- package/dist/components/layout/TabPanel.js +0 -11
- package/dist/components/layout/TabsGroup.js +0 -52
- package/dist/components/layout/index.js +0 -12
- package/dist/components/utils/Avatar.js +0 -77
- package/dist/components/utils/Badge.js +0 -151
- package/dist/components/utils/Dialog.js +0 -44
- package/dist/components/utils/FiltersDialog.js +0 -104
- package/dist/components/utils/Loader.js +0 -44
- package/dist/components/utils/RoadMap.js +0 -139
- package/dist/components/utils/Skeleton.js +0 -10
- package/dist/components/utils/Snackbar.js +0 -136
- package/dist/components/utils/SnackbarContainer.js +0 -26
- package/dist/components/utils/iconUtils.js +0 -40
- package/dist/components/utils/index.js +0 -9
- package/dist/contexts/AppLayoutContext.js +0 -104
- package/dist/contexts/AuthContext.js +0 -224
- package/dist/contexts/CrudContext.js +0 -333
- package/dist/contexts/SnackbarContext.js +0 -41
- package/dist/contexts/ThemeContext.js +0 -197
- package/dist/contexts/index.js +0 -13
- package/dist/contexts/presets.js +0 -311
- package/dist/contexts/types.js +0 -1
- package/dist/docs/AccordionDocs.d.ts +0 -4
- package/dist/docs/AccordionDocs.d.ts.map +0 -1
- package/dist/docs/AccordionDocs.js +0 -21
- package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts +0 -13
- package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts.map +0 -1
- package/dist/docs/AuthDocs.tsx/AuthDocs.js +0 -18
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.d.ts +0 -2
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.d.ts.map +0 -1
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +0 -22
- package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts +0 -24
- package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts.map +0 -1
- package/dist/docs/AuthDocs.tsx/mockAuthService.js +0 -78
- package/dist/docs/AutocompleteInputDocs.d.ts +0 -4
- package/dist/docs/AutocompleteInputDocs.d.ts.map +0 -1
- package/dist/docs/AutocompleteInputDocs.js +0 -84
- package/dist/docs/AvatarDocs.d.ts +0 -4
- package/dist/docs/AvatarDocs.d.ts.map +0 -1
- package/dist/docs/AvatarDocs.js +0 -7
- package/dist/docs/BadgeDocs.d.ts +0 -4
- package/dist/docs/BadgeDocs.d.ts.map +0 -1
- package/dist/docs/BadgeDocs.js +0 -9
- package/dist/docs/ButtonDocs.d.ts +0 -4
- package/dist/docs/ButtonDocs.d.ts.map +0 -1
- package/dist/docs/ButtonDocs.js +0 -7
- package/dist/docs/CardDocs.d.ts +0 -4
- package/dist/docs/CardDocs.d.ts.map +0 -1
- package/dist/docs/CardDocs.js +0 -22
- package/dist/docs/CheckboxDocs.d.ts +0 -4
- package/dist/docs/CheckboxDocs.d.ts.map +0 -1
- package/dist/docs/CheckboxDocs.js +0 -7
- package/dist/docs/CurrencyInputDocs.d.ts +0 -4
- package/dist/docs/CurrencyInputDocs.d.ts.map +0 -1
- package/dist/docs/CurrencyInputDocs.js +0 -22
- package/dist/docs/DataFieldDocs.d.ts +0 -4
- package/dist/docs/DataFieldDocs.d.ts.map +0 -1
- package/dist/docs/DataFieldDocs.js +0 -7
- package/dist/docs/DataTableDocs.d.ts +0 -4
- package/dist/docs/DataTableDocs.d.ts.map +0 -1
- package/dist/docs/DataTableDocs.js +0 -244
- package/dist/docs/DateInputDocs.d.ts +0 -5
- package/dist/docs/DateInputDocs.d.ts.map +0 -1
- package/dist/docs/DateInputDocs.js +0 -19
- package/dist/docs/DatePickerDocs.d.ts +0 -5
- package/dist/docs/DatePickerDocs.d.ts.map +0 -1
- package/dist/docs/DatePickerDocs.js +0 -16
- package/dist/docs/DialogDocs.d.ts +0 -4
- package/dist/docs/DialogDocs.d.ts.map +0 -1
- package/dist/docs/DialogDocs.js +0 -13
- package/dist/docs/DocAdmin.d.ts +0 -4
- package/dist/docs/DocAdmin.d.ts.map +0 -1
- package/dist/docs/DocAdmin.js +0 -68
- package/dist/docs/DocsMenu.d.ts +0 -2
- package/dist/docs/DocsMenu.d.ts.map +0 -1
- package/dist/docs/DocsMenu.js +0 -5
- package/dist/docs/DocsRouter.d.ts +0 -4
- package/dist/docs/DocsRouter.d.ts.map +0 -1
- package/dist/docs/DocsRouter.js +0 -39
- package/dist/docs/DropdownMenuDocs.d.ts +0 -4
- package/dist/docs/DropdownMenuDocs.d.ts.map +0 -1
- package/dist/docs/DropdownMenuDocs.js +0 -66
- package/dist/docs/DropdownPanelDocs.d.ts +0 -4
- package/dist/docs/DropdownPanelDocs.d.ts.map +0 -1
- package/dist/docs/DropdownPanelDocs.js +0 -7
- package/dist/docs/ExampleFormDocs.d.ts +0 -4
- package/dist/docs/ExampleFormDocs.d.ts.map +0 -1
- package/dist/docs/ExampleFormDocs.js +0 -153
- package/dist/docs/FilterDocs.d.ts +0 -4
- package/dist/docs/FilterDocs.d.ts.map +0 -1
- package/dist/docs/FilterDocs.js +0 -130
- package/dist/docs/InputDocs.d.ts +0 -4
- package/dist/docs/InputDocs.d.ts.map +0 -1
- package/dist/docs/InputDocs.js +0 -17
- package/dist/docs/LinkButtonDocs.d.ts +0 -4
- package/dist/docs/LinkButtonDocs.d.ts.map +0 -1
- package/dist/docs/LinkButtonDocs.js +0 -7
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts +0 -2
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.d.ts.map +0 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocs.js +0 -47
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts +0 -2
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.d.ts.map +0 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaPersonas.js +0 -34
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts +0 -2
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.d.ts.map +0 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresaSingle.js +0 -66
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts +0 -2
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.d.ts.map +0 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresas.js +0 -7
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts +0 -10
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.d.ts.map +0 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentEmpresasPersonasEditDialog.js +0 -39
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts +0 -2
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.d.ts.map +0 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsContentPersonas.js +0 -57
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts +0 -9
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.d.ts.map +0 -1
- package/dist/docs/ListCrudDocs.tsx/ListCrudDocsEditDialog.js +0 -30
- package/dist/docs/LoaderDocs.d.ts +0 -4
- package/dist/docs/LoaderDocs.d.ts.map +0 -1
- package/dist/docs/LoaderDocs.js +0 -33
- package/dist/docs/MenuDocs.d.ts +0 -4
- package/dist/docs/MenuDocs.d.ts.map +0 -1
- package/dist/docs/MenuDocs.js +0 -26
- package/dist/docs/PaginationDocs.d.ts +0 -4
- package/dist/docs/PaginationDocs.d.ts.map +0 -1
- package/dist/docs/PaginationDocs.js +0 -38
- package/dist/docs/RadioButtonGroupDocs.d.ts +0 -4
- package/dist/docs/RadioButtonGroupDocs.d.ts.map +0 -1
- package/dist/docs/RadioButtonGroupDocs.js +0 -46
- package/dist/docs/RoadMapDocs.d.ts +0 -4
- package/dist/docs/RoadMapDocs.d.ts.map +0 -1
- package/dist/docs/RoadMapDocs.js +0 -171
- package/dist/docs/SearchSelectInputDocs.d.ts +0 -4
- package/dist/docs/SearchSelectInputDocs.d.ts.map +0 -1
- package/dist/docs/SearchSelectInputDocs.js +0 -168
- package/dist/docs/SkeletonDocs.d.ts +0 -4
- package/dist/docs/SkeletonDocs.d.ts.map +0 -1
- package/dist/docs/SkeletonDocs.js +0 -7
- package/dist/docs/SnackbarDocs.d.ts +0 -4
- package/dist/docs/SnackbarDocs.d.ts.map +0 -1
- package/dist/docs/SnackbarDocs.js +0 -69
- package/dist/docs/TabsGroupDocs.d.ts +0 -4
- package/dist/docs/TabsGroupDocs.d.ts.map +0 -1
- package/dist/docs/TabsGroupDocs.js +0 -38
- package/dist/docs/ThemeSwitcherDocs.d.ts +0 -4
- package/dist/docs/ThemeSwitcherDocs.d.ts.map +0 -1
- package/dist/docs/ThemeSwitcherDocs.js +0 -11
- package/dist/docs/docMockServices/empresaService.d.ts +0 -38
- package/dist/docs/docMockServices/empresaService.d.ts.map +0 -1
- package/dist/docs/docMockServices/empresaService.js +0 -125
- package/dist/docs/docMockServices/index.d.ts +0 -9
- package/dist/docs/docMockServices/index.d.ts.map +0 -1
- package/dist/docs/docMockServices/index.js +0 -8
- package/dist/docs/docMockServices/initialData.d.ts +0 -6
- package/dist/docs/docMockServices/initialData.d.ts.map +0 -1
- package/dist/docs/docMockServices/initialData.js +0 -132
- package/dist/docs/docMockServices/interfaces.d.ts +0 -38
- package/dist/docs/docMockServices/interfaces.d.ts.map +0 -1
- package/dist/docs/docMockServices/interfaces.js +0 -1
- package/dist/docs/docMockServices/personaEmpresaService.d.ts +0 -43
- package/dist/docs/docMockServices/personaEmpresaService.d.ts.map +0 -1
- package/dist/docs/docMockServices/personaEmpresaService.js +0 -151
- package/dist/docs/docMockServices/personaService.d.ts +0 -39
- package/dist/docs/docMockServices/personaService.d.ts.map +0 -1
- package/dist/docs/docMockServices/personaService.js +0 -190
- package/dist/helpers/currencyFormat.js +0 -3
- package/dist/helpers/getErrorMessage.js +0 -13
- package/dist/helpers/getInitialLetters.js +0 -5
- package/dist/helpers/getQueryString.js +0 -13
- package/dist/helpers/index.js +0 -9
- package/dist/helpers/mappers.js +0 -27
- package/dist/helpers/nameValueArrayToObject.js +0 -3
- package/dist/helpers/objectToQueryString.js +0 -3
- package/dist/helpers/queryStringToObject.js +0 -13
- package/dist/helpers/regularExpressions.js +0 -5
- package/dist/hooks/index.js +0 -6
- package/dist/hooks/useAsyncRequest.js +0 -53
- package/dist/hooks/useBreakpoint.js +0 -59
- package/dist/hooks/useElementScroll.js +0 -58
- package/dist/hooks/useEnum.js +0 -21
- package/dist/hooks/useGlobalThemeStyles.js +0 -40
- package/dist/hooks/useThemeOverride.js +0 -99
- package/dist/interfaces/index.js +0 -1
- package/dist/interfaces/name-value.interface.js +0 -1
- package/dist/interfaces/pagination.interface.js +0 -1
- package/dist/main.d.ts +0 -2
- package/dist/main.d.ts.map +0 -1
- package/dist/main.js +0 -6
- package/dist/services/apiClient.js +0 -216
- package/dist/services/index.js +0 -1
- package/dist/styles.d.ts +0 -2
- package/dist/styles.d.ts.map +0 -1
- package/dist/styles.js +0 -3
- package/dist/templates/forms/ContactForm.js +0 -58
- package/dist/templates/forms/LoginForm.js +0 -36
- package/dist/templates/forms/RegistrationForm.js +0 -54
- package/dist/templates/layouts/DashboardLayout.js +0 -26
- package/dist/templates/layouts/SidebarLayout.js +0 -28
- package/dist/templates/patterns/FormPattern.js +0 -68
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from "react";
|
|
2
|
-
export const useElementScroll = (elementRef) => {
|
|
3
|
-
const [scrollY, setScrollY] = useState(0);
|
|
4
|
-
const [scrollDirection, setScrollDirection] = useState(null);
|
|
5
|
-
useEffect(() => {
|
|
6
|
-
if (!elementRef.current)
|
|
7
|
-
return;
|
|
8
|
-
const element = elementRef.current;
|
|
9
|
-
let lastScrollY = element.scrollTop;
|
|
10
|
-
let lastDirection = null;
|
|
11
|
-
let rafId = null;
|
|
12
|
-
let pendingScrollY = element.scrollTop;
|
|
13
|
-
const handleScroll = () => {
|
|
14
|
-
pendingScrollY = element.scrollTop;
|
|
15
|
-
// Usar requestAnimationFrame para agrupar actualizaciones y evitar temblores
|
|
16
|
-
if (rafId === null) {
|
|
17
|
-
rafId = requestAnimationFrame(() => {
|
|
18
|
-
rafId = null;
|
|
19
|
-
const currentScrollY = pendingScrollY;
|
|
20
|
-
const delta = currentScrollY - lastScrollY;
|
|
21
|
-
// Verificar si estamos cerca del final (margen de 5px)
|
|
22
|
-
const isNearBottom = Math.abs(element.scrollHeight - element.clientHeight - currentScrollY) < 5;
|
|
23
|
-
let newDirection = lastDirection;
|
|
24
|
-
// Si estamos cerca del final y el delta es muy pequeño, mantener la dirección actual
|
|
25
|
-
if (isNearBottom && Math.abs(delta) < 2) {
|
|
26
|
-
// Mantener la dirección actual, no cambiar
|
|
27
|
-
}
|
|
28
|
-
else if (delta > 4 && currentScrollY > 10) {
|
|
29
|
-
newDirection = "down";
|
|
30
|
-
}
|
|
31
|
-
else if (delta < -4 && currentScrollY > 0) {
|
|
32
|
-
newDirection = "up";
|
|
33
|
-
}
|
|
34
|
-
else if (Math.abs(delta) < 2) {
|
|
35
|
-
// Cambios muy pequeños, mantener la dirección actual
|
|
36
|
-
newDirection = lastDirection;
|
|
37
|
-
}
|
|
38
|
-
setScrollY(currentScrollY);
|
|
39
|
-
// Solo actualizar la dirección si cambió realmente
|
|
40
|
-
if (newDirection !== lastDirection) {
|
|
41
|
-
setScrollDirection(newDirection);
|
|
42
|
-
lastDirection = newDirection;
|
|
43
|
-
}
|
|
44
|
-
lastScrollY = currentScrollY;
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
// Agregar el listener al elemento
|
|
49
|
-
element.addEventListener("scroll", handleScroll, { passive: true });
|
|
50
|
-
return () => {
|
|
51
|
-
if (rafId !== null) {
|
|
52
|
-
cancelAnimationFrame(rafId);
|
|
53
|
-
}
|
|
54
|
-
element.removeEventListener("scroll", handleScroll);
|
|
55
|
-
};
|
|
56
|
-
}, [elementRef]);
|
|
57
|
-
return { scrollY, scrollDirection };
|
|
58
|
-
};
|
package/dist/hooks/useEnum.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export const useEnum = (baseEnum) => {
|
|
2
|
-
const buildArray = () => {
|
|
3
|
-
return Object.keys(baseEnum)
|
|
4
|
-
.filter((t) => isNaN(+t))
|
|
5
|
-
.map((t) => ({
|
|
6
|
-
name: t.split("_").join(" "),
|
|
7
|
-
value: baseEnum[t],
|
|
8
|
-
}));
|
|
9
|
-
};
|
|
10
|
-
const array = buildArray();
|
|
11
|
-
const getArray = () => {
|
|
12
|
-
return array;
|
|
13
|
-
};
|
|
14
|
-
const getInstance = (id) => {
|
|
15
|
-
return array.find((i) => i.value === id);
|
|
16
|
-
};
|
|
17
|
-
return {
|
|
18
|
-
getArray,
|
|
19
|
-
getInstance,
|
|
20
|
-
};
|
|
21
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { useTheme } from "../contexts/ThemeContext";
|
|
3
|
-
/**
|
|
4
|
-
* Hook que aplica estilos globales del tema al body y html
|
|
5
|
-
* Útil para aplicaciones host que quieren que el tema afecte toda la página
|
|
6
|
-
*/
|
|
7
|
-
export const useGlobalThemeStyles = () => {
|
|
8
|
-
const { theme } = useTheme();
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
const body = document.body;
|
|
11
|
-
const html = document.documentElement;
|
|
12
|
-
if (body) {
|
|
13
|
-
// Aplicar estilos al body
|
|
14
|
-
body.style.backgroundColor = theme.colors.bgDefault;
|
|
15
|
-
body.style.color = theme.colors.textPrimary;
|
|
16
|
-
body.style.fontFamily = theme.fonts.default;
|
|
17
|
-
body.style.margin = "0";
|
|
18
|
-
body.style.padding = "0";
|
|
19
|
-
}
|
|
20
|
-
if (html) {
|
|
21
|
-
// Aplicar estilos al html
|
|
22
|
-
html.style.backgroundColor = theme.colors.bgDefault;
|
|
23
|
-
html.style.color = theme.colors.textPrimary;
|
|
24
|
-
}
|
|
25
|
-
// Cleanup function para restaurar estilos originales
|
|
26
|
-
return () => {
|
|
27
|
-
if (body) {
|
|
28
|
-
body.style.backgroundColor = "";
|
|
29
|
-
body.style.color = "";
|
|
30
|
-
body.style.fontFamily = "";
|
|
31
|
-
body.style.margin = "";
|
|
32
|
-
body.style.padding = "";
|
|
33
|
-
}
|
|
34
|
-
if (html) {
|
|
35
|
-
html.style.backgroundColor = "";
|
|
36
|
-
html.style.color = "";
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}, [theme]);
|
|
40
|
-
};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef } from "react";
|
|
2
|
-
/**
|
|
3
|
-
* Hook para aplicar overrides directos a variables CSS del tema
|
|
4
|
-
* Permite personalización granular sin cambiar el tema completo
|
|
5
|
-
*/
|
|
6
|
-
export const useThemeOverride = (options = {}) => {
|
|
7
|
-
const { scope = "global", element = null, prefix = "flysoft" } = options;
|
|
8
|
-
const appliedOverrides = useRef(new Set());
|
|
9
|
-
// Función para aplicar override
|
|
10
|
-
const applyOverride = useCallback((overrides) => {
|
|
11
|
-
const targetElement = scope === "global" ? document.documentElement : element;
|
|
12
|
-
if (!targetElement) {
|
|
13
|
-
console.warn("useThemeOverride: No target element available");
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
Object.entries(overrides).forEach(([key, value]) => {
|
|
17
|
-
const cssVarName = `--${prefix}-${key
|
|
18
|
-
.replace(/([A-Z])/g, "-$1")
|
|
19
|
-
.toLowerCase()}`;
|
|
20
|
-
// Aplicar el override
|
|
21
|
-
targetElement.style.setProperty(cssVarName, String(value));
|
|
22
|
-
// Registrar para poder revertir después
|
|
23
|
-
appliedOverrides.current.add(cssVarName);
|
|
24
|
-
});
|
|
25
|
-
}, [scope, element, prefix]);
|
|
26
|
-
// Función para revertir overrides específicos
|
|
27
|
-
const revertOverride = useCallback((keys) => {
|
|
28
|
-
const targetElement = scope === "global" ? document.documentElement : element;
|
|
29
|
-
if (!targetElement)
|
|
30
|
-
return;
|
|
31
|
-
keys.forEach((key) => {
|
|
32
|
-
const cssVarName = `--${prefix}-${key
|
|
33
|
-
.replace(/([A-Z])/g, "-$1")
|
|
34
|
-
.toLowerCase()}`;
|
|
35
|
-
if (appliedOverrides.current.has(cssVarName)) {
|
|
36
|
-
targetElement.style.removeProperty(cssVarName);
|
|
37
|
-
appliedOverrides.current.delete(cssVarName);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}, [scope, element, prefix]);
|
|
41
|
-
// Función para revertir todos los overrides aplicados
|
|
42
|
-
const revertAllOverrides = useCallback(() => {
|
|
43
|
-
const targetElement = scope === "global" ? document.documentElement : element;
|
|
44
|
-
if (!targetElement)
|
|
45
|
-
return;
|
|
46
|
-
appliedOverrides.current.forEach((cssVarName) => {
|
|
47
|
-
targetElement.style.removeProperty(cssVarName);
|
|
48
|
-
});
|
|
49
|
-
appliedOverrides.current.clear();
|
|
50
|
-
}, [scope, element]);
|
|
51
|
-
// Función para obtener el valor actual de una variable CSS
|
|
52
|
-
const getCSSVariable = useCallback((key) => {
|
|
53
|
-
const targetElement = scope === "global" ? document.documentElement : element;
|
|
54
|
-
if (!targetElement)
|
|
55
|
-
return null;
|
|
56
|
-
const cssVarName = `--${prefix}-${key
|
|
57
|
-
.replace(/([A-Z])/g, "-$1")
|
|
58
|
-
.toLowerCase()}`;
|
|
59
|
-
return (getComputedStyle(targetElement).getPropertyValue(cssVarName) || null);
|
|
60
|
-
}, [scope, element, prefix]);
|
|
61
|
-
// Función para verificar si un override está aplicado
|
|
62
|
-
const isOverrideApplied = useCallback((key) => {
|
|
63
|
-
const cssVarName = `--${prefix}-${key
|
|
64
|
-
.replace(/([A-Z])/g, "-$1")
|
|
65
|
-
.toLowerCase()}`;
|
|
66
|
-
return appliedOverrides.current.has(cssVarName);
|
|
67
|
-
}, [prefix]);
|
|
68
|
-
// Cleanup al desmontar
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
return () => {
|
|
71
|
-
revertAllOverrides();
|
|
72
|
-
};
|
|
73
|
-
}, [revertAllOverrides]);
|
|
74
|
-
return {
|
|
75
|
-
applyOverride,
|
|
76
|
-
revertOverride,
|
|
77
|
-
revertAllOverrides,
|
|
78
|
-
getCSSVariable,
|
|
79
|
-
isOverrideApplied,
|
|
80
|
-
appliedOverridesCount: appliedOverrides.current.size,
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
/**
|
|
84
|
-
* Hook para aplicar overrides temporales que se revierten automáticamente
|
|
85
|
-
*/
|
|
86
|
-
export const useTemporaryOverride = (overrides, duration = 3000, options = {}) => {
|
|
87
|
-
const { applyOverride, revertOverride } = useThemeOverride(options);
|
|
88
|
-
const applyTemporaryOverride = useCallback(() => {
|
|
89
|
-
applyOverride(overrides);
|
|
90
|
-
const timeoutId = setTimeout(() => {
|
|
91
|
-
revertOverride(Object.keys(overrides));
|
|
92
|
-
}, duration);
|
|
93
|
-
return () => {
|
|
94
|
-
clearTimeout(timeoutId);
|
|
95
|
-
revertOverride(Object.keys(overrides));
|
|
96
|
-
};
|
|
97
|
-
}, [applyOverride, revertOverride, overrides, duration]);
|
|
98
|
-
return { applyTemporaryOverride };
|
|
99
|
-
};
|
package/dist/interfaces/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/main.d.ts
DELETED
package/dist/main.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":""}
|
package/dist/main.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { StrictMode } from "react";
|
|
3
|
-
import { createRoot } from "react-dom/client";
|
|
4
|
-
import { BrowserRouter } from "react-router-dom";
|
|
5
|
-
import App from "./App";
|
|
6
|
-
createRoot(document.getElementById("root")).render(_jsx(StrictMode, { children: _jsx(BrowserRouter, { future: { v7_startTransition: true, v7_relativeSplatPath: true }, children: _jsx(App, {}) }) }));
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import axios, {} from "axios";
|
|
2
|
-
class ApiClientService {
|
|
3
|
-
instance;
|
|
4
|
-
tokenProvider;
|
|
5
|
-
constructor(config) {
|
|
6
|
-
this.instance = axios.create({
|
|
7
|
-
baseURL: config?.baseURL ?? "",
|
|
8
|
-
timeout: config?.timeout ?? 15000,
|
|
9
|
-
headers: {
|
|
10
|
-
"Content-Type": "application/json",
|
|
11
|
-
...config?.headers,
|
|
12
|
-
},
|
|
13
|
-
});
|
|
14
|
-
this.setupInterceptors();
|
|
15
|
-
}
|
|
16
|
-
setupInterceptors() {
|
|
17
|
-
// Request interceptor para inyectar el token automáticamente
|
|
18
|
-
this.instance.interceptors.request.use((config) => {
|
|
19
|
-
const token = this.tokenProvider?.();
|
|
20
|
-
if (token && config.headers) {
|
|
21
|
-
// Manejo compatible con diferentes versiones de axios
|
|
22
|
-
if ("set" in config.headers &&
|
|
23
|
-
typeof config.headers.set === "function") {
|
|
24
|
-
config.headers.set("Authorization", `Bearer ${token}`);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
const headers = config.headers;
|
|
28
|
-
headers.Authorization = `Bearer ${token}`;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return config;
|
|
32
|
-
}, (error) => {
|
|
33
|
-
return Promise.reject(error);
|
|
34
|
-
});
|
|
35
|
-
// Response interceptor para manejo de errores (opcional, puede extenderse)
|
|
36
|
-
this.instance.interceptors.response.use((response) => response, (error) => {
|
|
37
|
-
return Promise.reject(error);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Establece el proveedor de token que se usará en todas las peticiones
|
|
42
|
-
* @param provider Función que retorna el token de autorización
|
|
43
|
-
*/
|
|
44
|
-
setTokenProvider(provider) {
|
|
45
|
-
this.tokenProvider = provider;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Limpia el proveedor de token
|
|
49
|
-
*/
|
|
50
|
-
clearTokenProvider() {
|
|
51
|
-
this.tokenProvider = undefined;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Actualiza la configuración por defecto del cliente
|
|
55
|
-
*/
|
|
56
|
-
updateDefaults(config) {
|
|
57
|
-
if (config.baseURL) {
|
|
58
|
-
this.instance.defaults.baseURL = config.baseURL;
|
|
59
|
-
}
|
|
60
|
-
if (config.timeout) {
|
|
61
|
-
this.instance.defaults.timeout = config.timeout;
|
|
62
|
-
}
|
|
63
|
-
if (config.headers) {
|
|
64
|
-
// Actualizar headers comunes de forma segura
|
|
65
|
-
Object.assign(this.instance.defaults.headers.common || {}, config.headers);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
async axiosRequest({ method, url, headers, body, params, }) {
|
|
69
|
-
return await this.instance({
|
|
70
|
-
method,
|
|
71
|
-
headers,
|
|
72
|
-
url,
|
|
73
|
-
data: body,
|
|
74
|
-
params,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Realiza una petición GET
|
|
79
|
-
*/
|
|
80
|
-
async get(options) {
|
|
81
|
-
const { url, params, headers } = options;
|
|
82
|
-
const response = await this.axiosRequest({
|
|
83
|
-
method: "GET",
|
|
84
|
-
url,
|
|
85
|
-
params,
|
|
86
|
-
headers,
|
|
87
|
-
});
|
|
88
|
-
return response.data;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Realiza una petición POST
|
|
92
|
-
*/
|
|
93
|
-
async post(options) {
|
|
94
|
-
const { url, body, headers } = options;
|
|
95
|
-
const response = await this.axiosRequest({
|
|
96
|
-
method: "POST",
|
|
97
|
-
url,
|
|
98
|
-
headers,
|
|
99
|
-
body,
|
|
100
|
-
});
|
|
101
|
-
return response.data;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Realiza una petición PUT
|
|
105
|
-
*/
|
|
106
|
-
async put(options) {
|
|
107
|
-
const { url, body, headers } = options;
|
|
108
|
-
const response = await this.axiosRequest({
|
|
109
|
-
method: "PUT",
|
|
110
|
-
url,
|
|
111
|
-
headers,
|
|
112
|
-
body,
|
|
113
|
-
});
|
|
114
|
-
return response.data;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Realiza una petición DELETE
|
|
118
|
-
*/
|
|
119
|
-
async del(options) {
|
|
120
|
-
const { url, headers } = options;
|
|
121
|
-
const response = await this.axiosRequest({
|
|
122
|
-
method: "DELETE",
|
|
123
|
-
url,
|
|
124
|
-
headers,
|
|
125
|
-
});
|
|
126
|
-
return response.data;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Obtiene un archivo como Blob
|
|
130
|
-
*/
|
|
131
|
-
async getFile(options) {
|
|
132
|
-
const { url, headers = {} } = options;
|
|
133
|
-
const response = await this.instance.get(url, {
|
|
134
|
-
responseType: "blob",
|
|
135
|
-
headers,
|
|
136
|
-
});
|
|
137
|
-
return {
|
|
138
|
-
data: response.data,
|
|
139
|
-
headers: response.headers,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Obtiene un archivo y retorna su URL como objeto
|
|
144
|
-
*/
|
|
145
|
-
async getFileAsUrl(options) {
|
|
146
|
-
const { data } = await this.getFile(options);
|
|
147
|
-
const blob = new Blob([data], { type: data.type });
|
|
148
|
-
return URL.createObjectURL(blob);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Abre un archivo en una nueva ventana
|
|
152
|
-
*/
|
|
153
|
-
async openFile(options) {
|
|
154
|
-
const { data } = await this.getFile(options);
|
|
155
|
-
const urlData = URL.createObjectURL(data);
|
|
156
|
-
window.open(urlData);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Descarga un archivo
|
|
160
|
-
*/
|
|
161
|
-
async downloadFile(options) {
|
|
162
|
-
const { data, headers: dataHeaders } = await this.getFile(options);
|
|
163
|
-
const contentDisposition = dataHeaders["content-disposition"] || dataHeaders["Content-Disposition"];
|
|
164
|
-
const fileName = contentDisposition
|
|
165
|
-
?.split("filename=")[1]
|
|
166
|
-
?.split(";")[0]
|
|
167
|
-
.replaceAll('"', "");
|
|
168
|
-
const blob = new Blob([data], { type: data.type });
|
|
169
|
-
const link = document.createElement("a");
|
|
170
|
-
link.href = window.URL.createObjectURL(blob);
|
|
171
|
-
link.setAttribute("download", fileName || "");
|
|
172
|
-
document.body.appendChild(link);
|
|
173
|
-
link.click();
|
|
174
|
-
link.parentNode?.removeChild(link);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Sube uno o más archivos usando FormData
|
|
178
|
-
*/
|
|
179
|
-
async uploadFile(options) {
|
|
180
|
-
const { url, files, headers } = options;
|
|
181
|
-
const formData = new FormData();
|
|
182
|
-
const { paramName = "file", ...newHeaders } = headers || {};
|
|
183
|
-
const fileArray = Array.from(files);
|
|
184
|
-
for (const file of fileArray) {
|
|
185
|
-
formData.append(paramName, file, file.name);
|
|
186
|
-
}
|
|
187
|
-
const response = await this.instance.post(url, formData, {
|
|
188
|
-
headers: newHeaders,
|
|
189
|
-
});
|
|
190
|
-
return response.data;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
// Instancia compartida del cliente
|
|
194
|
-
const sharedClient = new ApiClientService();
|
|
195
|
-
/**
|
|
196
|
-
* Cliente de API compartido con todas las funciones de HTTP
|
|
197
|
-
*/
|
|
198
|
-
export const apiClient = sharedClient;
|
|
199
|
-
/**
|
|
200
|
-
* Crea una nueva instancia del cliente de API
|
|
201
|
-
*/
|
|
202
|
-
export const createApiClient = (config) => {
|
|
203
|
-
return new ApiClientService(config);
|
|
204
|
-
};
|
|
205
|
-
/**
|
|
206
|
-
* Establece el proveedor de token global para el cliente compartido
|
|
207
|
-
*/
|
|
208
|
-
export const setApiClientTokenProvider = (provider) => {
|
|
209
|
-
sharedClient.setTokenProvider(provider);
|
|
210
|
-
};
|
|
211
|
-
/**
|
|
212
|
-
* Limpia el proveedor de token global
|
|
213
|
-
*/
|
|
214
|
-
export const clearApiClientTokenProvider = () => {
|
|
215
|
-
sharedClient.clearTokenProvider();
|
|
216
|
-
};
|
package/dist/services/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { apiClient, createApiClient, setApiClientTokenProvider, clearApiClientTokenProvider, } from "./apiClient";
|
package/dist/styles.d.ts
DELETED
package/dist/styles.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":""}
|
package/dist/styles.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState } from "react";
|
|
3
|
-
import { Button, Input, Card } from "../../index";
|
|
4
|
-
export const ContactForm = ({ onSubmit, loading = false, success = false, error, className = "", }) => {
|
|
5
|
-
const [formData, setFormData] = useState({
|
|
6
|
-
name: "",
|
|
7
|
-
email: "",
|
|
8
|
-
subject: "",
|
|
9
|
-
message: "",
|
|
10
|
-
});
|
|
11
|
-
const [errors, setErrors] = useState({});
|
|
12
|
-
const handleSubmit = (e) => {
|
|
13
|
-
e.preventDefault();
|
|
14
|
-
// Validación
|
|
15
|
-
const newErrors = {};
|
|
16
|
-
if (!formData.name.trim()) {
|
|
17
|
-
newErrors.name = "El nombre es requerido";
|
|
18
|
-
}
|
|
19
|
-
if (!formData.email) {
|
|
20
|
-
newErrors.email = "El email es requerido";
|
|
21
|
-
}
|
|
22
|
-
else if (!/\S+@\S+\.\S+/.test(formData.email)) {
|
|
23
|
-
newErrors.email = "El email no es válido";
|
|
24
|
-
}
|
|
25
|
-
if (!formData.subject.trim()) {
|
|
26
|
-
newErrors.subject = "El asunto es requerido";
|
|
27
|
-
}
|
|
28
|
-
if (!formData.message.trim()) {
|
|
29
|
-
newErrors.message = "El mensaje es requerido";
|
|
30
|
-
}
|
|
31
|
-
else if (formData.message.trim().length < 10) {
|
|
32
|
-
newErrors.message = "El mensaje debe tener al menos 10 caracteres";
|
|
33
|
-
}
|
|
34
|
-
setErrors(newErrors);
|
|
35
|
-
if (Object.keys(newErrors).length === 0) {
|
|
36
|
-
onSubmit?.(formData);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
const handleChange = (field) => (e) => {
|
|
40
|
-
setFormData((prev) => ({ ...prev, [field]: e.target.value }));
|
|
41
|
-
// Limpiar error cuando el usuario empiece a escribir
|
|
42
|
-
if (errors[field]) {
|
|
43
|
-
setErrors((prev) => ({ ...prev, [field]: undefined }));
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
if (success) {
|
|
47
|
-
return (_jsx(Card, { title: "Mensaje Enviado", subtitle: "Gracias por contactarnos", className: className, children: _jsxs("div", { className: "text-center py-8", children: [_jsx("div", { className: "w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4", children: _jsx("i", { className: "fal fa-check text-green-600 text-2xl" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "\u00A1Mensaje enviado con \u00E9xito!" }), _jsx("p", { className: "text-gray-600 mb-4", children: "Hemos recibido tu mensaje y te responderemos pronto." }), _jsx(Button, { variant: "outline", onClick: () => window.location.reload(), icon: "fa-refresh", children: "Enviar otro mensaje" })] }) }));
|
|
48
|
-
}
|
|
49
|
-
return (_jsx(Card, { title: "Cont\u00E1ctanos", subtitle: "Env\u00EDanos un mensaje y te responderemos pronto", className: className, children: _jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [error && (_jsx("div", { className: "p-3 bg-red-50 border border-red-200 rounded-lg", children: _jsxs("p", { className: "text-sm text-red-600", children: [_jsx("i", { className: "fal fa-exclamation-triangle mr-2" }), error] }) })), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(Input, { label: "Nombre Completo", placeholder: "Tu nombre completo", icon: "fa-user", value: formData.name, onChange: handleChange("name"), error: errors.name, disabled: loading }), _jsx(Input, { label: "Email", type: "email", placeholder: "tu@email.com", icon: "fa-envelope", value: formData.email, onChange: handleChange("email"), error: errors.email, disabled: loading })] }), _jsx(Input, { label: "Asunto", placeholder: "\u00BFEn qu\u00E9 podemos ayudarte?", icon: "fa-tag", value: formData.subject, onChange: handleChange("subject"), error: errors.subject, disabled: loading }), _jsxs("div", { className: "w-full", children: [_jsx("label", { className: "block text-sm font-medium text-[var(--color-text-primary)] mb-1 font-[var(--font-default)]", children: "Mensaje" }), _jsxs("div", { className: "relative", children: [_jsx("i", { className: "fal fa-comment text-[var(--color-text-muted)] absolute top-3 left-3 w-5 h-5" }), _jsx("textarea", { placeholder: "Escribe tu mensaje aqu\u00ED...", className: `
|
|
50
|
-
w-full border rounded-lg transition-colors focus:outline-none focus:ring-2
|
|
51
|
-
disabled:opacity-50 disabled:cursor-not-allowed
|
|
52
|
-
font-[var(--font-default)] text-[var(--color-text-primary)]
|
|
53
|
-
bg-[var(--color-bg-default)] pl-10 pr-4 py-3 text-base
|
|
54
|
-
${errors.message
|
|
55
|
-
? "border-[var(--color-border-error)] focus:border-[var(--color-border-error)] focus:ring-[var(--color-border-error)]"
|
|
56
|
-
: "border-[var(--color-border-default)] focus:border-[var(--color-border-focus)] focus:ring-[var(--color-border-focus)]"}
|
|
57
|
-
`, rows: 5, value: formData.message, onChange: handleChange("message"), disabled: loading })] }), errors.message && (_jsx("p", { className: "mt-1 text-sm text-[var(--color-danger)] font-[var(--font-default)]", children: errors.message }))] }), _jsx(Button, { type: "submit", variant: "primary", size: "lg", icon: "fa-paper-plane", loading: loading, className: "w-full", children: "Enviar Mensaje" })] }) }));
|
|
58
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState } from "react";
|
|
3
|
-
import { Button, Input, Card } from "../../index";
|
|
4
|
-
export const LoginForm = ({ onSubmit, loading = false, error, className = "", }) => {
|
|
5
|
-
const [formData, setFormData] = useState({
|
|
6
|
-
email: "",
|
|
7
|
-
password: "",
|
|
8
|
-
});
|
|
9
|
-
const [errors, setErrors] = useState({});
|
|
10
|
-
const handleSubmit = (e) => {
|
|
11
|
-
e.preventDefault();
|
|
12
|
-
// Validación básica
|
|
13
|
-
const newErrors = {};
|
|
14
|
-
if (!formData.email) {
|
|
15
|
-
newErrors.email = "El email es requerido";
|
|
16
|
-
}
|
|
17
|
-
else if (!/\S+@\S+\.\S+/.test(formData.email)) {
|
|
18
|
-
newErrors.email = "El email no es válido";
|
|
19
|
-
}
|
|
20
|
-
if (!formData.password) {
|
|
21
|
-
newErrors.password = "La contraseña es requerida";
|
|
22
|
-
}
|
|
23
|
-
setErrors(newErrors);
|
|
24
|
-
if (Object.keys(newErrors).length === 0) {
|
|
25
|
-
onSubmit?.(formData);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
const handleChange = (field) => (e) => {
|
|
29
|
-
setFormData((prev) => ({ ...prev, [field]: e.target.value }));
|
|
30
|
-
// Limpiar error cuando el usuario empiece a escribir
|
|
31
|
-
if (errors[field]) {
|
|
32
|
-
setErrors((prev) => ({ ...prev, [field]: undefined }));
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
return (_jsxs(Card, { title: "Iniciar Sesi\u00F3n", subtitle: "Ingresa tus credenciales para acceder", className: className, children: [_jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [error && (_jsx("div", { className: "p-3 bg-red-50 border border-red-200 rounded-lg", children: _jsxs("p", { className: "text-sm text-red-600", children: [_jsx("i", { className: "fal fa-exclamation-triangle mr-2" }), error] }) })), _jsx(Input, { label: "Email", type: "email", placeholder: "tu@email.com", icon: "fa-envelope", value: formData.email, onChange: handleChange("email"), error: errors.email, disabled: loading }), _jsx(Input, { label: "Contrase\u00F1a", type: "password", placeholder: "Tu contrase\u00F1a", icon: "fa-lock", value: formData.password, onChange: handleChange("password"), error: errors.password, disabled: loading }), _jsx(Button, { type: "submit", variant: "primary", size: "lg", icon: "fa-sign-in-alt", loading: loading, className: "w-full", children: "Iniciar Sesi\u00F3n" })] }), _jsx("div", { className: "mt-4 text-center", children: _jsxs("p", { className: "text-sm text-gray-600", children: ["\u00BFNo tienes cuenta?", " ", _jsx("a", { href: "#", className: "text-blue-600 hover:text-blue-800 font-medium", children: "Reg\u00EDstrate aqu\u00ED" })] }) })] }));
|
|
36
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState } from "react";
|
|
3
|
-
import { Button, Input, Card } from "../../index";
|
|
4
|
-
export const RegistrationForm = ({ onSubmit, loading = false, error, className = "", }) => {
|
|
5
|
-
const [formData, setFormData] = useState({
|
|
6
|
-
firstName: "",
|
|
7
|
-
lastName: "",
|
|
8
|
-
email: "",
|
|
9
|
-
password: "",
|
|
10
|
-
confirmPassword: "",
|
|
11
|
-
});
|
|
12
|
-
const [errors, setErrors] = useState({});
|
|
13
|
-
const handleSubmit = (e) => {
|
|
14
|
-
e.preventDefault();
|
|
15
|
-
// Validación
|
|
16
|
-
const newErrors = {};
|
|
17
|
-
if (!formData.firstName.trim()) {
|
|
18
|
-
newErrors.firstName = "El nombre es requerido";
|
|
19
|
-
}
|
|
20
|
-
if (!formData.lastName.trim()) {
|
|
21
|
-
newErrors.lastName = "El apellido es requerido";
|
|
22
|
-
}
|
|
23
|
-
if (!formData.email) {
|
|
24
|
-
newErrors.email = "El email es requerido";
|
|
25
|
-
}
|
|
26
|
-
else if (!/\S+@\S+\.\S+/.test(formData.email)) {
|
|
27
|
-
newErrors.email = "El email no es válido";
|
|
28
|
-
}
|
|
29
|
-
if (!formData.password) {
|
|
30
|
-
newErrors.password = "La contraseña es requerida";
|
|
31
|
-
}
|
|
32
|
-
else if (formData.password.length < 6) {
|
|
33
|
-
newErrors.password = "La contraseña debe tener al menos 6 caracteres";
|
|
34
|
-
}
|
|
35
|
-
if (!formData.confirmPassword) {
|
|
36
|
-
newErrors.confirmPassword = "Confirma tu contraseña";
|
|
37
|
-
}
|
|
38
|
-
else if (formData.password !== formData.confirmPassword) {
|
|
39
|
-
newErrors.confirmPassword = "Las contraseñas no coinciden";
|
|
40
|
-
}
|
|
41
|
-
setErrors(newErrors);
|
|
42
|
-
if (Object.keys(newErrors).length === 0) {
|
|
43
|
-
onSubmit?.(formData);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
const handleChange = (field) => (e) => {
|
|
47
|
-
setFormData((prev) => ({ ...prev, [field]: e.target.value }));
|
|
48
|
-
// Limpiar error cuando el usuario empiece a escribir
|
|
49
|
-
if (errors[field]) {
|
|
50
|
-
setErrors((prev) => ({ ...prev, [field]: undefined }));
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
return (_jsxs(Card, { title: "Crear Cuenta", subtitle: "Completa los datos para registrarte", className: className, children: [_jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [error && (_jsx("div", { className: "p-3 bg-red-50 border border-red-200 rounded-lg", children: _jsxs("p", { className: "text-sm text-red-600", children: [_jsx("i", { className: "fal fa-exclamation-triangle mr-2" }), error] }) })), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(Input, { label: "Nombre", placeholder: "Tu nombre", icon: "fa-user", value: formData.firstName, onChange: handleChange("firstName"), error: errors.firstName, disabled: loading }), _jsx(Input, { label: "Apellido", placeholder: "Tu apellido", icon: "fa-user", value: formData.lastName, onChange: handleChange("lastName"), error: errors.lastName, disabled: loading })] }), _jsx(Input, { label: "Email", type: "email", placeholder: "tu@email.com", icon: "fa-envelope", value: formData.email, onChange: handleChange("email"), error: errors.email, disabled: loading }), _jsx(Input, { label: "Contrase\u00F1a", type: "password", placeholder: "M\u00EDnimo 6 caracteres", icon: "fa-lock", value: formData.password, onChange: handleChange("password"), error: errors.password, disabled: loading }), _jsx(Input, { label: "Confirmar Contrase\u00F1a", type: "password", placeholder: "Repite tu contrase\u00F1a", icon: "fa-lock", value: formData.confirmPassword, onChange: handleChange("confirmPassword"), error: errors.confirmPassword, disabled: loading }), _jsx(Button, { type: "submit", variant: "primary", size: "lg", icon: "fa-user-plus", loading: loading, className: "w-full", children: "Crear Cuenta" })] }), _jsx("div", { className: "mt-4 text-center", children: _jsxs("p", { className: "text-sm text-gray-600", children: ["\u00BFYa tienes cuenta?", " ", _jsx("a", { href: "#", className: "text-blue-600 hover:text-blue-800 font-medium", children: "Inicia sesi\u00F3n aqu\u00ED" })] }) })] }));
|
|
54
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { Card } from "../../index";
|
|
4
|
-
export const DashboardLayout = ({ title, subtitle, stats = [], actions, children, className = "", }) => {
|
|
5
|
-
const getChangeColor = (changeType) => {
|
|
6
|
-
switch (changeType) {
|
|
7
|
-
case "positive":
|
|
8
|
-
return "text-green-600";
|
|
9
|
-
case "negative":
|
|
10
|
-
return "text-red-600";
|
|
11
|
-
default:
|
|
12
|
-
return "text-gray-600";
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
const getChangeIcon = (changeType) => {
|
|
16
|
-
switch (changeType) {
|
|
17
|
-
case "positive":
|
|
18
|
-
return "fa-arrow-up";
|
|
19
|
-
case "negative":
|
|
20
|
-
return "fa-arrow-down";
|
|
21
|
-
default:
|
|
22
|
-
return "fa-minus";
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
return (_jsxs("div", { className: `min-h-screen bg-gray-50 ${className}`, children: [_jsx("div", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-6", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-gray-900", children: title }), subtitle && (_jsx("p", { className: "mt-1 text-sm text-gray-600", children: subtitle }))] }), actions && (_jsx("div", { className: "flex items-center space-x-3", children: actions }))] }) }) }), stats.length > 0 && (_jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6", children: _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6", children: stats.map((stat, index) => (_jsx(Card, { variant: "elevated", className: "p-6", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: stat.icon && (_jsx("div", { className: "w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center", children: _jsx("i", { className: `fa ${stat.icon} text-blue-600` }) })) }), _jsxs("div", { className: "ml-4 flex-1", children: [_jsx("p", { className: "text-sm font-medium text-gray-600", children: stat.title }), _jsx("p", { className: "text-2xl font-semibold text-gray-900", children: stat.value }), stat.change && (_jsxs("div", { className: "flex items-center mt-1", children: [_jsx("i", { className: `fa ${getChangeIcon(stat.changeType)} text-xs mr-1 ${getChangeColor(stat.changeType)}` }), _jsx("span", { className: `text-sm ${getChangeColor(stat.changeType)}`, children: stat.change })] }))] })] }) }, index))) }) })), _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6", children: children })] }));
|
|
26
|
-
};
|