@juantroconisf/lib 1.9.0 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,2 +1,44 @@
1
+ import * as react from 'react';
2
+ import { ChangeEvent } from 'react';
1
3
 
2
- export { }
4
+ type ValidatorFunction<T, U> = (val: T, ...args: U[]) => boolean;
5
+ interface Validator<T, U = any> {
6
+ validate: ValidatorFunction<T, U>;
7
+ msg: string;
8
+ }
9
+ interface ValidatorTypes {
10
+ required: Validator<string | number, boolean>;
11
+ min: Validator<number, number>;
12
+ max: Validator<number, number>;
13
+ minLength: Validator<string, number>;
14
+ maxLength: Validator<string, number>;
15
+ pattern: Validator<string, RegExp>;
16
+ equal: Validator<string, string>;
17
+ numberIsEqual: Validator<number, number>;
18
+ email: Validator<string, boolean>;
19
+ password: Validator<string, boolean>;
20
+ }
21
+ type ValidatorParams = {
22
+ [K in keyof ValidatorTypes]: ValidatorTypes[K] extends Validator<any, infer U> ? U : never;
23
+ };
24
+ type ValidatorErrorMessage = {
25
+ [K in keyof ValidatorTypes]: string;
26
+ };
27
+
28
+ declare function useFormChange<InitialObj extends object>(initialObj: InitialObj): {
29
+ onChange: ({ target: { id, value }, }: ChangeEvent<HTMLInputElement>) => void;
30
+ onBlur: ({ target: { id } }: ChangeEvent<HTMLInputElement>) => void;
31
+ state: InitialObj;
32
+ setState: react.Dispatch<react.SetStateAction<InitialObj>>;
33
+ register: <K extends keyof InitialObj>(id: K, validations: ValidatorParams, errorMessages: ValidatorErrorMessage) => {
34
+ id: K;
35
+ onChange: ({ target: { id, value }, }: ChangeEvent<HTMLInputElement>) => void;
36
+ onBlur: ({ target: { id } }: ChangeEvent<HTMLInputElement>) => void;
37
+ value: any;
38
+ };
39
+ hasInvalidValues: () => boolean;
40
+ touched: InitialObj;
41
+ resetForm: () => void;
42
+ };
43
+
44
+ export { useFormChange };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,44 @@
1
+ import * as react from 'react';
2
+ import { ChangeEvent } from 'react';
1
3
 
2
- export { }
4
+ type ValidatorFunction<T, U> = (val: T, ...args: U[]) => boolean;
5
+ interface Validator<T, U = any> {
6
+ validate: ValidatorFunction<T, U>;
7
+ msg: string;
8
+ }
9
+ interface ValidatorTypes {
10
+ required: Validator<string | number, boolean>;
11
+ min: Validator<number, number>;
12
+ max: Validator<number, number>;
13
+ minLength: Validator<string, number>;
14
+ maxLength: Validator<string, number>;
15
+ pattern: Validator<string, RegExp>;
16
+ equal: Validator<string, string>;
17
+ numberIsEqual: Validator<number, number>;
18
+ email: Validator<string, boolean>;
19
+ password: Validator<string, boolean>;
20
+ }
21
+ type ValidatorParams = {
22
+ [K in keyof ValidatorTypes]: ValidatorTypes[K] extends Validator<any, infer U> ? U : never;
23
+ };
24
+ type ValidatorErrorMessage = {
25
+ [K in keyof ValidatorTypes]: string;
26
+ };
27
+
28
+ declare function useFormChange<InitialObj extends object>(initialObj: InitialObj): {
29
+ onChange: ({ target: { id, value }, }: ChangeEvent<HTMLInputElement>) => void;
30
+ onBlur: ({ target: { id } }: ChangeEvent<HTMLInputElement>) => void;
31
+ state: InitialObj;
32
+ setState: react.Dispatch<react.SetStateAction<InitialObj>>;
33
+ register: <K extends keyof InitialObj>(id: K, validations: ValidatorParams, errorMessages: ValidatorErrorMessage) => {
34
+ id: K;
35
+ onChange: ({ target: { id, value }, }: ChangeEvent<HTMLInputElement>) => void;
36
+ onBlur: ({ target: { id } }: ChangeEvent<HTMLInputElement>) => void;
37
+ value: any;
38
+ };
39
+ hasInvalidValues: () => boolean;
40
+ touched: InitialObj;
41
+ resetForm: () => void;
42
+ };
43
+
44
+ export { useFormChange };
package/dist/index.js CHANGED
@@ -2,6 +2,10 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
5
9
  var __copyProps = (to, from, except, desc) => {
6
10
  if (from && typeof from === "object" || typeof from === "function") {
7
11
  for (let key of __getOwnPropNames(from))
@@ -14,7 +18,196 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
14
18
 
15
19
  // src/index.ts
16
20
  var src_exports = {};
21
+ __export(src_exports, {
22
+ useFormChange: () => useFormChange
23
+ });
17
24
  module.exports = __toCommonJS(src_exports);
18
25
 
19
26
  // src/hooks/useFormChange.tsx
20
27
  var import_react = require("react");
28
+
29
+ // src/utils.ts
30
+ var getNestedValueByKey = (obj, nestedKey) => nestedKey.split(".").reduce((acc, key) => acc[key], obj);
31
+ function handleNestedChange({
32
+ state,
33
+ id,
34
+ value
35
+ }) {
36
+ const propertyDepth = id.split("."), newValues = state;
37
+ let current = newValues;
38
+ for (let i = 0; i < propertyDepth.length - 1; i++) {
39
+ const key = propertyDepth[i];
40
+ current[key] = { ...current[key] };
41
+ current = current[key];
42
+ }
43
+ current[propertyDepth[propertyDepth.length - 1]] = value;
44
+ return { ...newValues };
45
+ }
46
+ var allToValue = (obj, value) => Object.keys(obj).reduce((acc, key) => {
47
+ const current = obj[key];
48
+ return {
49
+ ...acc,
50
+ [key]: typeof current === "object" ? allToValue(current, value) : value
51
+ };
52
+ }, {});
53
+
54
+ // lang/en.json
55
+ var en_default = { BIRTH_DATE: "Birth date", DAY: "Day", DAY_PLACEHOLDER: "Choose a day", MONTH: "Month", MONTH_PLACEHOLDER: "Choose a month", YEAR: "Year", YEAR_PLACEHOLDER: "Choose a year", PRICING: "Pricing", PRICING_TABLE: "Pricing table", OUR_PRICING_PLAN: "Our pricing plan", PRICING_DESCRIPTION: "Level up your experience. Discover the plan that unlocks the features you need.", VALUE_STORAGE: "{{value}} storage", GOOGLE_CALENDAR_SYNC: "Google Calendar Sync", INTERNAL_REMINDERS: "Internal reminders", WHATSAPP_AUTOMATED_REMINDERS: "WhatsApp Automated Reminders", PROFESSIONAL: "Professional", PROFESSIONAL_PLAN_DESCRIPTION: "For single doctors looking to level up their practice", DIGITAL_PRESCRIPTIONS: "Digital prescriptions", DICOM_VIEWER: "DICOM Viewer", VERIFIED_MEDICAL_CREDENTIALS: "Verified medical credentials", PATIENT_SELF_MANAGEMENT: "Patient self management", BUY_NOW: "Buy now", ORGANIZATION: "Organization", ORGANIZATION_PLAN_DESCRIPTION: "For organizations with multiple users looking to share information", UP_TO_VALUE_STORAGE: "Up to {{value}} storage", CONFIGURABLE_USER_PERMISSIONS: "Configurable user permissions", CALCULATE_PRICING: "Calculate pricing", DOCTORS: "Doctors", ASSISTANTS: "Assistants", BASIC: "Basic", BASIC_PLAN_DESCRIPTION: "For starters in the medical industry", USER: "User", TYPE_A_VALUE: "Type a value", STORAGE: "Storage", PASSWORD: "Password", PASSWORD_PLACEHOLDER: "Enter your password", REQUIRED: "Required", TOO_SHORT: "Too short", TOO_LONG: "Too long", VALUE_LOW: "Value is too low", VALUE_HIGH: "Value is too high", PATTERN_INVALID: "Pattern is not valid", INVALID_EMAIL: "Invalid email", SHOW_PASSWORD: "Show password", HIDE_PASSWORD: "Hide password", GROUP_PRICING_CALCULATOR: "Group Pricing Calculator", VERIFIED_ACCOUNT: "Verified account", VERIFIED_ACCOUNT_TEXT: "This account has been verified by Clinikos, as well as its affiliations with the following institutions", PHONE_NUMBER: "Phone number", PHONE_NUMBER_PLACEHOLDER: "Enter your phone number", SEND_MESSAGE: "Send message", BOOK_MEETING: "Book meeting", SIGN_UP: "Sign up", INVALID_PASSWORD: "Your password doesn't meet the security criteria.", NOT_EQUAL: "Values are not equal", GENDER: "Gender", FEMALE: "Female", MALE: "Male", CLOSE: "Close", MANDATORY_FIELDS_WARNING: "", INVALID_FIELDS_WARNING: "", COUNTRY: "Country", COUNTRY_PLACEHOLDER: "Select a country", STATE: "State", STATE_PLACEHOLDER: "Select a state", CITY: "City", CITY_PLACEHOLDER: "Select a city", TIMEZONE: "Timezone", TIMEZONE_PLACEHOLDER: "Selecte a timezone", NAME: "Name", OK: "Ok", PAGE_NOT_FOUND: "Page not found", PAGE_NOT_FOUND_DESCRIPTION: "The link you clicked may be broken or the page may have been removed or renamed", TODAY: "Today", WEEK: "Week", CALENDAR: "Calendar", EVENT: "Event", NO_INFORMATION: "No information", SYNC_GOOGLE_CALENDAR: "Sync Google Calendar", NO_RESULTS: "No results were found", GOOGLE_MEET: "Google Meet", LONG_TIME_AGO: "Long time ago", TOMORROW: "Tomorrow", CHOOSE_PLAN: "Choose a plan", CHOOSE_PLAN_DESCRIPTION: "Choose a plan that fits your needs!", PRIVACY_POLICY: "", OPTIONAL: "Optional", RESULTS: "Results", LOCATION: "Location", ADDRESS: "Address", ADDRESS_PLACEHOLDER: "Enter your address", COPY_TO_CLIPBOARD: "Copy to clipboard", ACTIONS: "Actions", MIN: "Minimum", MAX: "Maximum", DUE_DATE: "Due date", QUICK_SEARCH: "Quick search", MONTHLY: "Monthly", WEEKLY: "Weekly", GOOGLE_MAPS_LINK: "Google maps link", MINUTE: "Minute", MINUTES: "Minutes", HOUR: "Hour", HOURS: "Hours", VE_ID: "Identity card", ACCOUNT_VERIFIED_BY_CLINIKOS: "This account has been verified by Clinikos, as well as its affiliations with the following institutions", INBOX: "Inbox", ACCEPTED: "Accepted", DECLINED: "Declined", NEEDS_ACTION: "Needs action", OVERDUE: "Overdue", FILTER_BY: "Filter by", REFRESH: "Refresh", LOADING: "Loading", MINUTE_LEFT: "One minute left", VALUE_MINUTES_LEFT: "{{value}} minutes left", PLAY: "Play", PAUSE: "Pause", STOP: "Stop", LOAD_MORE: "Load more", BILLING: "Billing", DOCTOR: "Doctor", ASSISTANT: "Assistant", NUMBER_OF_DOCTORS: "Number of Doctors", NUMBER_OF_ASSISTANTS: "Number of Assistants", EACH_DOCTOR: "Each doctor", EACH_ASSISTANT: "Each assistant", ROLE: "Role", PAYMENT_METHODS: "Payment methods", UPGRADE: "Upgrade", TOTAL: "Total", BUY: "Buy", TYPE: "Type", RECURRENT: "Recurrent", ACCEPT: "Accept", DECLINE: "Decline", PREFERENCES: "Preferences", BOOKING: "Booking", PATTERN_NOT_VALID: "Pattern is not valid" };
56
+
57
+ // lang/es.json
58
+ var es_default = { BIRTH_DATE: "Fecha de nacimiento", DAY: "D\xEDa", DAY_PLACEHOLDER: "Elige un d\xEDa", MONTH: "Mes", MONTH_PLACEHOLDER: "Elige un mes", YEAR: "A\xF1o", YEAR_PLACEHOLDER: "Elige un a\xF1o", PRICING: "Precio", PRICING_TABLE: "Tabla de precios", OUR_PRICING_PLAN: "Nuestros precios", PRICING_DESCRIPTION: "Mejora tu experiencia. Descubre el plan que desbloquea las funciones que necesitas.", VALUE_STORAGE: "{{value}} almacenamiento", GOOGLE_CALENDAR_SYNC: "Google Calenar Sync", INTERNAL_REMINDERS: "Recordatorios internos", WHATSAPP_AUTOMATED_REMINDERS: "Recordatorios automatizados de WhatsApp", PROFESSIONAL: "Profesional", PROFESSIONAL_PLAN_DESCRIPTION: "Para doctores individuales que buscan elevar sus pr\xE1cticas", DIGITAL_PRESCRIPTIONS: "Recipes digitales", DICOM_VIEWER: "Visualizador DICOM", VERIFIED_MEDICAL_CREDENTIALS: "Credenciales m\xE9dicas verificadas", PATIENT_SELF_MANAGEMENT: "Auto gesti\xF3n para pacientes", BUY_NOW: "Comprar ahora", ORGANIZATION: "Organizaci\xF3n", ORGANIZATION_PLAN_DESCRIPTION: "Para organizaciones con m\xFAltiples usuarios que buscan compartir informaci\xF3n", UP_TO_VALUE_STORAGE: "Hasta {{value}} de almacenamiento", CONFIGURABLE_USER_PERMISSIONS: "Permisolog\xEDa configurable para usuarios", CALCULATE_PRICING: "Calcular precio", DOCTORS: "Doctores", ASSISTANTS: "Asistentes", BASIC: "B\xE1sico", BASIC_PLAN_DESCRIPTION: "Para iniciar en la industria m\xE9dica", USER: "Usuario", TYPE_A_VALUE: "Ingresa un valor", STORAGE: "Almacenamiento", PASSWORD: "Contrase\xF1a", PASSWORD_PLACEHOLDER: "Ingresa tu contrase\xF1a", REQUIRED: "Requerido", TOO_SHORT: "Demasiado corto", TOO_LONG: "Demasiado largo", VALUE_LOW: "El valor es muy bajo", VALUE_HIGH: "El valor es muy alto", PATTERN_INVALID: "El patr\xF3n no es v\xE1lido", INVALID_EMAIL: "Correo inv\xE1lido", SHOW_PASSWORD: "Mostrar contrase\xF1a", HIDE_PASSWORD: "Esconder contrase\xF1a", GROUP_PRICING_CALCULATOR: "Calculadora de precios grupal", VERIFIED_ACCOUNT: "Cuenta verificada", VERIFIED_ACCOUNT_TEXT: "Esta cuenta ha sido verificada por Clinikos, as\xED como sus afiliaciones con las siguientes instituciones", PHONE_NUMBER: "N\xFAmero de tel\xE9fono", PHONE_NUMBER_PLACEHOLDER: "Ingrese su n\xFAmero de tel\xE9fono", SEND_MESSAGE: "Enviar mensaje", BOOK_MEETING: "Agendar cita", SIGN_UP: "Reg\xEDstrate", INVALID_PASSWORD: "Tu contrase\xF1a no cumple con los requisitos de seguridad.", NOT_EQUAL: "Los valores no son iguales", GENDER: "G\xE9nero", FEMALE: "Femenino", MALE: "Masculino", CLOSE: "Cerrar", MANDATORY_FIELDS_WARNING: "", INVALID_FIELDS_WARNING: "", COUNTRY: "Pa\xEDs", COUNTRY_PLACEHOLDER: "Selecciona un pa\xEDs", STATE: "Estado", STATE_PLACEHOLDER: "Selecciona un estado", CITY: "Ciudad", CITY_PLACEHOLDER: "Selecciona una ciudad", TIMEZONE: "Zona horaria", TIMEZONE_PLACEHOLDER: "Selecciona una zora horaria", NAME: "Nombre", OK: "Ok", PAGE_NOT_FOUND: "P\xE1gina no encontrada", PAGE_NOT_FOUND_DESCRIPTION: "El enlace en el que hiciste click puede que est\xE9 roto o la p\xE1gina puede haber sido eliminada o renombrada", TODAY: "Hoy", WEEK: "Semana", CALENDAR: "Calendario", EVENT: "Evento", NO_INFORMATION: "Sin informaci\xF3n", SYNC_GOOGLE_CALENDAR: "Vincular Calendario de Google", NO_RESULTS: "No se encontraron resultados", GOOGLE_MEET: "Google Meet", LONG_TIME_AGO: "Hace mucho tiempo", TOMORROW: "Ma\xF1ana", CHOOSE_PLAN: "Elige un plan", CHOOSE_PLAN_DESCRIPTION: "\xA1Elige el plan que se ajuste a tus necesidades!", PRIVACY_POLICY: "", OPTIONAL: "Opcional", RESULTS: "Resultados", LOCATION: "Ubicaci\xF3n", ADDRESS: "Direcci\xF3n", ADDRESS_PLACEHOLDER: "Ingresa tu direcci\xF3n", COPY_TO_CLIPBOARD: "Copiar al portapapeles", ACTIONS: "Acciones", MIN: "M\xEDnimo", MAX: "M\xE1ximo", DUE_DATE: "Fecha l\xEDmite", QUICK_SEARCH: "B\xFAsqueda r\xE1pida", MONTHLY: "Mensual", WEEKLY: "Semanal", GOOGLE_MAPS_LINK: "Link de Google Maps", MINUTE: "Minuto", MINUTES: "Minutos", HOUR: "Hora", HOURS: "Horas", VE_ID: "C\xE9dula de Identidad", ACCOUNT_VERIFIED_BY_CLINIKOS: "Esta cuenta ha sido verificada por Clinikos, as\xED como sus afiliaciones con las siguientes instituciones", INBOX: "Bandeja de entrada", ACCEPTED: "Aceptado", DECLINED: "Declinado", NEEDS_ACTION: "Necesita acci\xF3n", OVERDUE: "Atrasado", FILTER_BY: "Filtrar por", REFRESH: "Refrescar", LOADING: "Cargando", MINUTE_LEFT: "Un minuto restante", VALUE_MINUTES_LEFT: "{{value}} minutos restantes", PLAY: "Reproducir", PAUSE: "Pausar", STOP: "Detener", LOAD_MORE: "Cargar m\xE1s", BILLING: "Facturaci\xF3n", DOCTOR: "Doctor", ASSISTANT: "Asistente", NUMBER_OF_DOCTORS: "N\xFAmero de Doctores", NUMBER_OF_ASSISTANTS: "N\xFAmero de Asistentes", EACH_DOCTOR: "Cada doctor", EACH_ASSISTANT: "Cada asistente", ROLE: "Rol", PAYMENT_METHODS: "M\xE9todos de pago", UPGRADE: "Mejorar", TOTAL: "Total", BUY: "Comprar", TYPE: "Tipo", RECURRENT: "Recurrente", ACCEPT: "Aceptar", DECLINE: "Declinar", PREFERENCES: "Preferencias", BOOKING: "Agendar cita", PATTERN_NOT_VALID: "El patr\xF3n no es v\xE1lido" };
59
+
60
+ // types/errors.ts
61
+ var regex = {
62
+ email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
63
+ password: /^(?!.*\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}[\]|:;"'<>,.?/_₹]).{8,24}$/
64
+ };
65
+ var errors = {
66
+ required: {
67
+ validate: (val) => Boolean(val),
68
+ msg: "REQUIRED"
69
+ },
70
+ min: {
71
+ validate: (val, min) => val >= min,
72
+ msg: "VALUE_LOW"
73
+ },
74
+ max: {
75
+ validate: (val, max) => val <= max,
76
+ msg: "VALUE_HIGH"
77
+ },
78
+ minLength: {
79
+ validate: (val = "", min) => val.length >= min,
80
+ msg: "TOO_SHORT"
81
+ },
82
+ maxLength: {
83
+ validate: (val = "", max) => val.length <= max,
84
+ msg: "TOO_LONG"
85
+ },
86
+ pattern: {
87
+ validate: (val, pattern) => new RegExp(pattern).test(val),
88
+ msg: "PATTERN_INVALID"
89
+ },
90
+ equal: {
91
+ validate: (val, comparison) => val === comparison,
92
+ msg: "NOT_EQUAL"
93
+ },
94
+ numberIsEqual: {
95
+ validate: (val, comparison) => val === comparison,
96
+ msg: "NOT_EQUAL"
97
+ },
98
+ email: {
99
+ validate: (val) => new RegExp(regex.email).test(val),
100
+ msg: "INVALID_EMAIL"
101
+ },
102
+ password: {
103
+ validate: (val) => new RegExp(regex.password).test(val),
104
+ msg: "INVALID_PASSWORD"
105
+ }
106
+ };
107
+ var NextUIError = class {
108
+ isInvalid;
109
+ errorMessage;
110
+ constructor(bool = false, msg = "") {
111
+ this.isInvalid = bool;
112
+ this.errorMessage = bool ? msg : "";
113
+ }
114
+ };
115
+ var nxError = (bool, msg) => new NextUIError(bool, msg);
116
+
117
+ // types/types.ts
118
+ var langMap = {
119
+ en: en_default,
120
+ es: es_default
121
+ };
122
+
123
+ // src/hooks/useComponentLang.tsx
124
+ var cookieName = "LOCALE";
125
+ var getClientCookie = () => {
126
+ const value = "; " + document.cookie, decodedValue = decodeURIComponent(value), parts = decodedValue.split("; " + cookieName + "=");
127
+ if (parts.length === 2) return parts.pop()?.split(";").shift();
128
+ };
129
+ var getServerCookie = () => {
130
+ try {
131
+ const { cookies } = require("next/headers");
132
+ return cookies().get(cookieName)?.value;
133
+ } catch {
134
+ return "es";
135
+ }
136
+ };
137
+ function useComponentLanguage() {
138
+ const isServer = typeof window === "undefined", locale = (isServer ? getServerCookie() : getClientCookie()) || "en";
139
+ return {
140
+ locale,
141
+ lang: langMap[locale]
142
+ };
143
+ }
144
+
145
+ // src/hooks/useValidation.tsx
146
+ function useValidation() {
147
+ const { lang } = useComponentLanguage();
148
+ const getValidation = (value, isTouched, types, errorMessages) => {
149
+ const items = Object.entries(types), isRequired = items.map(([key]) => key).includes("required");
150
+ const validations = items.map(([name, opts]) => {
151
+ const { validate, msg: msg2 } = errors[name];
152
+ return {
153
+ isValid: validate(value, opts),
154
+ msg: errorMessages?.[name] || lang[msg2]
155
+ };
156
+ }), { isValid, msg } = validations.find(({ isValid: isValid2 }) => !isValid2) || {
157
+ isValid: true,
158
+ msg: ""
159
+ };
160
+ return {
161
+ isValid,
162
+ validationProps: isRequired && !isTouched ? nxError() : nxError(!isValid, msg)
163
+ };
164
+ };
165
+ return { getValidation };
166
+ }
167
+
168
+ // src/hooks/useFormChange.tsx
169
+ function useFormChange(initialObj) {
170
+ const [state, setState] = (0, import_react.useState)(initialObj), [touched, setTouched] = (0, import_react.useState)(allToValue(initialObj, false)), { getValidation } = useValidation();
171
+ let errors2 = allToValue(initialObj, false);
172
+ const onChange = ({
173
+ target: { id, value }
174
+ }) => setState(handleNestedChange({ state, id, value })), onBlur = ({ target: { id } }) => setTouched(handleNestedChange({ state: touched, id, value: true })), resetForm = () => {
175
+ setTouched(allToValue(initialObj, false));
176
+ setState(initialObj);
177
+ };
178
+ function register(id, validations, errorMessages) {
179
+ const [value, isTouched] = [state, touched].map(
180
+ (obj) => getNestedValueByKey(obj, id)
181
+ ), hasValidations = validations !== void 0, { isValid = false, validationProps = {} } = hasValidations ? getValidation(value, isTouched, validations, errorMessages) : {};
182
+ errors2 = handleNestedChange({
183
+ state: errors2,
184
+ id,
185
+ value: hasValidations ? !isValid : false
186
+ });
187
+ return {
188
+ id,
189
+ onChange,
190
+ onBlur,
191
+ value,
192
+ ...validationProps
193
+ };
194
+ }
195
+ const hasInvalidValues = () => {
196
+ setTouched(allToValue(touched, true));
197
+ return JSON.stringify(errors2).includes(":true");
198
+ };
199
+ return {
200
+ onChange,
201
+ onBlur,
202
+ state,
203
+ setState,
204
+ register,
205
+ hasInvalidValues,
206
+ touched,
207
+ resetForm
208
+ };
209
+ }
210
+ // Annotate the CommonJS export names for ESM import in node:
211
+ 0 && (module.exports = {
212
+ useFormChange
213
+ });
package/dist/index.mjs CHANGED
@@ -1,2 +1,194 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
1
8
  // src/hooks/useFormChange.tsx
2
9
  import { useState } from "react";
10
+
11
+ // src/utils.ts
12
+ var getNestedValueByKey = (obj, nestedKey) => nestedKey.split(".").reduce((acc, key) => acc[key], obj);
13
+ function handleNestedChange({
14
+ state,
15
+ id,
16
+ value
17
+ }) {
18
+ const propertyDepth = id.split("."), newValues = state;
19
+ let current = newValues;
20
+ for (let i = 0; i < propertyDepth.length - 1; i++) {
21
+ const key = propertyDepth[i];
22
+ current[key] = { ...current[key] };
23
+ current = current[key];
24
+ }
25
+ current[propertyDepth[propertyDepth.length - 1]] = value;
26
+ return { ...newValues };
27
+ }
28
+ var allToValue = (obj, value) => Object.keys(obj).reduce((acc, key) => {
29
+ const current = obj[key];
30
+ return {
31
+ ...acc,
32
+ [key]: typeof current === "object" ? allToValue(current, value) : value
33
+ };
34
+ }, {});
35
+
36
+ // lang/en.json
37
+ var en_default = { BIRTH_DATE: "Birth date", DAY: "Day", DAY_PLACEHOLDER: "Choose a day", MONTH: "Month", MONTH_PLACEHOLDER: "Choose a month", YEAR: "Year", YEAR_PLACEHOLDER: "Choose a year", PRICING: "Pricing", PRICING_TABLE: "Pricing table", OUR_PRICING_PLAN: "Our pricing plan", PRICING_DESCRIPTION: "Level up your experience. Discover the plan that unlocks the features you need.", VALUE_STORAGE: "{{value}} storage", GOOGLE_CALENDAR_SYNC: "Google Calendar Sync", INTERNAL_REMINDERS: "Internal reminders", WHATSAPP_AUTOMATED_REMINDERS: "WhatsApp Automated Reminders", PROFESSIONAL: "Professional", PROFESSIONAL_PLAN_DESCRIPTION: "For single doctors looking to level up their practice", DIGITAL_PRESCRIPTIONS: "Digital prescriptions", DICOM_VIEWER: "DICOM Viewer", VERIFIED_MEDICAL_CREDENTIALS: "Verified medical credentials", PATIENT_SELF_MANAGEMENT: "Patient self management", BUY_NOW: "Buy now", ORGANIZATION: "Organization", ORGANIZATION_PLAN_DESCRIPTION: "For organizations with multiple users looking to share information", UP_TO_VALUE_STORAGE: "Up to {{value}} storage", CONFIGURABLE_USER_PERMISSIONS: "Configurable user permissions", CALCULATE_PRICING: "Calculate pricing", DOCTORS: "Doctors", ASSISTANTS: "Assistants", BASIC: "Basic", BASIC_PLAN_DESCRIPTION: "For starters in the medical industry", USER: "User", TYPE_A_VALUE: "Type a value", STORAGE: "Storage", PASSWORD: "Password", PASSWORD_PLACEHOLDER: "Enter your password", REQUIRED: "Required", TOO_SHORT: "Too short", TOO_LONG: "Too long", VALUE_LOW: "Value is too low", VALUE_HIGH: "Value is too high", PATTERN_INVALID: "Pattern is not valid", INVALID_EMAIL: "Invalid email", SHOW_PASSWORD: "Show password", HIDE_PASSWORD: "Hide password", GROUP_PRICING_CALCULATOR: "Group Pricing Calculator", VERIFIED_ACCOUNT: "Verified account", VERIFIED_ACCOUNT_TEXT: "This account has been verified by Clinikos, as well as its affiliations with the following institutions", PHONE_NUMBER: "Phone number", PHONE_NUMBER_PLACEHOLDER: "Enter your phone number", SEND_MESSAGE: "Send message", BOOK_MEETING: "Book meeting", SIGN_UP: "Sign up", INVALID_PASSWORD: "Your password doesn't meet the security criteria.", NOT_EQUAL: "Values are not equal", GENDER: "Gender", FEMALE: "Female", MALE: "Male", CLOSE: "Close", MANDATORY_FIELDS_WARNING: "", INVALID_FIELDS_WARNING: "", COUNTRY: "Country", COUNTRY_PLACEHOLDER: "Select a country", STATE: "State", STATE_PLACEHOLDER: "Select a state", CITY: "City", CITY_PLACEHOLDER: "Select a city", TIMEZONE: "Timezone", TIMEZONE_PLACEHOLDER: "Selecte a timezone", NAME: "Name", OK: "Ok", PAGE_NOT_FOUND: "Page not found", PAGE_NOT_FOUND_DESCRIPTION: "The link you clicked may be broken or the page may have been removed or renamed", TODAY: "Today", WEEK: "Week", CALENDAR: "Calendar", EVENT: "Event", NO_INFORMATION: "No information", SYNC_GOOGLE_CALENDAR: "Sync Google Calendar", NO_RESULTS: "No results were found", GOOGLE_MEET: "Google Meet", LONG_TIME_AGO: "Long time ago", TOMORROW: "Tomorrow", CHOOSE_PLAN: "Choose a plan", CHOOSE_PLAN_DESCRIPTION: "Choose a plan that fits your needs!", PRIVACY_POLICY: "", OPTIONAL: "Optional", RESULTS: "Results", LOCATION: "Location", ADDRESS: "Address", ADDRESS_PLACEHOLDER: "Enter your address", COPY_TO_CLIPBOARD: "Copy to clipboard", ACTIONS: "Actions", MIN: "Minimum", MAX: "Maximum", DUE_DATE: "Due date", QUICK_SEARCH: "Quick search", MONTHLY: "Monthly", WEEKLY: "Weekly", GOOGLE_MAPS_LINK: "Google maps link", MINUTE: "Minute", MINUTES: "Minutes", HOUR: "Hour", HOURS: "Hours", VE_ID: "Identity card", ACCOUNT_VERIFIED_BY_CLINIKOS: "This account has been verified by Clinikos, as well as its affiliations with the following institutions", INBOX: "Inbox", ACCEPTED: "Accepted", DECLINED: "Declined", NEEDS_ACTION: "Needs action", OVERDUE: "Overdue", FILTER_BY: "Filter by", REFRESH: "Refresh", LOADING: "Loading", MINUTE_LEFT: "One minute left", VALUE_MINUTES_LEFT: "{{value}} minutes left", PLAY: "Play", PAUSE: "Pause", STOP: "Stop", LOAD_MORE: "Load more", BILLING: "Billing", DOCTOR: "Doctor", ASSISTANT: "Assistant", NUMBER_OF_DOCTORS: "Number of Doctors", NUMBER_OF_ASSISTANTS: "Number of Assistants", EACH_DOCTOR: "Each doctor", EACH_ASSISTANT: "Each assistant", ROLE: "Role", PAYMENT_METHODS: "Payment methods", UPGRADE: "Upgrade", TOTAL: "Total", BUY: "Buy", TYPE: "Type", RECURRENT: "Recurrent", ACCEPT: "Accept", DECLINE: "Decline", PREFERENCES: "Preferences", BOOKING: "Booking", PATTERN_NOT_VALID: "Pattern is not valid" };
38
+
39
+ // lang/es.json
40
+ var es_default = { BIRTH_DATE: "Fecha de nacimiento", DAY: "D\xEDa", DAY_PLACEHOLDER: "Elige un d\xEDa", MONTH: "Mes", MONTH_PLACEHOLDER: "Elige un mes", YEAR: "A\xF1o", YEAR_PLACEHOLDER: "Elige un a\xF1o", PRICING: "Precio", PRICING_TABLE: "Tabla de precios", OUR_PRICING_PLAN: "Nuestros precios", PRICING_DESCRIPTION: "Mejora tu experiencia. Descubre el plan que desbloquea las funciones que necesitas.", VALUE_STORAGE: "{{value}} almacenamiento", GOOGLE_CALENDAR_SYNC: "Google Calenar Sync", INTERNAL_REMINDERS: "Recordatorios internos", WHATSAPP_AUTOMATED_REMINDERS: "Recordatorios automatizados de WhatsApp", PROFESSIONAL: "Profesional", PROFESSIONAL_PLAN_DESCRIPTION: "Para doctores individuales que buscan elevar sus pr\xE1cticas", DIGITAL_PRESCRIPTIONS: "Recipes digitales", DICOM_VIEWER: "Visualizador DICOM", VERIFIED_MEDICAL_CREDENTIALS: "Credenciales m\xE9dicas verificadas", PATIENT_SELF_MANAGEMENT: "Auto gesti\xF3n para pacientes", BUY_NOW: "Comprar ahora", ORGANIZATION: "Organizaci\xF3n", ORGANIZATION_PLAN_DESCRIPTION: "Para organizaciones con m\xFAltiples usuarios que buscan compartir informaci\xF3n", UP_TO_VALUE_STORAGE: "Hasta {{value}} de almacenamiento", CONFIGURABLE_USER_PERMISSIONS: "Permisolog\xEDa configurable para usuarios", CALCULATE_PRICING: "Calcular precio", DOCTORS: "Doctores", ASSISTANTS: "Asistentes", BASIC: "B\xE1sico", BASIC_PLAN_DESCRIPTION: "Para iniciar en la industria m\xE9dica", USER: "Usuario", TYPE_A_VALUE: "Ingresa un valor", STORAGE: "Almacenamiento", PASSWORD: "Contrase\xF1a", PASSWORD_PLACEHOLDER: "Ingresa tu contrase\xF1a", REQUIRED: "Requerido", TOO_SHORT: "Demasiado corto", TOO_LONG: "Demasiado largo", VALUE_LOW: "El valor es muy bajo", VALUE_HIGH: "El valor es muy alto", PATTERN_INVALID: "El patr\xF3n no es v\xE1lido", INVALID_EMAIL: "Correo inv\xE1lido", SHOW_PASSWORD: "Mostrar contrase\xF1a", HIDE_PASSWORD: "Esconder contrase\xF1a", GROUP_PRICING_CALCULATOR: "Calculadora de precios grupal", VERIFIED_ACCOUNT: "Cuenta verificada", VERIFIED_ACCOUNT_TEXT: "Esta cuenta ha sido verificada por Clinikos, as\xED como sus afiliaciones con las siguientes instituciones", PHONE_NUMBER: "N\xFAmero de tel\xE9fono", PHONE_NUMBER_PLACEHOLDER: "Ingrese su n\xFAmero de tel\xE9fono", SEND_MESSAGE: "Enviar mensaje", BOOK_MEETING: "Agendar cita", SIGN_UP: "Reg\xEDstrate", INVALID_PASSWORD: "Tu contrase\xF1a no cumple con los requisitos de seguridad.", NOT_EQUAL: "Los valores no son iguales", GENDER: "G\xE9nero", FEMALE: "Femenino", MALE: "Masculino", CLOSE: "Cerrar", MANDATORY_FIELDS_WARNING: "", INVALID_FIELDS_WARNING: "", COUNTRY: "Pa\xEDs", COUNTRY_PLACEHOLDER: "Selecciona un pa\xEDs", STATE: "Estado", STATE_PLACEHOLDER: "Selecciona un estado", CITY: "Ciudad", CITY_PLACEHOLDER: "Selecciona una ciudad", TIMEZONE: "Zona horaria", TIMEZONE_PLACEHOLDER: "Selecciona una zora horaria", NAME: "Nombre", OK: "Ok", PAGE_NOT_FOUND: "P\xE1gina no encontrada", PAGE_NOT_FOUND_DESCRIPTION: "El enlace en el que hiciste click puede que est\xE9 roto o la p\xE1gina puede haber sido eliminada o renombrada", TODAY: "Hoy", WEEK: "Semana", CALENDAR: "Calendario", EVENT: "Evento", NO_INFORMATION: "Sin informaci\xF3n", SYNC_GOOGLE_CALENDAR: "Vincular Calendario de Google", NO_RESULTS: "No se encontraron resultados", GOOGLE_MEET: "Google Meet", LONG_TIME_AGO: "Hace mucho tiempo", TOMORROW: "Ma\xF1ana", CHOOSE_PLAN: "Elige un plan", CHOOSE_PLAN_DESCRIPTION: "\xA1Elige el plan que se ajuste a tus necesidades!", PRIVACY_POLICY: "", OPTIONAL: "Opcional", RESULTS: "Resultados", LOCATION: "Ubicaci\xF3n", ADDRESS: "Direcci\xF3n", ADDRESS_PLACEHOLDER: "Ingresa tu direcci\xF3n", COPY_TO_CLIPBOARD: "Copiar al portapapeles", ACTIONS: "Acciones", MIN: "M\xEDnimo", MAX: "M\xE1ximo", DUE_DATE: "Fecha l\xEDmite", QUICK_SEARCH: "B\xFAsqueda r\xE1pida", MONTHLY: "Mensual", WEEKLY: "Semanal", GOOGLE_MAPS_LINK: "Link de Google Maps", MINUTE: "Minuto", MINUTES: "Minutos", HOUR: "Hora", HOURS: "Horas", VE_ID: "C\xE9dula de Identidad", ACCOUNT_VERIFIED_BY_CLINIKOS: "Esta cuenta ha sido verificada por Clinikos, as\xED como sus afiliaciones con las siguientes instituciones", INBOX: "Bandeja de entrada", ACCEPTED: "Aceptado", DECLINED: "Declinado", NEEDS_ACTION: "Necesita acci\xF3n", OVERDUE: "Atrasado", FILTER_BY: "Filtrar por", REFRESH: "Refrescar", LOADING: "Cargando", MINUTE_LEFT: "Un minuto restante", VALUE_MINUTES_LEFT: "{{value}} minutos restantes", PLAY: "Reproducir", PAUSE: "Pausar", STOP: "Detener", LOAD_MORE: "Cargar m\xE1s", BILLING: "Facturaci\xF3n", DOCTOR: "Doctor", ASSISTANT: "Asistente", NUMBER_OF_DOCTORS: "N\xFAmero de Doctores", NUMBER_OF_ASSISTANTS: "N\xFAmero de Asistentes", EACH_DOCTOR: "Cada doctor", EACH_ASSISTANT: "Cada asistente", ROLE: "Rol", PAYMENT_METHODS: "M\xE9todos de pago", UPGRADE: "Mejorar", TOTAL: "Total", BUY: "Comprar", TYPE: "Tipo", RECURRENT: "Recurrente", ACCEPT: "Aceptar", DECLINE: "Declinar", PREFERENCES: "Preferencias", BOOKING: "Agendar cita", PATTERN_NOT_VALID: "El patr\xF3n no es v\xE1lido" };
41
+
42
+ // types/errors.ts
43
+ var regex = {
44
+ email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
45
+ password: /^(?!.*\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}[\]|:;"'<>,.?/_₹]).{8,24}$/
46
+ };
47
+ var errors = {
48
+ required: {
49
+ validate: (val) => Boolean(val),
50
+ msg: "REQUIRED"
51
+ },
52
+ min: {
53
+ validate: (val, min) => val >= min,
54
+ msg: "VALUE_LOW"
55
+ },
56
+ max: {
57
+ validate: (val, max) => val <= max,
58
+ msg: "VALUE_HIGH"
59
+ },
60
+ minLength: {
61
+ validate: (val = "", min) => val.length >= min,
62
+ msg: "TOO_SHORT"
63
+ },
64
+ maxLength: {
65
+ validate: (val = "", max) => val.length <= max,
66
+ msg: "TOO_LONG"
67
+ },
68
+ pattern: {
69
+ validate: (val, pattern) => new RegExp(pattern).test(val),
70
+ msg: "PATTERN_INVALID"
71
+ },
72
+ equal: {
73
+ validate: (val, comparison) => val === comparison,
74
+ msg: "NOT_EQUAL"
75
+ },
76
+ numberIsEqual: {
77
+ validate: (val, comparison) => val === comparison,
78
+ msg: "NOT_EQUAL"
79
+ },
80
+ email: {
81
+ validate: (val) => new RegExp(regex.email).test(val),
82
+ msg: "INVALID_EMAIL"
83
+ },
84
+ password: {
85
+ validate: (val) => new RegExp(regex.password).test(val),
86
+ msg: "INVALID_PASSWORD"
87
+ }
88
+ };
89
+ var NextUIError = class {
90
+ isInvalid;
91
+ errorMessage;
92
+ constructor(bool = false, msg = "") {
93
+ this.isInvalid = bool;
94
+ this.errorMessage = bool ? msg : "";
95
+ }
96
+ };
97
+ var nxError = (bool, msg) => new NextUIError(bool, msg);
98
+
99
+ // types/types.ts
100
+ var langMap = {
101
+ en: en_default,
102
+ es: es_default
103
+ };
104
+
105
+ // src/hooks/useComponentLang.tsx
106
+ var cookieName = "LOCALE";
107
+ var getClientCookie = () => {
108
+ const value = "; " + document.cookie, decodedValue = decodeURIComponent(value), parts = decodedValue.split("; " + cookieName + "=");
109
+ if (parts.length === 2) return parts.pop()?.split(";").shift();
110
+ };
111
+ var getServerCookie = () => {
112
+ try {
113
+ const { cookies } = __require("next/headers");
114
+ return cookies().get(cookieName)?.value;
115
+ } catch {
116
+ return "es";
117
+ }
118
+ };
119
+ function useComponentLanguage() {
120
+ const isServer = typeof window === "undefined", locale = (isServer ? getServerCookie() : getClientCookie()) || "en";
121
+ return {
122
+ locale,
123
+ lang: langMap[locale]
124
+ };
125
+ }
126
+
127
+ // src/hooks/useValidation.tsx
128
+ function useValidation() {
129
+ const { lang } = useComponentLanguage();
130
+ const getValidation = (value, isTouched, types, errorMessages) => {
131
+ const items = Object.entries(types), isRequired = items.map(([key]) => key).includes("required");
132
+ const validations = items.map(([name, opts]) => {
133
+ const { validate, msg: msg2 } = errors[name];
134
+ return {
135
+ isValid: validate(value, opts),
136
+ msg: errorMessages?.[name] || lang[msg2]
137
+ };
138
+ }), { isValid, msg } = validations.find(({ isValid: isValid2 }) => !isValid2) || {
139
+ isValid: true,
140
+ msg: ""
141
+ };
142
+ return {
143
+ isValid,
144
+ validationProps: isRequired && !isTouched ? nxError() : nxError(!isValid, msg)
145
+ };
146
+ };
147
+ return { getValidation };
148
+ }
149
+
150
+ // src/hooks/useFormChange.tsx
151
+ function useFormChange(initialObj) {
152
+ const [state, setState] = useState(initialObj), [touched, setTouched] = useState(allToValue(initialObj, false)), { getValidation } = useValidation();
153
+ let errors2 = allToValue(initialObj, false);
154
+ const onChange = ({
155
+ target: { id, value }
156
+ }) => setState(handleNestedChange({ state, id, value })), onBlur = ({ target: { id } }) => setTouched(handleNestedChange({ state: touched, id, value: true })), resetForm = () => {
157
+ setTouched(allToValue(initialObj, false));
158
+ setState(initialObj);
159
+ };
160
+ function register(id, validations, errorMessages) {
161
+ const [value, isTouched] = [state, touched].map(
162
+ (obj) => getNestedValueByKey(obj, id)
163
+ ), hasValidations = validations !== void 0, { isValid = false, validationProps = {} } = hasValidations ? getValidation(value, isTouched, validations, errorMessages) : {};
164
+ errors2 = handleNestedChange({
165
+ state: errors2,
166
+ id,
167
+ value: hasValidations ? !isValid : false
168
+ });
169
+ return {
170
+ id,
171
+ onChange,
172
+ onBlur,
173
+ value,
174
+ ...validationProps
175
+ };
176
+ }
177
+ const hasInvalidValues = () => {
178
+ setTouched(allToValue(touched, true));
179
+ return JSON.stringify(errors2).includes(":true");
180
+ };
181
+ return {
182
+ onChange,
183
+ onBlur,
184
+ state,
185
+ setState,
186
+ register,
187
+ hasInvalidValues,
188
+ touched,
189
+ resetForm
190
+ };
191
+ }
192
+ export {
193
+ useFormChange
194
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juantroconisf/lib",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/lang/en.json DELETED
@@ -1 +0,0 @@
1
- {"BIRTH_DATE":"Birth date","DAY":"Day","DAY_PLACEHOLDER":"Choose a day","MONTH":"Month","MONTH_PLACEHOLDER":"Choose a month","YEAR":"Year","YEAR_PLACEHOLDER":"Choose a year","PRICING":"Pricing","PRICING_TABLE":"Pricing table","OUR_PRICING_PLAN":"Our pricing plan","PRICING_DESCRIPTION":"Level up your experience. Discover the plan that unlocks the features you need.","VALUE_STORAGE":"{{value}} storage","GOOGLE_CALENDAR_SYNC":"Google Calendar Sync","INTERNAL_REMINDERS":"Internal reminders","WHATSAPP_AUTOMATED_REMINDERS":"WhatsApp Automated Reminders","PROFESSIONAL":"Professional","PROFESSIONAL_PLAN_DESCRIPTION":"For single doctors looking to level up their practice","DIGITAL_PRESCRIPTIONS":"Digital prescriptions","DICOM_VIEWER":"DICOM Viewer","VERIFIED_MEDICAL_CREDENTIALS":"Verified medical credentials","PATIENT_SELF_MANAGEMENT":"Patient self management","BUY_NOW":"Buy now","ORGANIZATION":"Organization","ORGANIZATION_PLAN_DESCRIPTION":"For organizations with multiple users looking to share information","UP_TO_VALUE_STORAGE":"Up to {{value}} storage","CONFIGURABLE_USER_PERMISSIONS":"Configurable user permissions","CALCULATE_PRICING":"Calculate pricing","DOCTORS":"Doctors","ASSISTANTS":"Assistants","BASIC":"Basic","BASIC_PLAN_DESCRIPTION":"For starters in the medical industry","USER":"User","TYPE_A_VALUE":"Type a value","STORAGE":"Storage","PASSWORD":"Password","PASSWORD_PLACEHOLDER":"Enter your password","REQUIRED":"Required","TOO_SHORT":"Too short","TOO_LONG":"Too long","VALUE_LOW":"Value is too low","VALUE_HIGH":"Value is too high","PATTERN_INVALID":"Pattern is not valid","INVALID_EMAIL":"Invalid email","SHOW_PASSWORD":"Show password","HIDE_PASSWORD":"Hide password","GROUP_PRICING_CALCULATOR":"Group Pricing Calculator","VERIFIED_ACCOUNT":"Verified account","VERIFIED_ACCOUNT_TEXT":"This account has been verified by Clinikos, as well as its affiliations with the following institutions","PHONE_NUMBER":"Phone number","PHONE_NUMBER_PLACEHOLDER":"Enter your phone number","SEND_MESSAGE":"Send message","BOOK_MEETING":"Book meeting","SIGN_UP":"Sign up","INVALID_PASSWORD":"Your password doesn't meet the security criteria.","NOT_EQUAL":"Values are not equal","GENDER":"Gender","FEMALE":"Female","MALE":"Male","CLOSE":"Close","MANDATORY_FIELDS_WARNING":"","INVALID_FIELDS_WARNING":"","COUNTRY":"Country","COUNTRY_PLACEHOLDER":"Select a country","STATE":"State","STATE_PLACEHOLDER":"Select a state","CITY":"City","CITY_PLACEHOLDER":"Select a city","TIMEZONE":"Timezone","TIMEZONE_PLACEHOLDER":"Selecte a timezone","NAME":"Name","OK":"Ok","PAGE_NOT_FOUND":"Page not found","PAGE_NOT_FOUND_DESCRIPTION":"The link you clicked may be broken or the page may have been removed or renamed","TODAY":"Today","WEEK":"Week","CALENDAR":"Calendar","EVENT":"Event","NO_INFORMATION":"No information","SYNC_GOOGLE_CALENDAR":"Sync Google Calendar","NO_RESULTS":"No results were found","GOOGLE_MEET":"Google Meet","LONG_TIME_AGO":"Long time ago","TOMORROW":"Tomorrow","CHOOSE_PLAN":"Choose a plan","CHOOSE_PLAN_DESCRIPTION":"Choose a plan that fits your needs!","PRIVACY_POLICY":"","OPTIONAL":"Optional","RESULTS":"Results","LOCATION":"Location","ADDRESS":"Address","ADDRESS_PLACEHOLDER":"Enter your address","COPY_TO_CLIPBOARD":"Copy to clipboard","ACTIONS":"Actions","MIN":"Minimum","MAX":"Maximum","DUE_DATE":"Due date","QUICK_SEARCH":"Quick search","MONTHLY":"Monthly","WEEKLY":"Weekly","GOOGLE_MAPS_LINK":"Google maps link","MINUTE":"Minute","MINUTES":"Minutes","HOUR":"Hour","HOURS":"Hours","VE_ID":"Identity card","ACCOUNT_VERIFIED_BY_CLINIKOS":"This account has been verified by Clinikos, as well as its affiliations with the following institutions","INBOX":"Inbox","ACCEPTED":"Accepted","DECLINED":"Declined","NEEDS_ACTION":"Needs action","OVERDUE":"Overdue","FILTER_BY":"Filter by","REFRESH":"Refresh","LOADING":"Loading","MINUTE_LEFT":"One minute left","VALUE_MINUTES_LEFT":"{{value}} minutes left","PLAY":"Play","PAUSE":"Pause","STOP":"Stop","LOAD_MORE":"Load more","BILLING":"Billing","DOCTOR":"Doctor","ASSISTANT":"Assistant","NUMBER_OF_DOCTORS":"Number of Doctors","NUMBER_OF_ASSISTANTS":"Number of Assistants","EACH_DOCTOR":"Each doctor","EACH_ASSISTANT":"Each assistant","ROLE":"Role","PAYMENT_METHODS":"Payment methods","UPGRADE":"Upgrade","TOTAL":"Total","BUY":"Buy","TYPE":"Type","RECURRENT":"Recurrent","ACCEPT":"Accept","DECLINE":"Decline","PREFERENCES":"Preferences","BOOKING":"Booking","PATTERN_NOT_VALID":"Pattern is not valid"}
package/lang/es.json DELETED
@@ -1 +0,0 @@
1
- {"BIRTH_DATE":"Fecha de nacimiento","DAY":"Día","DAY_PLACEHOLDER":"Elige un día","MONTH":"Mes","MONTH_PLACEHOLDER":"Elige un mes","YEAR":"Año","YEAR_PLACEHOLDER":"Elige un año","PRICING":"Precio","PRICING_TABLE":"Tabla de precios","OUR_PRICING_PLAN":"Nuestros precios","PRICING_DESCRIPTION":"Mejora tu experiencia. Descubre el plan que desbloquea las funciones que necesitas.","VALUE_STORAGE":"{{value}} almacenamiento","GOOGLE_CALENDAR_SYNC":"Google Calenar Sync","INTERNAL_REMINDERS":"Recordatorios internos","WHATSAPP_AUTOMATED_REMINDERS":"Recordatorios automatizados de WhatsApp","PROFESSIONAL":"Profesional","PROFESSIONAL_PLAN_DESCRIPTION":"Para doctores individuales que buscan elevar sus prácticas","DIGITAL_PRESCRIPTIONS":"Recipes digitales","DICOM_VIEWER":"Visualizador DICOM","VERIFIED_MEDICAL_CREDENTIALS":"Credenciales médicas verificadas","PATIENT_SELF_MANAGEMENT":"Auto gestión para pacientes","BUY_NOW":"Comprar ahora","ORGANIZATION":"Organización","ORGANIZATION_PLAN_DESCRIPTION":"Para organizaciones con múltiples usuarios que buscan compartir información","UP_TO_VALUE_STORAGE":"Hasta {{value}} de almacenamiento","CONFIGURABLE_USER_PERMISSIONS":"Permisología configurable para usuarios","CALCULATE_PRICING":"Calcular precio","DOCTORS":"Doctores","ASSISTANTS":"Asistentes","BASIC":"Básico","BASIC_PLAN_DESCRIPTION":"Para iniciar en la industria médica","USER":"Usuario","TYPE_A_VALUE":"Ingresa un valor","STORAGE":"Almacenamiento","PASSWORD":"Contraseña","PASSWORD_PLACEHOLDER":"Ingresa tu contraseña","REQUIRED":"Requerido","TOO_SHORT":"Demasiado corto","TOO_LONG":"Demasiado largo","VALUE_LOW":"El valor es muy bajo","VALUE_HIGH":"El valor es muy alto","PATTERN_INVALID":"El patrón no es válido","INVALID_EMAIL":"Correo inválido","SHOW_PASSWORD":"Mostrar contraseña","HIDE_PASSWORD":"Esconder contraseña","GROUP_PRICING_CALCULATOR":"Calculadora de precios grupal","VERIFIED_ACCOUNT":"Cuenta verificada","VERIFIED_ACCOUNT_TEXT":"Esta cuenta ha sido verificada por Clinikos, así como sus afiliaciones con las siguientes instituciones","PHONE_NUMBER":"Número de teléfono","PHONE_NUMBER_PLACEHOLDER":"Ingrese su número de teléfono","SEND_MESSAGE":"Enviar mensaje","BOOK_MEETING":"Agendar cita","SIGN_UP":"Regístrate","INVALID_PASSWORD":"Tu contraseña no cumple con los requisitos de seguridad.","NOT_EQUAL":"Los valores no son iguales","GENDER":"Género","FEMALE":"Femenino","MALE":"Masculino","CLOSE":"Cerrar","MANDATORY_FIELDS_WARNING":"","INVALID_FIELDS_WARNING":"","COUNTRY":"País","COUNTRY_PLACEHOLDER":"Selecciona un país","STATE":"Estado","STATE_PLACEHOLDER":"Selecciona un estado","CITY":"Ciudad","CITY_PLACEHOLDER":"Selecciona una ciudad","TIMEZONE":"Zona horaria","TIMEZONE_PLACEHOLDER":"Selecciona una zora horaria","NAME":"Nombre","OK":"Ok","PAGE_NOT_FOUND":"Página no encontrada","PAGE_NOT_FOUND_DESCRIPTION":"El enlace en el que hiciste click puede que esté roto o la página puede haber sido eliminada o renombrada","TODAY":"Hoy","WEEK":"Semana","CALENDAR":"Calendario","EVENT":"Evento","NO_INFORMATION":"Sin información","SYNC_GOOGLE_CALENDAR":"Vincular Calendario de Google","NO_RESULTS":"No se encontraron resultados","GOOGLE_MEET":"Google Meet","LONG_TIME_AGO":"Hace mucho tiempo","TOMORROW":"Mañana","CHOOSE_PLAN":"Elige un plan","CHOOSE_PLAN_DESCRIPTION":"¡Elige el plan que se ajuste a tus necesidades!","PRIVACY_POLICY":"","OPTIONAL":"Opcional","RESULTS":"Resultados","LOCATION":"Ubicación","ADDRESS":"Dirección","ADDRESS_PLACEHOLDER":"Ingresa tu dirección","COPY_TO_CLIPBOARD":"Copiar al portapapeles","ACTIONS":"Acciones","MIN":"Mínimo","MAX":"Máximo","DUE_DATE":"Fecha límite","QUICK_SEARCH":"Búsqueda rápida","MONTHLY":"Mensual","WEEKLY":"Semanal","GOOGLE_MAPS_LINK":"Link de Google Maps","MINUTE":"Minuto","MINUTES":"Minutos","HOUR":"Hora","HOURS":"Horas","VE_ID":"Cédula de Identidad","ACCOUNT_VERIFIED_BY_CLINIKOS":"Esta cuenta ha sido verificada por Clinikos, así como sus afiliaciones con las siguientes instituciones","INBOX":"Bandeja de entrada","ACCEPTED":"Aceptado","DECLINED":"Declinado","NEEDS_ACTION":"Necesita acción","OVERDUE":"Atrasado","FILTER_BY":"Filtrar por","REFRESH":"Refrescar","LOADING":"Cargando","MINUTE_LEFT":"Un minuto restante","VALUE_MINUTES_LEFT":"{{value}} minutos restantes","PLAY":"Reproducir","PAUSE":"Pausar","STOP":"Detener","LOAD_MORE":"Cargar más","BILLING":"Facturación","DOCTOR":"Doctor","ASSISTANT":"Asistente","NUMBER_OF_DOCTORS":"Número de Doctores","NUMBER_OF_ASSISTANTS":"Número de Asistentes","EACH_DOCTOR":"Cada doctor","EACH_ASSISTANT":"Cada asistente","ROLE":"Rol","PAYMENT_METHODS":"Métodos de pago","UPGRADE":"Mejorar","TOTAL":"Total","BUY":"Comprar","TYPE":"Tipo","RECURRENT":"Recurrente","ACCEPT":"Aceptar","DECLINE":"Declinar","PREFERENCES":"Preferencias","BOOKING":"Agendar cita","PATTERN_NOT_VALID":"El patrón no es válido"}
package/types/errors.ts DELETED
@@ -1,91 +0,0 @@
1
- type ValidatorFunction<T, U> = (val: T, ...args: U[]) => boolean;
2
-
3
- interface Validator<T, U = any> {
4
- validate: ValidatorFunction<T, U>;
5
- msg: string;
6
- }
7
-
8
- interface ValidatorTypes {
9
- required: Validator<string | number, boolean>;
10
- min: Validator<number, number>;
11
- max: Validator<number, number>;
12
- minLength: Validator<string, number>;
13
- maxLength: Validator<string, number>;
14
- pattern: Validator<string, RegExp>;
15
- equal: Validator<string, string>;
16
- numberIsEqual: Validator<number, number>;
17
- email: Validator<string, boolean>;
18
- password: Validator<string, boolean>;
19
- }
20
-
21
- export type ValidatorParams = {
22
- [K in keyof ValidatorTypes]: ValidatorTypes[K] extends Validator<any, infer U>
23
- ? U
24
- : never;
25
- };
26
- export type ValidatorErrorMessage = {
27
- [K in keyof ValidatorTypes]: string;
28
- };
29
-
30
- const regex = {
31
- email:
32
- /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
33
- password:
34
- /^(?!.*\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}[\]|:;"'<>,.?/_₹]).{8,24}$/,
35
- };
36
-
37
- export const errors: ValidatorTypes = {
38
- required: {
39
- validate: (val) => Boolean(val),
40
- msg: "REQUIRED",
41
- },
42
- min: {
43
- validate: (val, min) => val >= min,
44
- msg: "VALUE_LOW",
45
- },
46
- max: {
47
- validate: (val, max) => val <= max,
48
- msg: "VALUE_HIGH",
49
- },
50
- minLength: {
51
- validate: (val = "", min) => val.length >= min,
52
- msg: "TOO_SHORT",
53
- },
54
- maxLength: {
55
- validate: (val = "", max) => val.length <= max,
56
- msg: "TOO_LONG",
57
- },
58
- pattern: {
59
- validate: (val, pattern) => new RegExp(pattern).test(val),
60
- msg: "PATTERN_INVALID",
61
- },
62
- equal: {
63
- validate: (val, comparison) => val === comparison,
64
- msg: "NOT_EQUAL",
65
- },
66
- numberIsEqual: {
67
- validate: (val, comparison) => val === comparison,
68
- msg: "NOT_EQUAL",
69
- },
70
- email: {
71
- validate: (val) => new RegExp(regex.email).test(val),
72
- msg: "INVALID_EMAIL",
73
- },
74
- password: {
75
- validate: (val) => new RegExp(regex.password).test(val),
76
- msg: "INVALID_PASSWORD",
77
- },
78
- };
79
-
80
- class NextUIError {
81
- isInvalid: boolean;
82
- errorMessage: string;
83
-
84
- constructor(bool: boolean = false, msg: string = "") {
85
- this.isInvalid = bool;
86
- this.errorMessage = bool ? msg : "";
87
- }
88
- }
89
-
90
- export const nxError = (bool?: boolean, msg?: string) =>
91
- new NextUIError(bool, msg);
package/types/types.ts DELETED
@@ -1,9 +0,0 @@
1
- import en from "../lang/en.json";
2
- import es from "../lang/es.json";
3
-
4
- export const langMap = {
5
- en,
6
- es,
7
- };
8
-
9
- export * from "./errors";