@zauru-sdk/components 1.0.111 → 1.0.113

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/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.0.113](https://github.com/intuitiva/zauru-typescript-sdk/compare/v1.0.112...v1.0.113) (2024-09-25)
7
+
8
+ **Note:** Version bump only for package @zauru-sdk/components
9
+
10
+
11
+
12
+
13
+
14
+ ## [1.0.112](https://github.com/intuitiva/zauru-typescript-sdk/compare/v1.0.111...v1.0.112) (2024-09-19)
15
+
16
+ **Note:** Version bump only for package @zauru-sdk/components
17
+
18
+
19
+
20
+
21
+
6
22
  ## [1.0.111](https://github.com/intuitiva/zauru-typescript-sdk/compare/v1.0.110...v1.0.111) (2024-09-19)
7
23
 
8
24
  **Note:** Version bump only for package @zauru-sdk/components
@@ -0,0 +1,5 @@
1
+ export declare const ValidateEmployeeAccess: ({ children, permissionVariableName, showIfNoPermission, }: {
2
+ children: React.ReactNode;
3
+ permissionVariableName: string;
4
+ showIfNoPermission?: boolean | undefined;
5
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare const ErrorLayout: () => import("react/jsx-runtime").JSX.Element;
@@ -1 +1,2 @@
1
1
  export * from "./homeLayout/index.js";
2
+ export * from "./errorLayout/index.js";
@@ -49,13 +49,13 @@ const Button = (props) => {
49
49
  .map((error) => error?.message?.toString())
50
50
  .join(", ")
51
51
  : "";
52
- const buttonContent = ((0, jsx_runtime_1.jsx)("button", { type: type, name: "action", disabled: loading || disabled || (enableFormErrorsValidation && formHasErrors), value: name, onClick: onClickSave, className: `ml-2 ${loading || disabled || (enableFormErrorsValidation && formHasErrors)
53
- ? " bg-opacity-25 "
54
- : ""} ${loading
55
- ? " cursor-progress"
56
- : `${disabled || (enableFormErrorsValidation && formHasErrors)
57
- ? ""
58
- : `hover:${color.bg700}`}`} inline-flex justify-center rounded-md border border-transparent ${color.bg600} py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${color.ring500} focus:ring-offset-2 ${className}`, children: loading ? loadingText : inside }));
52
+ const buttonContent = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", { type: "hidden", name: "action", value: name }), (0, jsx_runtime_1.jsx)("button", { type: type, disabled: loading || disabled || (enableFormErrorsValidation && formHasErrors), onClick: onClickSave, className: `ml-2 ${loading || disabled || (enableFormErrorsValidation && formHasErrors)
53
+ ? " bg-opacity-25 "
54
+ : ""} ${loading
55
+ ? " cursor-progress"
56
+ : `${disabled || (enableFormErrorsValidation && formHasErrors)
57
+ ? ""
58
+ : `hover:${color.bg700}`}`} inline-flex justify-center rounded-md border border-transparent ${color.bg600} py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${color.ring500} focus:ring-offset-2 ${className}`, children: loading ? loadingText : inside })] }));
59
59
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(enableFormErrorsValidation && formHasErrors && errorMessage) ||
60
60
  (enableFormErrorsDescriptions && errorMessage) ? ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-col items-end mb-2", children: (0, jsx_runtime_1.jsx)("div", { className: "p-2 bg-red-100 border border-red-400 text-red-700 rounded-md shadow-sm", children: (0, jsx_runtime_1.jsx)("p", { className: "text-sm", children: errorMessage }) }) })) : null, buttonContent] }));
61
61
  };
@@ -23,9 +23,7 @@ const ReactZodForm = (props) => {
23
23
  submit(event?.target, { method });
24
24
  }
25
25
  };
26
- return ((0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, { ...methods, children: (0, jsx_runtime_1.jsx)(react_1.Form, { onSubmit: onSubmit ? methods.handleSubmit(onSubmit) : undefined,
27
- //onSubmit={methods.handleSubmit(handleSubmit)}
28
- method: method, id: id, children: children }) }));
26
+ return ((0, jsx_runtime_1.jsx)(react_hook_form_1.FormProvider, { ...methods, children: (0, jsx_runtime_1.jsx)(react_1.Form, { onSubmit: methods.handleSubmit(handleSubmit), method: method, id: id, children: children }) }));
29
27
  };
30
28
  exports.ReactZodForm = ReactZodForm;
31
29
  exports.default = exports.ReactZodForm;
@@ -7,7 +7,7 @@ const react_1 = require("react");
7
7
  const index_js_1 = require("../../Skeletons/index.js");
8
8
  const react_hook_form_1 = require("react-hook-form");
9
9
  const SelectField = (props) => {
10
- const { id, name, title, defaultValue, defaultValueMulti = [], helpText, hint, options, onChange, onChangeMulti, isClearable = false, disabled = false, readOnly = false, isMulti = false, loading = false, className = "", onInputChange, required, } = props;
10
+ const { id, name, title, defaultValue, defaultValueMulti = [], helpText, hint, options, onChange, onChangeMulti, isClearable = false, disabled = false, readOnly = false, isMulti = false, loading = false, className = "", onInputChange, required = false, } = props;
11
11
  const [value, setValue] = (0, react_1.useState)(defaultValue || null);
12
12
  const [valueMulti, setValueMulti] = (0, react_1.useState)(defaultValueMulti);
13
13
  const [inputValue, setInputValue] = (0, react_1.useState)(defaultValue?.label || "");
@@ -20,8 +20,13 @@ const SelectField = (props) => {
20
20
  const [isTabPressed, setIsTabPressed] = (0, react_1.useState)(false);
21
21
  const [isEnterPressed, setIsEnterPressed] = (0, react_1.useState)(false);
22
22
  const [isSearching, setIsSearching] = (0, react_1.useState)(false);
23
- const { control, formState: { errors }, setValue: setFormValue, } = (0, react_hook_form_1.useFormContext)() || { formState: {} };
23
+ const { register: tempRegister, formState: { errors }, setValue: setFormValue, } = (0, react_hook_form_1.useFormContext)() || { formState: {} };
24
24
  const error = errors ? errors[props.name ?? "-1"] : undefined;
25
+ const register = tempRegister
26
+ ? tempRegister(props.name ?? "-1", {
27
+ required,
28
+ })
29
+ : undefined; // Solo usar register si está disponible
25
30
  const color = error ? "red" : "gray";
26
31
  const isReadOnly = disabled || readOnly;
27
32
  const bgColor = isReadOnly ? "bg-gray-200" : `bg-${color}-50`;
@@ -40,7 +45,7 @@ const SelectField = (props) => {
40
45
  if (defaultValue) {
41
46
  setValue(defaultValue);
42
47
  setInputValue(defaultValue.label);
43
- setFormValue(name || "", defaultValue);
48
+ setFormValue(name || "", defaultValue.value);
44
49
  }
45
50
  document.addEventListener("mousedown", handleClickOutside);
46
51
  return () => {
@@ -49,6 +54,9 @@ const SelectField = (props) => {
49
54
  }, []);
50
55
  const handleInputChange = (e) => {
51
56
  const newValue = e.target.value;
57
+ if (register) {
58
+ register.onChange(e);
59
+ }
52
60
  setInputValue(newValue);
53
61
  onInputChange && onInputChange(newValue);
54
62
  setIsSearching(true);
@@ -61,13 +69,13 @@ const SelectField = (props) => {
61
69
  : [...valueMulti, option];
62
70
  setValueMulti(newValue);
63
71
  onChangeMulti && onChangeMulti(newValue);
64
- setFormValue(name || "", newValue);
72
+ setFormValue(name || "", newValue.map((v) => v.value));
65
73
  }
66
74
  else {
67
75
  setValue(option);
68
76
  setInputValue(option.label);
69
77
  onChange && onChange(option);
70
- setFormValue(name || "", option);
78
+ setFormValue(name || "", option.value);
71
79
  }
72
80
  setIsOpen(false);
73
81
  };
@@ -80,7 +88,7 @@ const SelectField = (props) => {
80
88
  else {
81
89
  setValue(null);
82
90
  onChange && onChange(null);
83
- setFormValue(name || "", null);
91
+ setFormValue(name || "", "");
84
92
  }
85
93
  setInputValue("");
86
94
  };
@@ -145,10 +153,9 @@ const SelectField = (props) => {
145
153
  }
146
154
  return ((0, jsx_runtime_1.jsxs)("div", { className: `col-span-6 sm:col-span-3 ${className}`, ref: selectRef, children: [title && ((0, jsx_runtime_1.jsxs)("label", { htmlFor: error ? `${name}-error` : `${name}-success`, className: `block text-sm font-medium ${color === "red"
147
155
  ? "text-red-700 dark:text-red-500"
148
- : "text-gray-700 dark:text-gray-500"}`, children: [title, required && (0, jsx_runtime_1.jsx)("span", { className: "text-red-500", children: "*" })] })), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { name: name || "", control: control, rules: { required }, defaultValue: defaultValue || (isMulti ? [] : null), render: ({ field }) => ((0, jsx_runtime_1.jsx)("input", { ...field, type: "text", id: id, value: inputValue, onFocus: () => setIsOpen(true), onBlur: handleBlur, onKeyDown: handleKeyDown, readOnly: isReadOnly, disabled: disabled, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`, placeholder: isMulti ? "Select options..." : "Select an option...", onChange: (e) => {
149
- field.onChange(e);
150
- handleInputChange(e);
151
- }, autoComplete: "off" })) }), isClearable && (value || valueMulti.length > 0) && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: handleClear, className: "absolute inset-y-0 right-0 pr-3 flex items-center", children: "\u00D7" })), isOpen && !isReadOnly && ((0, jsx_runtime_1.jsx)("ul", { ref: optionsRef, className: "absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: filteredOptions.map((option, index) => ((0, jsx_runtime_1.jsx)("li", { className: `cursor-pointer select-none relative py-2 pl-3 pr-9 ${(isMulti
156
+ : "text-gray-700 dark:text-gray-500"}`, children: [title, required && (0, jsx_runtime_1.jsx)("span", { className: "text-red-500", children: "*" })] })), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", id: id, value: inputValue, onFocus: () => setIsOpen(true), onKeyDown: handleKeyDown, readOnly: isReadOnly, disabled: disabled, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`, placeholder: isMulti ? "Select options..." : "Select an option...", autoComplete: "off", onChange: handleInputChange, onBlur: handleBlur, required: required }), (0, jsx_runtime_1.jsx)("input", { type: "hidden", ...(register ?? {}), name: name, value: isMulti
157
+ ? valueMulti.map((v) => v.value).join(",")
158
+ : value?.value || "" }), isClearable && (value || valueMulti.length > 0) && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: handleClear, className: "absolute inset-y-0 right-0 pr-3 flex items-center", children: "\u00D7" })), isOpen && !isReadOnly && ((0, jsx_runtime_1.jsx)("ul", { ref: optionsRef, className: "absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: filteredOptions.map((option, index) => ((0, jsx_runtime_1.jsx)("li", { className: `cursor-pointer select-none relative py-2 pl-3 pr-9 ${(isMulti
152
159
  ? valueMulti.some((v) => v.value === option.value)
153
160
  : value?.value === option.value)
154
161
  ? "text-white bg-indigo-600"
@@ -9,7 +9,7 @@ const TextField = (props) => {
9
9
  const { id, name, defaultValue = "", hidden, type = "text", onChange, onKeyDown, disabled = false, readOnly = false, min, integer = false, stopChangeEvents, style, title, helpText, className, hint, required, } = props;
10
10
  const [showTooltip, setShowTooltip] = (0, react_1.useState)(false);
11
11
  const [value, setValue] = (0, react_1.useState)(defaultValue);
12
- const { register: tempRegister, formState: { errors }, } = (0, react_hook_form_1.useFormContext)() || { formState: {} }; // Obtener el contexto solo si existe
12
+ const { register: tempRegister, formState: { errors }, setValue: setOnFormValue, } = (0, react_hook_form_1.useFormContext)() || { formState: {} }; // Obtener el contexto solo si existe
13
13
  const error = errors ? errors[props.name ?? "-1"] : undefined;
14
14
  const register = tempRegister
15
15
  ? tempRegister(props.name ?? "-1", {
@@ -23,9 +23,11 @@ const TextField = (props) => {
23
23
  const textColor = isReadOnly ? "text-gray-500" : `text-${color}-900`;
24
24
  const borderColor = isReadOnly ? "border-gray-300" : `border-${color}-500`;
25
25
  (0, react_1.useEffect)(() => {
26
+ setOnFormValue(name ?? "-1", defaultValue);
26
27
  setValue(defaultValue);
27
28
  }, [defaultValue]);
28
29
  const handleInputChange = (event) => {
30
+ const newValue = event.target.value;
29
31
  if (register) {
30
32
  register.onChange(event);
31
33
  }
@@ -33,18 +35,8 @@ const TextField = (props) => {
33
35
  event.stopPropagation();
34
36
  event.preventDefault();
35
37
  }
36
- if (integer && type === "number") {
37
- const value = event.target.value;
38
- const isInteger = /^[0-9]*$/.test(value);
39
- if (isInteger || value === "") {
40
- setValue(value);
41
- onChange && onChange(value, event);
42
- }
43
- }
44
- else {
45
- setValue(event.target.value);
46
- onChange && onChange(event.target.value, event);
47
- }
38
+ setValue(newValue);
39
+ onChange && onChange(newValue, event);
48
40
  };
49
41
  const handleKeyDown = (event) => {
50
42
  if (integer && type === "number") {
@@ -63,9 +55,9 @@ const TextField = (props) => {
63
55
  }
64
56
  };
65
57
  if (hidden) {
66
- return ((0, jsx_runtime_1.jsx)("input", { type: "hidden", id: id ?? name, value: value, readOnly: true, hidden: true, ...(register ?? {}), name: name, onChange: handleInputChange }));
58
+ return ((0, jsx_runtime_1.jsx)("input", { type: type, id: id ?? name, value: value, hidden: true, ...(register ?? {}), name: name, onChange: handleInputChange }));
67
59
  }
68
- const inputComponent = ((0, jsx_runtime_1.jsx)("input", { type: type, readOnly: readOnly, disabled: disabled, id: id ?? name, autoComplete: "given-name", value: value, onWheel: (e) => {
60
+ const inputComponent = ((0, jsx_runtime_1.jsx)("input", { type: type, readOnly: isReadOnly, disabled: disabled, id: id ?? name, autoComplete: "off", value: value, onWheel: (e) => {
69
61
  e.currentTarget.blur();
70
62
  }, step: type === "number" ? 0.01 : undefined, onKeyDown: (event) => {
71
63
  handleKeyDown(event);
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValidateEmployeeAccess = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const hooks_1 = require("@zauru-sdk/hooks");
6
+ const react_1 = require("@remix-run/react");
7
+ const ValidateEmployeeAccess = ({ children, permissionVariableName, showIfNoPermission = false, }) => {
8
+ const { data: employee } = (0, hooks_1.useGetEmployeeProfile)();
9
+ const variable_string = (0, hooks_1.useGetSessionAttribute)(permissionVariableName, "sessionVariable");
10
+ const variable = variable_string?.split(",");
11
+ const hasPermission = variable?.includes(employee?.id?.toString() || "-1");
12
+ if (showIfNoPermission && !hasPermission) {
13
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-gray-900 text-white min-h-screen flex flex-col items-center justify-center p-4", children: [(0, jsx_runtime_1.jsx)("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), (0, jsx_runtime_1.jsx)("h1", { className: "text-5xl font-extrabold text-red-500 mb-6", children: "\u00A1Acceso Denegado!" }), (0, jsx_runtime_1.jsx)("div", { className: "w-full max-w-2xl", children: (0, jsx_runtime_1.jsx)("p", { className: "text-2xl text-gray-300 mb-8 text-center", children: "Lo sentimos, no tienes permiso para acceder a esta p\u00E1gina." }) }), (0, jsx_runtime_1.jsx)(react_1.Link, { to: "/", className: "bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105", children: "Regresar al inicio" }), (0, jsx_runtime_1.jsx)("div", { className: "mt-12 text-gray-500", children: (0, jsx_runtime_1.jsx)("p", { children: "Si crees que esto es un error, por favor contacta a soporte." }) })] }));
14
+ }
15
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: hasPermission ? children : null });
16
+ };
17
+ exports.ValidateEmployeeAccess = ValidateEmployeeAccess;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ErrorLayout = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("@remix-run/react");
6
+ const ErrorLayout = () => {
7
+ const error = (0, react_1.useRouteError)();
8
+ return ((0, jsx_runtime_1.jsxs)("html", { lang: "es", className: "bg-gray-900 text-white", children: [(0, jsx_runtime_1.jsxs)("head", { children: [(0, jsx_runtime_1.jsx)("meta", { charSet: "utf-8" }), (0, jsx_runtime_1.jsx)("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), (0, jsx_runtime_1.jsx)("title", { children: "\u00A1Ups! Algo sali\u00F3 mal" }), (0, jsx_runtime_1.jsx)(react_1.Meta, {}), (0, jsx_runtime_1.jsx)(react_1.Links, {})] }), (0, jsx_runtime_1.jsxs)("body", { className: "min-h-screen flex flex-col items-center justify-center p-4", children: [(0, jsx_runtime_1.jsx)("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), (0, jsx_runtime_1.jsx)("h1", { className: "text-5xl font-extrabold text-red-500 mb-6", children: "\u00A1Ups!" }), (0, jsx_runtime_1.jsx)("div", { className: "w-full max-w-2xl", children: (0, jsx_runtime_1.jsx)("p", { className: "text-2xl text-gray-300 mb-8 text-center", children: (0, react_1.isRouteErrorResponse)(error)
9
+ ? `Error ${error.status}: ${error.statusText}`
10
+ : error instanceof Error
11
+ ? error.message
12
+ : "Ha ocurrido un error inesperado" }) }), (0, jsx_runtime_1.jsx)(react_1.Link, { to: "/", className: "bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105", children: "Regresar al inicio" }), (0, jsx_runtime_1.jsx)("div", { className: "mt-12 text-gray-500", children: (0, jsx_runtime_1.jsx)("p", { children: "Si el problema persiste, por favor contacta a soporte." }) }), (0, jsx_runtime_1.jsx)(react_1.Scripts, {})] })] }));
13
+ };
14
+ exports.ErrorLayout = ErrorLayout;
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./homeLayout/index.js"), exports);
18
+ __exportStar(require("./errorLayout/index.js"), exports);
package/dist/cjs/index.js CHANGED
@@ -39,3 +39,4 @@ __exportStar(require("./Tooltip/index.js"), exports);
39
39
  __exportStar(require("./WithTooltip/index.js"), exports);
40
40
  __exportStar(require("./Wizards/index.js"), exports);
41
41
  __exportStar(require("./Zendesk/index.js"), exports);
42
+ __exportStar(require("./HOC/ValidateEmployeeAccess/index.js"), exports);
@@ -46,13 +46,13 @@ export const Button = (props) => {
46
46
  .map((error) => error?.message?.toString())
47
47
  .join(", ")
48
48
  : "";
49
- const buttonContent = (_jsx("button", { type: type, name: "action", disabled: loading || disabled || (enableFormErrorsValidation && formHasErrors), value: name, onClick: onClickSave, className: `ml-2 ${loading || disabled || (enableFormErrorsValidation && formHasErrors)
50
- ? " bg-opacity-25 "
51
- : ""} ${loading
52
- ? " cursor-progress"
53
- : `${disabled || (enableFormErrorsValidation && formHasErrors)
54
- ? ""
55
- : `hover:${color.bg700}`}`} inline-flex justify-center rounded-md border border-transparent ${color.bg600} py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${color.ring500} focus:ring-offset-2 ${className}`, children: loading ? loadingText : inside }));
49
+ const buttonContent = (_jsxs(_Fragment, { children: [_jsx("input", { type: "hidden", name: "action", value: name }), _jsx("button", { type: type, disabled: loading || disabled || (enableFormErrorsValidation && formHasErrors), onClick: onClickSave, className: `ml-2 ${loading || disabled || (enableFormErrorsValidation && formHasErrors)
50
+ ? " bg-opacity-25 "
51
+ : ""} ${loading
52
+ ? " cursor-progress"
53
+ : `${disabled || (enableFormErrorsValidation && formHasErrors)
54
+ ? ""
55
+ : `hover:${color.bg700}`}`} inline-flex justify-center rounded-md border border-transparent ${color.bg600} py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${color.ring500} focus:ring-offset-2 ${className}`, children: loading ? loadingText : inside })] }));
56
56
  return (_jsxs(_Fragment, { children: [(enableFormErrorsValidation && formHasErrors && errorMessage) ||
57
57
  (enableFormErrorsDescriptions && errorMessage) ? (_jsx("div", { className: "flex flex-col items-end mb-2", children: _jsx("div", { className: "p-2 bg-red-100 border border-red-400 text-red-700 rounded-md shadow-sm", children: _jsx("p", { className: "text-sm", children: errorMessage }) }) })) : null, buttonContent] }));
58
58
  };
@@ -20,8 +20,6 @@ export const ReactZodForm = (props) => {
20
20
  submit(event?.target, { method });
21
21
  }
22
22
  };
23
- return (_jsx(FormProvider, { ...methods, children: _jsx(Form, { onSubmit: onSubmit ? methods.handleSubmit(onSubmit) : undefined,
24
- //onSubmit={methods.handleSubmit(handleSubmit)}
25
- method: method, id: id, children: children }) }));
23
+ return (_jsx(FormProvider, { ...methods, children: _jsx(Form, { onSubmit: methods.handleSubmit(handleSubmit), method: method, id: id, children: children }) }));
26
24
  };
27
25
  export default ReactZodForm;
@@ -2,9 +2,9 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import { IdeaIconSVG } from "@zauru-sdk/icons";
3
3
  import { useEffect, useState, useRef } from "react";
4
4
  import { LoadingInputSkeleton } from "../../Skeletons/index.js";
5
- import { useFormContext, Controller } from "react-hook-form";
5
+ import { useFormContext } from "react-hook-form";
6
6
  export const SelectField = (props) => {
7
- const { id, name, title, defaultValue, defaultValueMulti = [], helpText, hint, options, onChange, onChangeMulti, isClearable = false, disabled = false, readOnly = false, isMulti = false, loading = false, className = "", onInputChange, required, } = props;
7
+ const { id, name, title, defaultValue, defaultValueMulti = [], helpText, hint, options, onChange, onChangeMulti, isClearable = false, disabled = false, readOnly = false, isMulti = false, loading = false, className = "", onInputChange, required = false, } = props;
8
8
  const [value, setValue] = useState(defaultValue || null);
9
9
  const [valueMulti, setValueMulti] = useState(defaultValueMulti);
10
10
  const [inputValue, setInputValue] = useState(defaultValue?.label || "");
@@ -17,8 +17,13 @@ export const SelectField = (props) => {
17
17
  const [isTabPressed, setIsTabPressed] = useState(false);
18
18
  const [isEnterPressed, setIsEnterPressed] = useState(false);
19
19
  const [isSearching, setIsSearching] = useState(false);
20
- const { control, formState: { errors }, setValue: setFormValue, } = useFormContext() || { formState: {} };
20
+ const { register: tempRegister, formState: { errors }, setValue: setFormValue, } = useFormContext() || { formState: {} };
21
21
  const error = errors ? errors[props.name ?? "-1"] : undefined;
22
+ const register = tempRegister
23
+ ? tempRegister(props.name ?? "-1", {
24
+ required,
25
+ })
26
+ : undefined; // Solo usar register si está disponible
22
27
  const color = error ? "red" : "gray";
23
28
  const isReadOnly = disabled || readOnly;
24
29
  const bgColor = isReadOnly ? "bg-gray-200" : `bg-${color}-50`;
@@ -37,7 +42,7 @@ export const SelectField = (props) => {
37
42
  if (defaultValue) {
38
43
  setValue(defaultValue);
39
44
  setInputValue(defaultValue.label);
40
- setFormValue(name || "", defaultValue);
45
+ setFormValue(name || "", defaultValue.value);
41
46
  }
42
47
  document.addEventListener("mousedown", handleClickOutside);
43
48
  return () => {
@@ -46,6 +51,9 @@ export const SelectField = (props) => {
46
51
  }, []);
47
52
  const handleInputChange = (e) => {
48
53
  const newValue = e.target.value;
54
+ if (register) {
55
+ register.onChange(e);
56
+ }
49
57
  setInputValue(newValue);
50
58
  onInputChange && onInputChange(newValue);
51
59
  setIsSearching(true);
@@ -58,13 +66,13 @@ export const SelectField = (props) => {
58
66
  : [...valueMulti, option];
59
67
  setValueMulti(newValue);
60
68
  onChangeMulti && onChangeMulti(newValue);
61
- setFormValue(name || "", newValue);
69
+ setFormValue(name || "", newValue.map((v) => v.value));
62
70
  }
63
71
  else {
64
72
  setValue(option);
65
73
  setInputValue(option.label);
66
74
  onChange && onChange(option);
67
- setFormValue(name || "", option);
75
+ setFormValue(name || "", option.value);
68
76
  }
69
77
  setIsOpen(false);
70
78
  };
@@ -77,7 +85,7 @@ export const SelectField = (props) => {
77
85
  else {
78
86
  setValue(null);
79
87
  onChange && onChange(null);
80
- setFormValue(name || "", null);
88
+ setFormValue(name || "", "");
81
89
  }
82
90
  setInputValue("");
83
91
  };
@@ -142,10 +150,9 @@ export const SelectField = (props) => {
142
150
  }
143
151
  return (_jsxs("div", { className: `col-span-6 sm:col-span-3 ${className}`, ref: selectRef, children: [title && (_jsxs("label", { htmlFor: error ? `${name}-error` : `${name}-success`, className: `block text-sm font-medium ${color === "red"
144
152
  ? "text-red-700 dark:text-red-500"
145
- : "text-gray-700 dark:text-gray-500"}`, children: [title, required && _jsx("span", { className: "text-red-500", children: "*" })] })), _jsxs("div", { className: "relative", children: [_jsx(Controller, { name: name || "", control: control, rules: { required }, defaultValue: defaultValue || (isMulti ? [] : null), render: ({ field }) => (_jsx("input", { ...field, type: "text", id: id, value: inputValue, onFocus: () => setIsOpen(true), onBlur: handleBlur, onKeyDown: handleKeyDown, readOnly: isReadOnly, disabled: disabled, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`, placeholder: isMulti ? "Select options..." : "Select an option...", onChange: (e) => {
146
- field.onChange(e);
147
- handleInputChange(e);
148
- }, autoComplete: "off" })) }), isClearable && (value || valueMulti.length > 0) && (_jsx("button", { type: "button", onClick: handleClear, className: "absolute inset-y-0 right-0 pr-3 flex items-center", children: "\u00D7" })), isOpen && !isReadOnly && (_jsx("ul", { ref: optionsRef, className: "absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: filteredOptions.map((option, index) => (_jsx("li", { className: `cursor-pointer select-none relative py-2 pl-3 pr-9 ${(isMulti
153
+ : "text-gray-700 dark:text-gray-500"}`, children: [title, required && _jsx("span", { className: "text-red-500", children: "*" })] })), _jsxs("div", { className: "relative", children: [_jsx("input", { type: "text", id: id, value: inputValue, onFocus: () => setIsOpen(true), onKeyDown: handleKeyDown, readOnly: isReadOnly, disabled: disabled, className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`, placeholder: isMulti ? "Select options..." : "Select an option...", autoComplete: "off", onChange: handleInputChange, onBlur: handleBlur, required: required }), _jsx("input", { type: "hidden", ...(register ?? {}), name: name, value: isMulti
154
+ ? valueMulti.map((v) => v.value).join(",")
155
+ : value?.value || "" }), isClearable && (value || valueMulti.length > 0) && (_jsx("button", { type: "button", onClick: handleClear, className: "absolute inset-y-0 right-0 pr-3 flex items-center", children: "\u00D7" })), isOpen && !isReadOnly && (_jsx("ul", { ref: optionsRef, className: "absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: filteredOptions.map((option, index) => (_jsx("li", { className: `cursor-pointer select-none relative py-2 pl-3 pr-9 ${(isMulti
149
156
  ? valueMulti.some((v) => v.value === option.value)
150
157
  : value?.value === option.value)
151
158
  ? "text-white bg-indigo-600"
@@ -6,7 +6,7 @@ export const TextField = (props) => {
6
6
  const { id, name, defaultValue = "", hidden, type = "text", onChange, onKeyDown, disabled = false, readOnly = false, min, integer = false, stopChangeEvents, style, title, helpText, className, hint, required, } = props;
7
7
  const [showTooltip, setShowTooltip] = useState(false);
8
8
  const [value, setValue] = useState(defaultValue);
9
- const { register: tempRegister, formState: { errors }, } = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
9
+ const { register: tempRegister, formState: { errors }, setValue: setOnFormValue, } = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
10
10
  const error = errors ? errors[props.name ?? "-1"] : undefined;
11
11
  const register = tempRegister
12
12
  ? tempRegister(props.name ?? "-1", {
@@ -20,9 +20,11 @@ export const TextField = (props) => {
20
20
  const textColor = isReadOnly ? "text-gray-500" : `text-${color}-900`;
21
21
  const borderColor = isReadOnly ? "border-gray-300" : `border-${color}-500`;
22
22
  useEffect(() => {
23
+ setOnFormValue(name ?? "-1", defaultValue);
23
24
  setValue(defaultValue);
24
25
  }, [defaultValue]);
25
26
  const handleInputChange = (event) => {
27
+ const newValue = event.target.value;
26
28
  if (register) {
27
29
  register.onChange(event);
28
30
  }
@@ -30,18 +32,8 @@ export const TextField = (props) => {
30
32
  event.stopPropagation();
31
33
  event.preventDefault();
32
34
  }
33
- if (integer && type === "number") {
34
- const value = event.target.value;
35
- const isInteger = /^[0-9]*$/.test(value);
36
- if (isInteger || value === "") {
37
- setValue(value);
38
- onChange && onChange(value, event);
39
- }
40
- }
41
- else {
42
- setValue(event.target.value);
43
- onChange && onChange(event.target.value, event);
44
- }
35
+ setValue(newValue);
36
+ onChange && onChange(newValue, event);
45
37
  };
46
38
  const handleKeyDown = (event) => {
47
39
  if (integer && type === "number") {
@@ -60,9 +52,9 @@ export const TextField = (props) => {
60
52
  }
61
53
  };
62
54
  if (hidden) {
63
- return (_jsx("input", { type: "hidden", id: id ?? name, value: value, readOnly: true, hidden: true, ...(register ?? {}), name: name, onChange: handleInputChange }));
55
+ return (_jsx("input", { type: type, id: id ?? name, value: value, hidden: true, ...(register ?? {}), name: name, onChange: handleInputChange }));
64
56
  }
65
- const inputComponent = (_jsx("input", { type: type, readOnly: readOnly, disabled: disabled, id: id ?? name, autoComplete: "given-name", value: value, onWheel: (e) => {
57
+ const inputComponent = (_jsx("input", { type: type, readOnly: isReadOnly, disabled: disabled, id: id ?? name, autoComplete: "off", value: value, onWheel: (e) => {
66
58
  e.currentTarget.blur();
67
59
  }, step: type === "number" ? 0.01 : undefined, onKeyDown: (event) => {
68
60
  handleKeyDown(event);
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useGetEmployeeProfile, useGetSessionAttribute, } from "@zauru-sdk/hooks";
3
+ import { Link } from "@remix-run/react";
4
+ export const ValidateEmployeeAccess = ({ children, permissionVariableName, showIfNoPermission = false, }) => {
5
+ const { data: employee } = useGetEmployeeProfile();
6
+ const variable_string = useGetSessionAttribute(permissionVariableName, "sessionVariable");
7
+ const variable = variable_string?.split(",");
8
+ const hasPermission = variable?.includes(employee?.id?.toString() || "-1");
9
+ if (showIfNoPermission && !hasPermission) {
10
+ return (_jsxs("div", { className: "bg-gray-900 text-white min-h-screen flex flex-col items-center justify-center p-4", children: [_jsx("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), _jsx("h1", { className: "text-5xl font-extrabold text-red-500 mb-6", children: "\u00A1Acceso Denegado!" }), _jsx("div", { className: "w-full max-w-2xl", children: _jsx("p", { className: "text-2xl text-gray-300 mb-8 text-center", children: "Lo sentimos, no tienes permiso para acceder a esta p\u00E1gina." }) }), _jsx(Link, { to: "/", className: "bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105", children: "Regresar al inicio" }), _jsx("div", { className: "mt-12 text-gray-500", children: _jsx("p", { children: "Si crees que esto es un error, por favor contacta a soporte." }) })] }));
11
+ }
12
+ return _jsx(_Fragment, { children: hasPermission ? children : null });
13
+ };
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { isRouteErrorResponse, Links, Meta, Scripts, useRouteError, Link, } from "@remix-run/react";
3
+ export const ErrorLayout = () => {
4
+ const error = useRouteError();
5
+ return (_jsxs("html", { lang: "es", className: "bg-gray-900 text-white", children: [_jsxs("head", { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: "\u00A1Ups! Algo sali\u00F3 mal" }), _jsx(Meta, {}), _jsx(Links, {})] }), _jsxs("body", { className: "min-h-screen flex flex-col items-center justify-center p-4", children: [_jsx("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), _jsx("h1", { className: "text-5xl font-extrabold text-red-500 mb-6", children: "\u00A1Ups!" }), _jsx("div", { className: "w-full max-w-2xl", children: _jsx("p", { className: "text-2xl text-gray-300 mb-8 text-center", children: isRouteErrorResponse(error)
6
+ ? `Error ${error.status}: ${error.statusText}`
7
+ : error instanceof Error
8
+ ? error.message
9
+ : "Ha ocurrido un error inesperado" }) }), _jsx(Link, { to: "/", className: "bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105", children: "Regresar al inicio" }), _jsx("div", { className: "mt-12 text-gray-500", children: _jsx("p", { children: "Si el problema persiste, por favor contacta a soporte." }) }), _jsx(Scripts, {})] })] }));
10
+ };
@@ -1 +1,2 @@
1
1
  export * from "./homeLayout/index.js";
2
+ export * from "./errorLayout/index.js";
package/dist/esm/index.js CHANGED
@@ -23,3 +23,4 @@ export * from "./Tooltip/index.js";
23
23
  export * from "./WithTooltip/index.js";
24
24
  export * from "./Wizards/index.js";
25
25
  export * from "./Zendesk/index.js";
26
+ export * from "./HOC/ValidateEmployeeAccess/index.js";
package/dist/index.d.ts CHANGED
@@ -23,3 +23,4 @@ export * from "./Tooltip/index.js";
23
23
  export * from "./WithTooltip/index.js";
24
24
  export * from "./Wizards/index.js";
25
25
  export * from "./Zendesk/index.js";
26
+ export * from "./HOC/ValidateEmployeeAccess/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zauru-sdk/components",
3
- "version": "1.0.111",
3
+ "version": "1.0.113",
4
4
  "description": "Componentes reutilizables en las WebApps de Zauru.",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -35,10 +35,10 @@
35
35
  "@reduxjs/toolkit": "^2.2.1",
36
36
  "@remix-run/react": "^2.8.1",
37
37
  "@zauru-sdk/common": "^1.0.110",
38
- "@zauru-sdk/hooks": "^1.0.110",
38
+ "@zauru-sdk/hooks": "^1.0.112",
39
39
  "@zauru-sdk/icons": "^1.0.60",
40
40
  "@zauru-sdk/types": "^1.0.109",
41
- "@zauru-sdk/utils": "^1.0.111",
41
+ "@zauru-sdk/utils": "^1.0.113",
42
42
  "framer-motion": "^11.0.8",
43
43
  "jsonwebtoken": "^9.0.2",
44
44
  "react": "^18.2.0",
@@ -50,5 +50,5 @@
50
50
  "styled-components": "^5.3.5",
51
51
  "zod": "^3.23.8"
52
52
  },
53
- "gitHead": "0ba44e89c12e146c8f0c3bd7a4604e0ccda29b1e"
53
+ "gitHead": "32d6e9f7c23ac5b58be802d23f007f86b4aea904"
54
54
  }
@@ -83,34 +83,35 @@ export const Button = (props: Props) => {
83
83
  : "";
84
84
 
85
85
  const buttonContent = (
86
- <button
87
- type={type}
88
- name="action"
89
- disabled={
90
- loading || disabled || (enableFormErrorsValidation && formHasErrors)
91
- }
92
- value={name}
93
- onClick={onClickSave}
94
- className={`ml-2 ${
95
- loading || disabled || (enableFormErrorsValidation && formHasErrors)
96
- ? " bg-opacity-25 "
97
- : ""
98
- } ${
99
- loading
100
- ? " cursor-progress"
101
- : `${
102
- disabled || (enableFormErrorsValidation && formHasErrors)
103
- ? ""
104
- : `hover:${color.bg700}`
105
- }`
106
- } inline-flex justify-center rounded-md border border-transparent ${
107
- color.bg600
108
- } py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${
109
- color.ring500
110
- } focus:ring-offset-2 ${className}`}
111
- >
112
- {loading ? loadingText : inside}
113
- </button>
86
+ <>
87
+ <input type="hidden" name="action" value={name} />
88
+ <button
89
+ type={type}
90
+ disabled={
91
+ loading || disabled || (enableFormErrorsValidation && formHasErrors)
92
+ }
93
+ onClick={onClickSave}
94
+ className={`ml-2 ${
95
+ loading || disabled || (enableFormErrorsValidation && formHasErrors)
96
+ ? " bg-opacity-25 "
97
+ : ""
98
+ } ${
99
+ loading
100
+ ? " cursor-progress"
101
+ : `${
102
+ disabled || (enableFormErrorsValidation && formHasErrors)
103
+ ? ""
104
+ : `hover:${color.bg700}`
105
+ }`
106
+ } inline-flex justify-center rounded-md border border-transparent ${
107
+ color.bg600
108
+ } py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${
109
+ color.ring500
110
+ } focus:ring-offset-2 ${className}`}
111
+ >
112
+ {loading ? loadingText : inside}
113
+ </button>
114
+ </>
114
115
  );
115
116
 
116
117
  return (
@@ -46,8 +46,7 @@ export const ReactZodForm = (props: Props) => {
46
46
  return (
47
47
  <FormProvider {...methods}>
48
48
  <Form
49
- onSubmit={onSubmit ? methods.handleSubmit(onSubmit) : undefined}
50
- //onSubmit={methods.handleSubmit(handleSubmit)}
49
+ onSubmit={methods.handleSubmit(handleSubmit)}
51
50
  method={method}
52
51
  id={id}
53
52
  >
@@ -2,7 +2,7 @@ import { IdeaIconSVG } from "@zauru-sdk/icons";
2
2
  import { SelectFieldOption } from "@zauru-sdk/types";
3
3
  import React, { useEffect, useState, useRef, KeyboardEvent } from "react";
4
4
  import { LoadingInputSkeleton } from "../../Skeletons/index.js";
5
- import { useFormContext, Controller } from "react-hook-form";
5
+ import { useFormContext } from "react-hook-form";
6
6
 
7
7
  type Props = {
8
8
  id?: string;
@@ -45,7 +45,7 @@ export const SelectField = (props: Props) => {
45
45
  loading = false,
46
46
  className = "",
47
47
  onInputChange,
48
- required,
48
+ required = false,
49
49
  } = props;
50
50
 
51
51
  const [value, setValue] = useState<SelectFieldOption | null>(
@@ -64,11 +64,16 @@ export const SelectField = (props: Props) => {
64
64
  const [isEnterPressed, setIsEnterPressed] = useState<boolean>(false);
65
65
  const [isSearching, setIsSearching] = useState<boolean>(false);
66
66
  const {
67
- control,
67
+ register: tempRegister,
68
68
  formState: { errors },
69
69
  setValue: setFormValue,
70
70
  } = useFormContext() || { formState: {} };
71
71
  const error = errors ? errors[props.name ?? "-1"] : undefined;
72
+ const register = tempRegister
73
+ ? tempRegister(props.name ?? "-1", {
74
+ required,
75
+ })
76
+ : undefined; // Solo usar register si está disponible
72
77
 
73
78
  const color = error ? "red" : "gray";
74
79
  const isReadOnly = disabled || readOnly;
@@ -93,7 +98,7 @@ export const SelectField = (props: Props) => {
93
98
  if (defaultValue) {
94
99
  setValue(defaultValue);
95
100
  setInputValue(defaultValue.label);
96
- setFormValue(name || "", defaultValue);
101
+ setFormValue(name || "", defaultValue.value);
97
102
  }
98
103
 
99
104
  document.addEventListener("mousedown", handleClickOutside);
@@ -104,6 +109,9 @@ export const SelectField = (props: Props) => {
104
109
 
105
110
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
106
111
  const newValue = e.target.value;
112
+ if (register) {
113
+ register.onChange(e);
114
+ }
107
115
  setInputValue(newValue);
108
116
  onInputChange && onInputChange(newValue);
109
117
  setIsSearching(true);
@@ -121,12 +129,15 @@ export const SelectField = (props: Props) => {
121
129
  : [...valueMulti, option];
122
130
  setValueMulti(newValue);
123
131
  onChangeMulti && onChangeMulti(newValue);
124
- setFormValue(name || "", newValue);
132
+ setFormValue(
133
+ name || "",
134
+ newValue.map((v) => v.value)
135
+ );
125
136
  } else {
126
137
  setValue(option);
127
138
  setInputValue(option.label);
128
139
  onChange && onChange(option);
129
- setFormValue(name || "", option);
140
+ setFormValue(name || "", option.value);
130
141
  }
131
142
  setIsOpen(false);
132
143
  };
@@ -139,7 +150,7 @@ export const SelectField = (props: Props) => {
139
150
  } else {
140
151
  setValue(null);
141
152
  onChange && onChange(null);
142
- setFormValue(name || "", null);
153
+ setFormValue(name || "", "");
143
154
  }
144
155
  setInputValue("");
145
156
  };
@@ -245,33 +256,30 @@ export const SelectField = (props: Props) => {
245
256
  </label>
246
257
  )}
247
258
  <div className="relative">
248
- <Controller
249
- name={name || ""}
250
- control={control}
251
- rules={{ required }}
252
- defaultValue={defaultValue || (isMulti ? [] : null)}
253
- render={({ field }) => (
254
- <input
255
- {...field}
256
- type="text"
257
- id={id}
258
- value={inputValue}
259
- onFocus={() => setIsOpen(true)}
260
- onBlur={handleBlur}
261
- onKeyDown={handleKeyDown}
262
- readOnly={isReadOnly}
263
- disabled={disabled}
264
- className={`block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`}
265
- placeholder={
266
- isMulti ? "Select options..." : "Select an option..."
267
- }
268
- onChange={(e) => {
269
- field.onChange(e);
270
- handleInputChange(e);
271
- }}
272
- autoComplete="off"
273
- />
274
- )}
259
+ <input
260
+ type="text"
261
+ id={id}
262
+ value={inputValue}
263
+ onFocus={() => setIsOpen(true)}
264
+ onKeyDown={handleKeyDown}
265
+ readOnly={isReadOnly}
266
+ disabled={disabled}
267
+ className={`block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`}
268
+ placeholder={isMulti ? "Select options..." : "Select an option..."}
269
+ autoComplete="off"
270
+ onChange={handleInputChange}
271
+ onBlur={handleBlur}
272
+ required={required}
273
+ />
274
+ <input
275
+ type="hidden"
276
+ {...(register ?? {})}
277
+ name={name}
278
+ value={
279
+ isMulti
280
+ ? valueMulti.map((v) => v.value).join(",")
281
+ : value?.value || ""
282
+ }
275
283
  />
276
284
  {isClearable && (value || valueMulti.length > 0) && (
277
285
  <button
@@ -53,6 +53,7 @@ export const TextField = (props: Props) => {
53
53
  const {
54
54
  register: tempRegister,
55
55
  formState: { errors },
56
+ setValue: setOnFormValue,
56
57
  } = useFormContext() || { formState: {} }; // Obtener el contexto solo si existe
57
58
  const error = errors ? errors[props.name ?? "-1"] : undefined;
58
59
  const register = tempRegister
@@ -70,10 +71,13 @@ export const TextField = (props: Props) => {
70
71
  const borderColor = isReadOnly ? "border-gray-300" : `border-${color}-500`;
71
72
 
72
73
  useEffect(() => {
74
+ setOnFormValue(name ?? "-1", defaultValue);
73
75
  setValue(defaultValue);
74
76
  }, [defaultValue]);
75
77
 
76
78
  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
79
+ const newValue = event.target.value;
80
+
77
81
  if (register) {
78
82
  register.onChange(event);
79
83
  }
@@ -81,17 +85,9 @@ export const TextField = (props: Props) => {
81
85
  event.stopPropagation();
82
86
  event.preventDefault();
83
87
  }
84
- if (integer && type === "number") {
85
- const value = event.target.value;
86
- const isInteger = /^[0-9]*$/.test(value);
87
- if (isInteger || value === "") {
88
- setValue(value);
89
- onChange && onChange(value, event);
90
- }
91
- } else {
92
- setValue(event.target.value);
93
- onChange && onChange(event.target.value, event);
94
- }
88
+
89
+ setValue(newValue);
90
+ onChange && onChange(newValue, event);
95
91
  };
96
92
 
97
93
  const handleKeyDown = (event: React.KeyboardEvent) => {
@@ -114,11 +110,10 @@ export const TextField = (props: Props) => {
114
110
  if (hidden) {
115
111
  return (
116
112
  <input
117
- type={"hidden"}
113
+ type={type}
118
114
  id={id ?? name}
119
115
  value={value}
120
- readOnly={true}
121
- hidden={true}
116
+ hidden
122
117
  {...(register ?? {})}
123
118
  name={name}
124
119
  onChange={handleInputChange}
@@ -129,10 +124,10 @@ export const TextField = (props: Props) => {
129
124
  const inputComponent = (
130
125
  <input
131
126
  type={type}
132
- readOnly={readOnly}
127
+ readOnly={isReadOnly}
133
128
  disabled={disabled}
134
129
  id={id ?? name}
135
- autoComplete="given-name"
130
+ autoComplete="off"
136
131
  value={value}
137
132
  onWheel={(e: React.WheelEvent<HTMLInputElement>) => {
138
133
  e.currentTarget.blur();
@@ -0,0 +1,51 @@
1
+ import {
2
+ useGetEmployeeProfile,
3
+ useGetSessionAttribute,
4
+ } from "@zauru-sdk/hooks";
5
+ import { Link } from "@remix-run/react";
6
+
7
+ export const ValidateEmployeeAccess = ({
8
+ children,
9
+ permissionVariableName,
10
+ showIfNoPermission = false,
11
+ }: {
12
+ children: React.ReactNode;
13
+ permissionVariableName: string;
14
+ showIfNoPermission?: boolean;
15
+ }) => {
16
+ const { data: employee } = useGetEmployeeProfile();
17
+ const variable_string = useGetSessionAttribute(
18
+ permissionVariableName,
19
+ "sessionVariable"
20
+ );
21
+
22
+ const variable = variable_string?.split(",");
23
+ const hasPermission = variable?.includes(employee?.id?.toString() || "-1");
24
+
25
+ if (showIfNoPermission && !hasPermission) {
26
+ return (
27
+ <div className="bg-gray-900 text-white min-h-screen flex flex-col items-center justify-center p-4">
28
+ <img src="/logo.png" alt="Zauru Logo" className="mb-8 h-20" />
29
+ <h1 className="text-5xl font-extrabold text-red-500 mb-6">
30
+ ¡Acceso Denegado!
31
+ </h1>
32
+ <div className="w-full max-w-2xl">
33
+ <p className="text-2xl text-gray-300 mb-8 text-center">
34
+ Lo sentimos, no tienes permiso para acceder a esta página.
35
+ </p>
36
+ </div>
37
+ <Link
38
+ to="/"
39
+ className="bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105"
40
+ >
41
+ Regresar al inicio
42
+ </Link>
43
+ <div className="mt-12 text-gray-500">
44
+ <p>Si crees que esto es un error, por favor contacta a soporte.</p>
45
+ </div>
46
+ </div>
47
+ );
48
+ }
49
+
50
+ return <>{hasPermission ? children : null}</>;
51
+ };
@@ -0,0 +1,47 @@
1
+ import {
2
+ isRouteErrorResponse,
3
+ Links,
4
+ Meta,
5
+ Scripts,
6
+ useRouteError,
7
+ Link,
8
+ } from "@remix-run/react";
9
+
10
+ export const ErrorLayout = () => {
11
+ const error = useRouteError();
12
+
13
+ return (
14
+ <html lang="es" className="bg-gray-900 text-white">
15
+ <head>
16
+ <meta charSet="utf-8" />
17
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
18
+ <title>¡Ups! Algo salió mal</title>
19
+ <Meta />
20
+ <Links />
21
+ </head>
22
+ <body className="min-h-screen flex flex-col items-center justify-center p-4">
23
+ <img src="/logo.png" alt="Zauru Logo" className="mb-8 h-20" />
24
+ <h1 className="text-5xl font-extrabold text-red-500 mb-6">¡Ups!</h1>
25
+ <div className="w-full max-w-2xl">
26
+ <p className="text-2xl text-gray-300 mb-8 text-center">
27
+ {isRouteErrorResponse(error)
28
+ ? `Error ${error.status}: ${error.statusText}`
29
+ : error instanceof Error
30
+ ? error.message
31
+ : "Ha ocurrido un error inesperado"}
32
+ </p>
33
+ </div>
34
+ <Link
35
+ to="/"
36
+ className="bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105"
37
+ >
38
+ Regresar al inicio
39
+ </Link>
40
+ <div className="mt-12 text-gray-500">
41
+ <p>Si el problema persiste, por favor contacta a soporte.</p>
42
+ </div>
43
+ <Scripts />
44
+ </body>
45
+ </html>
46
+ );
47
+ };
@@ -1 +1,2 @@
1
1
  export * from "./homeLayout/index.js";
2
+ export * from "./errorLayout/index.js";
package/src/index.ts CHANGED
@@ -23,3 +23,4 @@ export * from "./Tooltip/index.js";
23
23
  export * from "./WithTooltip/index.js";
24
24
  export * from "./Wizards/index.js";
25
25
  export * from "./Zendesk/index.js";
26
+ export * from "./HOC/ValidateEmployeeAccess/index.js";