@nocios/crudify-ui 1.0.69 → 1.0.71

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/README.md CHANGED
@@ -0,0 +1,375 @@
1
+ # CrudifyLogin - Integracion Completa
2
+
3
+ > Componente de autenticacion completo y reutilizable para aplicaciones React, basado en la API de Crudify.
4
+
5
+ ## 🚀 Instalacion
6
+
7
+ ```bash
8
+ npm install @nocios/crudify-ui
9
+ ```
10
+
11
+ ## 📋 Dependencias Requeridas
12
+
13
+ Asegurate de tener estas dependencias en tu proyecto:
14
+
15
+ ```bash
16
+ npm install react react-dom @mui/material @mui/icons-material
17
+ ```
18
+
19
+ ## 🎯 Uso Basico
20
+
21
+ ### Integracion Simple
22
+
23
+ ```tsx
24
+ import { CrudifyLogin } from "@nocios/crudify-ui";
25
+
26
+ function LoginPage() {
27
+ const handleLoginSuccess = (token: string, redirectUrl?: string) => {
28
+ // Guardar token y redirigir
29
+ sessionStorage.setItem("authToken", token);
30
+ window.location.href = redirectUrl || "/dashboard";
31
+ };
32
+
33
+ return (
34
+ <CrudifyLogin
35
+ config={{
36
+ publicApiKey: "tu-api-key",
37
+ env: "prod",
38
+ appName: "Mi Aplicacion",
39
+ }}
40
+ onLoginSuccess={handleLoginSuccess}
41
+ redirectUrl="/dashboard"
42
+ />
43
+ );
44
+ }
45
+ ```
46
+
47
+ ## ⚙️ Configuracion Completa
48
+
49
+ ### Props del Componente
50
+
51
+ | Prop | Tipo | Default | Descripcion |
52
+ | --------------------- | ----------------------------------------------- | --------- | --------------------------------- |
53
+ | `config` | `CrudifyLoginConfig` | `{}` | Configuracion del componente |
54
+ | `onLoginSuccess` | `(token: string, redirectUrl?: string) => void` | - | Callback cuando login es exitoso |
55
+ | `onError` | `(error: string) => void` | - | Callback para manejo de errores |
56
+ | `onScreenChange` | `(screen: string, params?: object) => void` | - | Callback para cambios de pantalla |
57
+ | `onExternalNavigate` | `(path: string) => void` | - | Callback para navegacion externa |
58
+ | `initialScreen` | `login,forgotPassword,resetPassword,checkCode` | `"login"` | Pantalla inicial |
59
+ | `redirectUrl` | `string` | `"/"` | URL de redireccion post-login |
60
+ | `autoReadFromCookies` | `boolean` | `true` | Leer configuracion desde cookies |
61
+ | `language` | `string` | `"en"` | Idioma de la interfaz |
62
+ | `translations` | `CrudifyLoginTranslations` | - | Traducciones customizadas |
63
+ | `translationsUrl` | `string` | - | URL para cargar traducciones |
64
+
65
+ ### Configuracion (CrudifyLoginConfig)
66
+
67
+ ```tsx
68
+ interface CrudifyLoginConfig {
69
+ publicApiKey?: string; // Clave de API de Crudify
70
+ env?: "dev" | "stg" | "api" | "prod"; // Entorno de la API
71
+ appName?: string; // Nombre de tu aplicacion
72
+ logo?: string; // URL del logo
73
+ colors?: {
74
+ primaryColor?: string; // Color principal
75
+ bgColor?: string; // Color de fondo
76
+ [key: string]: string | undefined;
77
+ };
78
+ loginActions?: string[]; // Acciones disponibles: ["forgotPassword", "createUser"]
79
+ }
80
+ ```
81
+
82
+ ## 🎨 Personalizacion Visual
83
+
84
+ ### Colores y Branding
85
+
86
+ ```tsx
87
+ <CrudifyLogin
88
+ config={{
89
+ appName: "Mi App",
90
+ logo: "/mi-logo.png",
91
+ colors: { primaryColor: "#1066BA", bgColor: "#f5f5f5" },
92
+ }}
93
+ />
94
+ ```
95
+
96
+ ### Traducciones Personalizadas
97
+
98
+ ```tsx
99
+ const misTraduciones = {
100
+ "login.title": "Iniciar Sesion",
101
+ "login.usernameLabel": "Usuario o Email",
102
+ "login.passwordLabel": "Contrasena",
103
+ "login.loginButton": "Entrar",
104
+ "login.forgotPasswordLink": "¿Olvidaste tu contrasena?",
105
+ };
106
+
107
+ <CrudifyLogin translations={misTraduciones} language="es" />;
108
+ ```
109
+
110
+ ## 🔧 Hooks Disponibles
111
+
112
+ ### useUserProfile
113
+
114
+ Hook para obtener y manejar el perfil del usuario autenticado:
115
+
116
+ ```tsx
117
+ import { useUserProfile } from "@nocios/crudify-ui";
118
+
119
+ function UserDashboard() {
120
+ const { userProfile, loading, error, refreshProfile } = useUserProfile();
121
+
122
+ if (loading) return <div>Cargando...</div>;
123
+ if (error) return <div>Error: {error}</div>;
124
+
125
+ return (
126
+ <div>
127
+ <h1>Bienvenido, {userProfile?.name}</h1>
128
+ <p>Email: {userProfile?.email}</p>
129
+ <button onClick={refreshProfile}>Actualizar Perfil</button>
130
+ </div>
131
+ );
132
+ }
133
+ ```
134
+
135
+ ### useCrudifyLogin
136
+
137
+ Hook interno para configuracion avanzada:
138
+
139
+ ```tsx
140
+ import { useCrudifyLogin } from "@nocios/crudify-ui";
141
+
142
+ function CustomLogin() {
143
+ const { config } = useCrudifyLogin({
144
+ publicApiKey: "mi-api-key",
145
+ env: "prod",
146
+ });
147
+
148
+ // config contiene la configuracion final combinada con cookies
149
+ return <div>App: {config.appName}</div>;
150
+ }
151
+ ```
152
+
153
+ ## 🛠️ Utilidades Disponibles
154
+
155
+ ### JWT Utils
156
+
157
+ ```tsx
158
+ import { getCurrentUserEmail, decodeJwtSafely, isTokenExpired } from "@nocios/crudify-ui";
159
+
160
+ // Obtener email del usuario actual
161
+ const userEmail = getCurrentUserEmail();
162
+
163
+ // Decodificar token JWT de forma segura
164
+ const payload = decodeJwtSafely(token);
165
+
166
+ // Verificar si token ha expirado
167
+ const expired = isTokenExpired(token);
168
+ ```
169
+
170
+ ### Storage Seguro
171
+
172
+ ```tsx
173
+ import { secureSessionStorage, secureLocalStorage } from "@nocios/crudify-ui";
174
+
175
+ // Guardar token de forma segura
176
+ secureSessionStorage.setToken(token);
177
+
178
+ // Obtener token
179
+ const token = secureSessionStorage.getToken();
180
+
181
+ // Limpiar storage
182
+ secureSessionStorage.clear();
183
+ ```
184
+
185
+ ### Manejo de Errores
186
+
187
+ ```tsx
188
+ import { handleCrudifyError, ERROR_CODES, getErrorMessage } from "@nocios/crudify-ui";
189
+
190
+ try {
191
+ // Tu codigo
192
+ } catch (error) {
193
+ const parsedErrors = handleCrudifyError(error);
194
+ parsedErrors.forEach((err) => {
195
+ console.log(`Error ${err.code}: ${err.message} (Severidad: ${err.severity})`);
196
+ });
197
+ }
198
+ ```
199
+
200
+ ## 📱 Flujos de Autenticacion
201
+
202
+ ### 1. Login Estandar
203
+
204
+ ```
205
+ Usuario ingresa credenciales → Validacion → Token JWT → Redireccion
206
+ ```
207
+
208
+ ### 2. Recuperacion de Contrasena
209
+
210
+ ```
211
+ Email → Codigo por email → Validacion → Nueva contrasena → Login automatico
212
+ ```
213
+
214
+ ### 3. Navegacion entre Pantallas
215
+
216
+ ```tsx
217
+ const handleScreenChange = (screen, params) => {
218
+ console.log(`Cambiando a: ${screen}`, params);
219
+ // Logica personalizada de navegacion
220
+ };
221
+
222
+ <CrudifyLogin onScreenChange={handleScreenChange} />;
223
+ ```
224
+
225
+ ## 🔐 Integracion con Cookies
226
+
227
+ El componente puede leer configuracion automaticamente desde cookies:
228
+
229
+ ```javascript
230
+ // Configurar desde JavaScript
231
+ document.cookie = "publicApiKey=tu-api-key; path=/";
232
+ document.cookie = "environment=prod; path=/";
233
+ document.cookie = "appName=Mi App; path=/";
234
+ document.cookie = 'loginActions=["forgotPassword","createUser"]; path=/';
235
+ ```
236
+
237
+ ## 🌍 Internacionalizacion
238
+
239
+ ### Idiomas Soportados
240
+
241
+ - **English** (`en`) - Default
242
+ - **Espanol** (`es`)
243
+ - **Personalizado** (via props)
244
+
245
+ ### Cargar traducciones desde URL
246
+
247
+ ```tsx
248
+ <CrudifyLogin translationsUrl="/api/translations/es.json" language="es" />
249
+ ```
250
+
251
+ ## 📊 Integracion con Crudify API
252
+
253
+ El componente incluye acceso completo a la API de Crudify:
254
+
255
+ ```tsx
256
+ import { crudify } from "@nocios/crudify-ui";
257
+
258
+ // Usar directamente en tu app
259
+ const usuarios = await crudify.users.list();
260
+ const perfil = await crudify.users.profile();
261
+ ```
262
+
263
+ ## 🚨 Manejo de Errores
264
+
265
+ ### Codigos de Error Estandar
266
+
267
+ | Codigo | Descripcion | Severidad |
268
+ | ----------------------- | ------------------------ | --------- |
269
+ | `INVALID_CREDENTIALS` | Credenciales incorrectas | warning |
270
+ | `TOO_MANY_REQUESTS` | Demasiados intentos | warning |
271
+ | `NETWORK_ERROR` | Error de conexion | error |
272
+ | `INTERNAL_SERVER_ERROR` | Error del servidor | error |
273
+
274
+ ### Callback de Errores
275
+
276
+ ```tsx
277
+ const handleError = (error: string) => {
278
+ // Notificar al usuario
279
+ toast.error(error);
280
+
281
+ // Log para debugging
282
+ console.error("Login error:", error);
283
+
284
+ // Analytics
285
+ analytics.track("login_error", { error });
286
+ };
287
+
288
+ <CrudifyLogin onError={handleError} />;
289
+ ```
290
+
291
+ ## 🔄 Estados del Componente
292
+
293
+ ### Estados de Carga
294
+
295
+ - Login en progreso
296
+ - Validacion de codigo
297
+ - Envio de email de recuperacion
298
+ - Reseteo de contrasena
299
+
300
+ ### Estados de Error
301
+
302
+ - Errores por campo especifico
303
+ - Errores globales
304
+ - Errores de red/servidor
305
+
306
+ ## 📱 Ejemplo Avanzado
307
+
308
+ ```tsx
309
+ import React from "react";
310
+ import { CrudifyLogin, useUserProfile, secureSessionStorage, handleCrudifyError } from "@nocios/crudify-ui";
311
+
312
+ function AuthenticatedApp() {
313
+ const { userProfile, loading } = useUserProfile();
314
+
315
+ // Si hay usuario, mostrar app
316
+ if (userProfile) {
317
+ return <MainApp user={userProfile} />;
318
+ }
319
+
320
+ // Si esta cargando, mostrar spinner
321
+ if (loading) {
322
+ return <div>Verificando autenticacion...</div>;
323
+ }
324
+
325
+ // Mostrar login
326
+ return (
327
+ <div
328
+ style={{
329
+ display: "flex",
330
+ justifyContent: "center",
331
+ alignItems: "center",
332
+ minHeight: "100vh",
333
+ backgroundColor: "#f5f5f5",
334
+ }}
335
+ >
336
+ <div style={{ width: "400px", padding: "2rem" }}>
337
+ <CrudifyLogin
338
+ config={{
339
+ publicApiKey: process.env.REACT_APP_CRUDIFY_API_KEY,
340
+ env: process.env.NODE_ENV || "dev",
341
+ appName: "Mi Aplicacion",
342
+ logo: "/logo.svg",
343
+ colors: {
344
+ primaryColor: "#1066BA",
345
+ },
346
+ loginActions: ["forgotPassword", "createUser"],
347
+ }}
348
+ onLoginSuccess={(token, redirectUrl) => {
349
+ secureSessionStorage.setToken(token);
350
+ // Force re-render para activar useUserProfile
351
+ window.location.reload();
352
+ }}
353
+ onError={(error) => {
354
+ console.error("Authentication error:", error);
355
+ // Mostrar notificacion de error
356
+ }}
357
+ onExternalNavigate={(path) => {
358
+ window.location.href = path;
359
+ }}
360
+ language="es"
361
+ redirectUrl="/dashboard"
362
+ autoReadFromCookies={true}
363
+ />
364
+ </div>
365
+ </div>
366
+ );
367
+ }
368
+
369
+ export default AuthenticatedApp;
370
+ ```
371
+
372
+ ---
373
+
374
+ **Version:** 1.0.0+
375
+ **Mantenido por:** Equipo Crudify
package/dist/index.d.mts CHANGED
@@ -1,11 +1,10 @@
1
- import * as _nocios_crudify_browser from '@nocios/crudify-browser';
2
1
  export * from '@nocios/crudify-browser';
3
2
  export { default as crudify } from '@nocios/crudify-browser';
4
3
  import React from 'react';
5
4
 
6
5
  type BoxScreenType = "login" | "signUp" | "forgotPassword" | "resetPassword" | "checkCode";
7
6
  interface CrudifyLoginConfig {
8
- publicApiKey?: string;
7
+ publicApiKey?: string | null;
9
8
  env?: "dev" | "stg" | "api" | "prod";
10
9
  appName?: string;
11
10
  logo?: string;
@@ -21,7 +20,8 @@ interface CrudifyLoginTranslations {
21
20
  }
22
21
  interface CrudifyLoginProps {
23
22
  config?: CrudifyLoginConfig;
24
- onNavigate?: (path: string) => void;
23
+ onScreenChange?: (screen: BoxScreenType, params?: Record<string, string>) => void;
24
+ onExternalNavigate?: (path: string) => void;
25
25
  onLoginSuccess?: (token: string, redirectUrl?: string) => void;
26
26
  onError?: (error: string) => void;
27
27
  initialScreen?: BoxScreenType;
@@ -34,13 +34,94 @@ interface CrudifyLoginProps {
34
34
 
35
35
  declare const CrudifyLogin: React.FC<CrudifyLoginProps>;
36
36
 
37
+ interface CrudifyApiResponse<T = unknown> {
38
+ success: boolean;
39
+ data?: T;
40
+ errors?: string | Record<string, string[]> | string[];
41
+ errorCode?: string;
42
+ fieldsWarning?: Record<string, string[]>;
43
+ }
44
+ interface CrudifyTransactionResponse {
45
+ success: boolean;
46
+ data?: TransactionResponseData[];
47
+ errors?: string | Record<string, string[]>;
48
+ errorCode?: string;
49
+ }
50
+ interface TransactionResponseData {
51
+ response?: {
52
+ status: string;
53
+ data?: unknown;
54
+ message?: string;
55
+ };
56
+ errors?: string | Record<string, string[]>;
57
+ }
58
+ interface UserProfile {
59
+ id: string | number;
60
+ email: string;
61
+ username?: string;
62
+ firstName?: string;
63
+ lastName?: string;
64
+ fullName?: string;
65
+ avatar?: string;
66
+ role?: string;
67
+ permissions?: string[];
68
+ lastLogin?: string;
69
+ isActive?: boolean;
70
+ createdAt?: string;
71
+ updatedAt?: string;
72
+ [key: string]: unknown;
73
+ }
74
+ interface LoginResponse {
75
+ token: string;
76
+ user?: UserProfile;
77
+ expiresIn?: number;
78
+ refreshToken?: string;
79
+ }
80
+ interface LoginRequest {
81
+ identifier: string;
82
+ password: string;
83
+ }
84
+ interface ForgotPasswordRequest {
85
+ email: string;
86
+ }
87
+ interface ResetPasswordRequest {
88
+ email: string;
89
+ code: string;
90
+ newPassword: string;
91
+ }
92
+ interface ValidateCodeRequest {
93
+ email: string;
94
+ codePassword: string;
95
+ }
96
+ interface JwtPayload {
97
+ sub?: string;
98
+ email?: string;
99
+ username?: string;
100
+ iat?: number;
101
+ exp?: number;
102
+ iss?: string;
103
+ aud?: string;
104
+ [key: string]: unknown;
105
+ }
106
+ interface ApiError {
107
+ code: string;
108
+ message: string;
109
+ field?: string;
110
+ details?: Record<string, unknown>;
111
+ }
112
+ interface ValidationError {
113
+ field: string;
114
+ message: string;
115
+ code: string;
116
+ }
117
+
37
118
  interface UseUserProfileOptions {
38
119
  autoFetch?: boolean;
39
120
  retryOnError?: boolean;
40
121
  maxRetries?: number;
41
122
  }
42
123
  interface UseUserProfileReturn {
43
- userProfile: any | null;
124
+ userProfile: UserProfile | null;
44
125
  loading: boolean;
45
126
  error: string | null;
46
127
  refreshProfile: () => Promise<void>;
@@ -53,21 +134,16 @@ interface UseCrudifyLoginOptions {
53
134
  showSuccessNotifications?: boolean;
54
135
  }
55
136
  declare const useCrudifyLogin: (config: CrudifyLoginConfig, _options?: UseCrudifyLoginOptions) => {
56
- crudify: {
57
- login: (identifier: string, password: string) => Promise<_nocios_crudify_browser.CrudifyResponse>;
58
- transaction: (data: any, options?: any) => Promise<_nocios_crudify_browser.CrudifyResponse>;
59
- } | null;
137
+ config: {
138
+ publicApiKey: string | null;
139
+ env: "dev" | "stg" | "prod";
140
+ appName: string;
141
+ loginActions: string[];
142
+ };
60
143
  };
61
144
 
62
- interface JWTPayload {
63
- email?: string;
145
+ interface JWTPayload extends JwtPayload {
64
146
  "cognito:username"?: string;
65
- sub?: string;
66
- exp?: number;
67
- iat?: number;
68
- iss?: string;
69
- aud?: string;
70
- [key: string]: any;
71
147
  }
72
148
  declare const decodeJwtSafely: (token: string) => JWTPayload | null;
73
149
  declare const getCurrentUserEmail: () => string | null;
@@ -89,4 +165,57 @@ declare class SecureStorage {
89
165
  declare const secureSessionStorage: SecureStorage;
90
166
  declare const secureLocalStorage: SecureStorage;
91
167
 
92
- export { type BoxScreenType, CrudifyLogin, type CrudifyLoginConfig, type CrudifyLoginProps, type CrudifyLoginTranslations, decodeJwtSafely, getCookie, getCurrentUserEmail, isTokenExpired, secureLocalStorage, secureSessionStorage, useCrudifyLogin, useUserProfile };
168
+ declare const ERROR_CODES: {
169
+ readonly INVALID_CREDENTIALS: "INVALID_CREDENTIALS";
170
+ readonly UNAUTHORIZED: "UNAUTHORIZED";
171
+ readonly INVALID_API_KEY: "INVALID_API_KEY";
172
+ readonly USER_NOT_FOUND: "USER_NOT_FOUND";
173
+ readonly USER_NOT_ACTIVE: "USER_NOT_ACTIVE";
174
+ readonly NO_PERMISSION: "NO_PERMISSION";
175
+ readonly ITEM_NOT_FOUND: "ITEM_NOT_FOUND";
176
+ readonly NOT_FOUND: "NOT_FOUND";
177
+ readonly IN_USE: "IN_USE";
178
+ readonly FIELD_ERROR: "FIELD_ERROR";
179
+ readonly BAD_REQUEST: "BAD_REQUEST";
180
+ readonly INVALID_EMAIL: "INVALID_EMAIL";
181
+ readonly INVALID_CODE: "INVALID_CODE";
182
+ readonly INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR";
183
+ readonly DATABASE_CONNECTION_ERROR: "DATABASE_CONNECTION_ERROR";
184
+ readonly INVALID_CONFIGURATION: "INVALID_CONFIGURATION";
185
+ readonly UNKNOWN_OPERATION: "UNKNOWN_OPERATION";
186
+ readonly TOO_MANY_REQUESTS: "TOO_MANY_REQUESTS";
187
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
188
+ readonly TIMEOUT_ERROR: "TIMEOUT_ERROR";
189
+ };
190
+ type ErrorCode = typeof ERROR_CODES[keyof typeof ERROR_CODES];
191
+ type ErrorSeverity = 'info' | 'warning' | 'error' | 'critical';
192
+ declare const ERROR_SEVERITY_MAP: Record<ErrorCode, ErrorSeverity>;
193
+ interface ParsedError {
194
+ code: ErrorCode;
195
+ message: string;
196
+ severity: ErrorSeverity;
197
+ field?: string;
198
+ details?: Record<string, unknown>;
199
+ }
200
+ /**
201
+ * Parse a Crudify API response and extract standardized error information
202
+ */
203
+ declare function parseApiError(response: unknown): ParsedError[];
204
+ /**
205
+ * Parse transaction response errors
206
+ */
207
+ declare function parseTransactionError(response: unknown): ParsedError[];
208
+ /**
209
+ * Get a human-readable error message for an error code
210
+ */
211
+ declare function getErrorMessage(code: ErrorCode): string;
212
+ /**
213
+ * Handle JavaScript/Network errors and convert to ParsedError
214
+ */
215
+ declare function parseJavaScriptError(error: unknown): ParsedError;
216
+ /**
217
+ * Universal error handler that can process any type of error from Crudify APIs
218
+ */
219
+ declare function handleCrudifyError(error: unknown): ParsedError[];
220
+
221
+ export { type ApiError, type BoxScreenType, type CrudifyApiResponse, CrudifyLogin, type CrudifyLoginConfig, type CrudifyLoginProps, type CrudifyLoginTranslations, type CrudifyTransactionResponse, ERROR_CODES, ERROR_SEVERITY_MAP, type ErrorCode, type ErrorSeverity, type ForgotPasswordRequest, type JwtPayload, type LoginRequest, type LoginResponse, type ParsedError, type ResetPasswordRequest, type TransactionResponseData, type UserProfile, type ValidateCodeRequest, type ValidationError, decodeJwtSafely, getCookie, getCurrentUserEmail, getErrorMessage, handleCrudifyError, isTokenExpired, parseApiError, parseJavaScriptError, parseTransactionError, secureLocalStorage, secureSessionStorage, useCrudifyLogin, useUserProfile };