@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/dist/index.mjs CHANGED
@@ -3,8 +3,7 @@ import { default as default2 } from "@nocios/crudify-browser";
3
3
  export * from "@nocios/crudify-browser";
4
4
 
5
5
  // src/components/CrudifyLogin/index.tsx
6
- import React2, { useState as useState7, useMemo as useMemo3 } from "react";
7
- import { Box as Box5, Typography as Typography5 } from "@mui/material";
6
+ import { Box as Box6, Typography as Typography6 } from "@mui/material";
8
7
 
9
8
  // src/components/CrudifyLogin/context/I18nProvider.tsx
10
9
  import { createContext, useContext, useMemo } from "react";
@@ -94,8 +93,290 @@ var useTranslation = () => {
94
93
  return context;
95
94
  };
96
95
 
96
+ // src/components/CrudifyLogin/context/CrudifyProvider.tsx
97
+ import { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState2 } from "react";
98
+ import crudify from "@nocios/crudify-browser";
99
+ import { jsx as jsx2 } from "react/jsx-runtime";
100
+ var CrudifyContext = createContext2(void 0);
101
+ var CrudifyProvider = ({ config, children }) => {
102
+ const [isLoading, setIsLoading] = useState2(true);
103
+ const [error, setError] = useState2(null);
104
+ const [isInitialized, setIsInitialized] = useState2(false);
105
+ const [initializationKey, setInitializationKey] = useState2("");
106
+ useEffect2(() => {
107
+ if (!config.publicApiKey) {
108
+ setError("No publicApiKey provided");
109
+ setIsLoading(false);
110
+ setIsInitialized(false);
111
+ return;
112
+ }
113
+ const currentKey = `${config.publicApiKey}-${config.env}`;
114
+ if (currentKey === initializationKey && isInitialized) {
115
+ setIsLoading(false);
116
+ return;
117
+ }
118
+ const initializeCrudify = async () => {
119
+ setIsLoading(true);
120
+ setError(null);
121
+ setIsInitialized(false);
122
+ try {
123
+ crudify.config(config.env || "prod");
124
+ await crudify.init(config.publicApiKey, "none");
125
+ if (typeof crudify.transaction === "function" && typeof crudify.login === "function") {
126
+ setIsInitialized(true);
127
+ setInitializationKey(currentKey);
128
+ } else {
129
+ throw new Error("Crudify methods not properly initialized");
130
+ }
131
+ } catch (err) {
132
+ const errorMessage = err instanceof Error ? err.message : "Failed to initialize Crudify";
133
+ setError(errorMessage);
134
+ setIsInitialized(false);
135
+ } finally {
136
+ setIsLoading(false);
137
+ }
138
+ };
139
+ initializeCrudify();
140
+ }, [config.publicApiKey, config.env, initializationKey, isInitialized]);
141
+ const value = {
142
+ crudify: isInitialized ? crudify : null,
143
+ isLoading,
144
+ error,
145
+ isInitialized
146
+ };
147
+ return /* @__PURE__ */ jsx2(CrudifyContext.Provider, { value, children });
148
+ };
149
+ var useCrudify = () => {
150
+ const context = useContext2(CrudifyContext);
151
+ if (context === void 0) {
152
+ throw new Error("useCrudify must be used within a CrudifyProvider");
153
+ }
154
+ return context;
155
+ };
156
+
157
+ // src/components/CrudifyLogin/context/LoginStateProvider.tsx
158
+ import { createContext as createContext3, useContext as useContext3, useReducer, useEffect as useEffect3 } from "react";
159
+
160
+ // src/components/CrudifyLogin/utils/cookies.ts
161
+ var getCookie = (name) => {
162
+ const match = document.cookie.match(new RegExp("(^|;)\\s*" + name + "=([^;]+)"));
163
+ return match ? match[2] : null;
164
+ };
165
+
166
+ // src/components/CrudifyLogin/context/LoginStateProvider.tsx
167
+ import { jsx as jsx3 } from "react/jsx-runtime";
168
+ var initialState = {
169
+ currentScreen: "login",
170
+ searchParams: {},
171
+ formData: {
172
+ username: "",
173
+ password: "",
174
+ email: "",
175
+ code: "",
176
+ newPassword: "",
177
+ confirmPassword: ""
178
+ },
179
+ loading: false,
180
+ errors: {
181
+ global: []
182
+ },
183
+ emailSent: false,
184
+ codeAlreadyExists: false,
185
+ codeValidated: false,
186
+ fromCodeVerification: false,
187
+ config: {}
188
+ };
189
+ function loginStateReducer(state, action) {
190
+ switch (action.type) {
191
+ case "SET_SCREEN":
192
+ return {
193
+ ...state,
194
+ currentScreen: action.payload.screen,
195
+ searchParams: action.payload.params || state.searchParams,
196
+ // Clear form errors when changing screens
197
+ errors: { global: [] }
198
+ };
199
+ case "SET_SEARCH_PARAMS":
200
+ return {
201
+ ...state,
202
+ searchParams: action.payload
203
+ };
204
+ case "UPDATE_FORM_DATA":
205
+ return {
206
+ ...state,
207
+ formData: {
208
+ ...state.formData,
209
+ ...action.payload
210
+ },
211
+ // Clear related errors when updating form data
212
+ errors: {
213
+ ...state.errors,
214
+ ...Object.keys(action.payload).reduce((acc, key) => ({
215
+ ...acc,
216
+ [key]: void 0
217
+ }), {})
218
+ }
219
+ };
220
+ case "SET_LOADING":
221
+ return {
222
+ ...state,
223
+ loading: action.payload
224
+ };
225
+ case "SET_ERRORS":
226
+ return {
227
+ ...state,
228
+ errors: {
229
+ ...state.errors,
230
+ ...action.payload
231
+ }
232
+ };
233
+ case "CLEAR_ERRORS":
234
+ return {
235
+ ...state,
236
+ errors: { global: [] }
237
+ };
238
+ case "SET_EMAIL_SENT":
239
+ return {
240
+ ...state,
241
+ emailSent: action.payload
242
+ };
243
+ case "SET_CODE_ALREADY_EXISTS":
244
+ return {
245
+ ...state,
246
+ codeAlreadyExists: action.payload
247
+ };
248
+ case "SET_CODE_VALIDATED":
249
+ return {
250
+ ...state,
251
+ codeValidated: action.payload
252
+ };
253
+ case "SET_FROM_CODE_VERIFICATION":
254
+ return {
255
+ ...state,
256
+ fromCodeVerification: action.payload
257
+ };
258
+ case "RESET_FORM":
259
+ return {
260
+ ...state,
261
+ formData: initialState.formData,
262
+ errors: { global: [] },
263
+ loading: false,
264
+ emailSent: false,
265
+ codeAlreadyExists: false,
266
+ codeValidated: false,
267
+ fromCodeVerification: false
268
+ };
269
+ case "INIT_CONFIG":
270
+ return {
271
+ ...state,
272
+ config: action.payload
273
+ };
274
+ default:
275
+ return state;
276
+ }
277
+ }
278
+ var LoginStateContext = createContext3(void 0);
279
+ var LoginStateProvider = ({
280
+ children,
281
+ initialScreen = "login",
282
+ config: providedConfig,
283
+ autoReadFromCookies = true
284
+ }) => {
285
+ const [state, dispatch] = useReducer(loginStateReducer, {
286
+ ...initialState,
287
+ currentScreen: initialScreen
288
+ });
289
+ useEffect3(() => {
290
+ const buildFinalConfig = () => {
291
+ let cookieConfig = {};
292
+ if (autoReadFromCookies) {
293
+ try {
294
+ const encodedLogo = getCookie("logo");
295
+ if (encodedLogo) {
296
+ const decodedLogo = decodeURIComponent(encodedLogo);
297
+ if (decodedLogo.startsWith("http")) {
298
+ cookieConfig.logo = decodedLogo;
299
+ }
300
+ }
301
+ const colorsCookie = getCookie("colors");
302
+ if (colorsCookie) {
303
+ const decodedColorsString = decodeURIComponent(colorsCookie);
304
+ const parsedColors = JSON.parse(decodedColorsString);
305
+ cookieConfig.colors = { primaryColor: "#1066BA", ...parsedColors };
306
+ } else {
307
+ cookieConfig.colors = { primaryColor: "#1066BA" };
308
+ }
309
+ } catch (e) {
310
+ console.error("Error reading configuration from cookies:", e);
311
+ cookieConfig.colors = { primaryColor: "#1066BA" };
312
+ }
313
+ }
314
+ return {
315
+ publicApiKey: providedConfig?.publicApiKey,
316
+ env: providedConfig?.env,
317
+ appName: providedConfig?.appName,
318
+ logo: providedConfig?.logo || cookieConfig.logo,
319
+ colors: { ...cookieConfig.colors, ...providedConfig?.colors },
320
+ loginActions: providedConfig?.loginActions
321
+ };
322
+ };
323
+ dispatch({ type: "INIT_CONFIG", payload: buildFinalConfig() });
324
+ }, [providedConfig, autoReadFromCookies]);
325
+ useEffect3(() => {
326
+ const urlParams = new URLSearchParams(window.location.search);
327
+ const paramsObject = {};
328
+ urlParams.forEach((value2, key) => {
329
+ paramsObject[key] = value2;
330
+ });
331
+ if (Object.keys(paramsObject).length > 0) {
332
+ dispatch({ type: "SET_SEARCH_PARAMS", payload: paramsObject });
333
+ }
334
+ if (initialScreen === "checkCode" && paramsObject.email) {
335
+ dispatch({
336
+ type: "UPDATE_FORM_DATA",
337
+ payload: { email: paramsObject.email, code: paramsObject.code || "" }
338
+ });
339
+ }
340
+ if (initialScreen === "resetPassword" && paramsObject.link) {
341
+ dispatch({ type: "SET_SEARCH_PARAMS", payload: paramsObject });
342
+ }
343
+ }, [initialScreen]);
344
+ const setScreen = (screen2, params) => {
345
+ dispatch({ type: "SET_SCREEN", payload: { screen: screen2, params } });
346
+ };
347
+ const updateFormData = (data) => {
348
+ dispatch({ type: "UPDATE_FORM_DATA", payload: data });
349
+ };
350
+ const setFieldError = (field, error) => {
351
+ dispatch({ type: "SET_ERRORS", payload: { [field]: error } });
352
+ };
353
+ const clearErrors = () => {
354
+ dispatch({ type: "CLEAR_ERRORS" });
355
+ };
356
+ const setLoading = (loading) => {
357
+ dispatch({ type: "SET_LOADING", payload: loading });
358
+ };
359
+ const value = {
360
+ state,
361
+ dispatch,
362
+ setScreen,
363
+ updateFormData,
364
+ setFieldError,
365
+ clearErrors,
366
+ setLoading
367
+ };
368
+ return /* @__PURE__ */ jsx3(LoginStateContext.Provider, { value, children });
369
+ };
370
+ var useLoginState = () => {
371
+ const context = useContext3(LoginStateContext);
372
+ if (context === void 0) {
373
+ throw new Error("useLoginState must be used within a LoginStateProvider");
374
+ }
375
+ return context;
376
+ };
377
+
97
378
  // src/components/CrudifyLogin/Forms/LoginForm.tsx
98
- import { useState as useState2, useEffect as useEffect2, useRef } from "react";
379
+ import { useEffect as useEffect4, useRef } from "react";
99
380
  import { Typography, TextField, Button, Box, CircularProgress, Alert, Link } from "@mui/material";
100
381
 
101
382
  // src/components/CrudifyLogin/utils/secureStorage.ts
@@ -207,45 +488,302 @@ var SecureStorage = class {
207
488
  var secureSessionStorage = new SecureStorage("sessionStorage");
208
489
  var secureLocalStorage = new SecureStorage("localStorage");
209
490
 
491
+ // src/utils/errorHandler.ts
492
+ var ERROR_CODES = {
493
+ // Authentication Errors
494
+ INVALID_CREDENTIALS: "INVALID_CREDENTIALS",
495
+ UNAUTHORIZED: "UNAUTHORIZED",
496
+ INVALID_API_KEY: "INVALID_API_KEY",
497
+ USER_NOT_FOUND: "USER_NOT_FOUND",
498
+ USER_NOT_ACTIVE: "USER_NOT_ACTIVE",
499
+ NO_PERMISSION: "NO_PERMISSION",
500
+ // Data Errors
501
+ ITEM_NOT_FOUND: "ITEM_NOT_FOUND",
502
+ NOT_FOUND: "NOT_FOUND",
503
+ IN_USE: "IN_USE",
504
+ // Validation Errors
505
+ FIELD_ERROR: "FIELD_ERROR",
506
+ BAD_REQUEST: "BAD_REQUEST",
507
+ INVALID_EMAIL: "INVALID_EMAIL",
508
+ INVALID_CODE: "INVALID_CODE",
509
+ // System Errors
510
+ INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR",
511
+ DATABASE_CONNECTION_ERROR: "DATABASE_CONNECTION_ERROR",
512
+ INVALID_CONFIGURATION: "INVALID_CONFIGURATION",
513
+ UNKNOWN_OPERATION: "UNKNOWN_OPERATION",
514
+ // Rate Limiting
515
+ TOO_MANY_REQUESTS: "TOO_MANY_REQUESTS",
516
+ // Network Errors
517
+ NETWORK_ERROR: "NETWORK_ERROR",
518
+ TIMEOUT_ERROR: "TIMEOUT_ERROR"
519
+ };
520
+ var ERROR_SEVERITY_MAP = {
521
+ // Authentication - warning (user can fix)
522
+ [ERROR_CODES.INVALID_CREDENTIALS]: "warning",
523
+ [ERROR_CODES.UNAUTHORIZED]: "warning",
524
+ [ERROR_CODES.INVALID_API_KEY]: "error",
525
+ [ERROR_CODES.USER_NOT_FOUND]: "warning",
526
+ [ERROR_CODES.USER_NOT_ACTIVE]: "warning",
527
+ [ERROR_CODES.NO_PERMISSION]: "warning",
528
+ // Data - info (might be expected)
529
+ [ERROR_CODES.ITEM_NOT_FOUND]: "info",
530
+ [ERROR_CODES.NOT_FOUND]: "info",
531
+ [ERROR_CODES.IN_USE]: "warning",
532
+ // Validation - warning (user input issue)
533
+ [ERROR_CODES.FIELD_ERROR]: "warning",
534
+ [ERROR_CODES.BAD_REQUEST]: "warning",
535
+ [ERROR_CODES.INVALID_EMAIL]: "warning",
536
+ [ERROR_CODES.INVALID_CODE]: "warning",
537
+ // System - error (server issue)
538
+ [ERROR_CODES.INTERNAL_SERVER_ERROR]: "error",
539
+ [ERROR_CODES.DATABASE_CONNECTION_ERROR]: "error",
540
+ [ERROR_CODES.INVALID_CONFIGURATION]: "error",
541
+ [ERROR_CODES.UNKNOWN_OPERATION]: "error",
542
+ // Rate limiting - warning with higher duration
543
+ [ERROR_CODES.TOO_MANY_REQUESTS]: "warning",
544
+ // Network - error
545
+ [ERROR_CODES.NETWORK_ERROR]: "error",
546
+ [ERROR_CODES.TIMEOUT_ERROR]: "error"
547
+ };
548
+ function parseApiError(response) {
549
+ const errors = [];
550
+ try {
551
+ const apiResponse = response;
552
+ if (apiResponse.data && typeof apiResponse.data === "object") {
553
+ const responseData = apiResponse.data;
554
+ if (responseData.response) {
555
+ const { status, fieldsWarning } = responseData.response;
556
+ if (fieldsWarning && typeof fieldsWarning === "object") {
557
+ Object.entries(fieldsWarning).forEach(([field, messages]) => {
558
+ if (Array.isArray(messages) && messages.length > 0) {
559
+ errors.push({
560
+ code: ERROR_CODES.FIELD_ERROR,
561
+ message: messages[0],
562
+ severity: "warning",
563
+ field
564
+ });
565
+ }
566
+ });
567
+ }
568
+ if (status && typeof status === "string") {
569
+ const errorCode = status;
570
+ if (ERROR_SEVERITY_MAP[errorCode]) {
571
+ errors.push({
572
+ code: errorCode,
573
+ message: getErrorMessage(errorCode),
574
+ severity: ERROR_SEVERITY_MAP[errorCode]
575
+ });
576
+ }
577
+ }
578
+ }
579
+ }
580
+ if (apiResponse.errors) {
581
+ if (typeof apiResponse.errors === "string") {
582
+ errors.push({
583
+ code: ERROR_CODES.BAD_REQUEST,
584
+ message: apiResponse.errors,
585
+ severity: "warning"
586
+ });
587
+ } else if (typeof apiResponse.errors === "object") {
588
+ const errorObj = apiResponse.errors;
589
+ Object.entries(errorObj).forEach(([field, messages]) => {
590
+ if (Array.isArray(messages) && messages.length > 0) {
591
+ if (field === "_error") {
592
+ messages.forEach((msg) => {
593
+ const errorCode = typeof msg === "string" && isValidErrorCode(msg) ? msg : ERROR_CODES.BAD_REQUEST;
594
+ errors.push({
595
+ code: errorCode,
596
+ message: typeof msg === "string" ? msg : getErrorMessage(errorCode),
597
+ severity: ERROR_SEVERITY_MAP[errorCode] || "warning"
598
+ });
599
+ });
600
+ } else if (field === "_graphql") {
601
+ messages.forEach((msg) => {
602
+ if (typeof msg === "string") {
603
+ const errorCode = isValidErrorCode(msg) ? msg : ERROR_CODES.BAD_REQUEST;
604
+ errors.push({
605
+ code: errorCode,
606
+ message: getErrorMessage(errorCode),
607
+ severity: ERROR_SEVERITY_MAP[errorCode] || "warning"
608
+ });
609
+ }
610
+ });
611
+ } else {
612
+ errors.push({
613
+ code: ERROR_CODES.FIELD_ERROR,
614
+ message: typeof messages[0] === "string" ? messages[0] : "Validation error",
615
+ severity: "warning",
616
+ field
617
+ });
618
+ }
619
+ }
620
+ });
621
+ }
622
+ }
623
+ if (errors.length === 0 && apiResponse.success === false) {
624
+ errors.push({
625
+ code: ERROR_CODES.BAD_REQUEST,
626
+ message: "Request failed",
627
+ severity: "warning"
628
+ });
629
+ }
630
+ } catch (error) {
631
+ errors.push({
632
+ code: ERROR_CODES.INTERNAL_SERVER_ERROR,
633
+ message: "Failed to parse error response",
634
+ severity: "error",
635
+ details: { originalError: error }
636
+ });
637
+ }
638
+ return errors.length > 0 ? errors : [{
639
+ code: ERROR_CODES.INTERNAL_SERVER_ERROR,
640
+ message: "Unknown error occurred",
641
+ severity: "error"
642
+ }];
643
+ }
644
+ function parseTransactionError(response) {
645
+ try {
646
+ const transactionResponse = response;
647
+ if (transactionResponse.data && Array.isArray(transactionResponse.data)) {
648
+ const errors = [];
649
+ transactionResponse.data.forEach((item, index) => {
650
+ if (item.response?.status === "TOO_MANY_REQUESTS") {
651
+ errors.push({
652
+ code: ERROR_CODES.TOO_MANY_REQUESTS,
653
+ message: getErrorMessage(ERROR_CODES.TOO_MANY_REQUESTS),
654
+ severity: "warning",
655
+ details: { transactionIndex: index }
656
+ });
657
+ } else if (!item.response || item.response.status !== "OK") {
658
+ errors.push({
659
+ code: ERROR_CODES.BAD_REQUEST,
660
+ message: "Transaction failed",
661
+ severity: "warning",
662
+ details: { transactionIndex: index, response: item.response }
663
+ });
664
+ }
665
+ });
666
+ return errors;
667
+ }
668
+ return parseApiError(response);
669
+ } catch (error) {
670
+ return [{
671
+ code: ERROR_CODES.INTERNAL_SERVER_ERROR,
672
+ message: "Failed to parse transaction error",
673
+ severity: "error",
674
+ details: { originalError: error }
675
+ }];
676
+ }
677
+ }
678
+ function isValidErrorCode(code) {
679
+ return Object.values(ERROR_CODES).includes(code);
680
+ }
681
+ function getErrorMessage(code) {
682
+ const messages = {
683
+ [ERROR_CODES.INVALID_CREDENTIALS]: "Invalid email or password",
684
+ [ERROR_CODES.UNAUTHORIZED]: "You are not authorized to perform this action",
685
+ [ERROR_CODES.INVALID_API_KEY]: "Invalid API key",
686
+ [ERROR_CODES.USER_NOT_FOUND]: "User not found",
687
+ [ERROR_CODES.USER_NOT_ACTIVE]: "User account is not active",
688
+ [ERROR_CODES.NO_PERMISSION]: "You do not have permission to perform this action",
689
+ [ERROR_CODES.ITEM_NOT_FOUND]: "Item not found",
690
+ [ERROR_CODES.NOT_FOUND]: "Resource not found",
691
+ [ERROR_CODES.IN_USE]: "Resource is currently in use",
692
+ [ERROR_CODES.FIELD_ERROR]: "Validation error",
693
+ [ERROR_CODES.BAD_REQUEST]: "Invalid request",
694
+ [ERROR_CODES.INVALID_EMAIL]: "Please enter a valid email address",
695
+ [ERROR_CODES.INVALID_CODE]: "Invalid or expired code",
696
+ [ERROR_CODES.INTERNAL_SERVER_ERROR]: "Internal server error",
697
+ [ERROR_CODES.DATABASE_CONNECTION_ERROR]: "Database connection error",
698
+ [ERROR_CODES.INVALID_CONFIGURATION]: "Invalid configuration",
699
+ [ERROR_CODES.UNKNOWN_OPERATION]: "Unknown operation",
700
+ [ERROR_CODES.TOO_MANY_REQUESTS]: "Too many requests. Please try again later.",
701
+ [ERROR_CODES.NETWORK_ERROR]: "Network error. Please check your connection.",
702
+ [ERROR_CODES.TIMEOUT_ERROR]: "Request timed out. Please try again."
703
+ };
704
+ return messages[code] || "An unknown error occurred";
705
+ }
706
+ function parseJavaScriptError(error) {
707
+ if (error instanceof Error) {
708
+ if (error.name === "AbortError") {
709
+ return {
710
+ code: ERROR_CODES.TIMEOUT_ERROR,
711
+ message: "Request was cancelled",
712
+ severity: "info"
713
+ };
714
+ }
715
+ if (error.message.includes("NetworkError") || error.message.includes("Failed to fetch")) {
716
+ return {
717
+ code: ERROR_CODES.NETWORK_ERROR,
718
+ message: getErrorMessage(ERROR_CODES.NETWORK_ERROR),
719
+ severity: "error"
720
+ };
721
+ }
722
+ return {
723
+ code: ERROR_CODES.INTERNAL_SERVER_ERROR,
724
+ message: error.message || "An unexpected error occurred",
725
+ severity: "error",
726
+ details: { originalError: error }
727
+ };
728
+ }
729
+ return {
730
+ code: ERROR_CODES.INTERNAL_SERVER_ERROR,
731
+ message: "An unknown error occurred",
732
+ severity: "error",
733
+ details: { originalError: error }
734
+ };
735
+ }
736
+ function handleCrudifyError(error) {
737
+ if (error instanceof Error) {
738
+ return [parseJavaScriptError(error)];
739
+ }
740
+ if (typeof error === "object" && error !== null) {
741
+ const response = error;
742
+ if (response.data && Array.isArray(response.data)) {
743
+ return parseTransactionError(error);
744
+ }
745
+ return parseApiError(error);
746
+ }
747
+ return [{
748
+ code: ERROR_CODES.INTERNAL_SERVER_ERROR,
749
+ message: "An unknown error occurred",
750
+ severity: "error",
751
+ details: { originalError: error }
752
+ }];
753
+ }
754
+
210
755
  // src/components/CrudifyLogin/Forms/LoginForm.tsx
211
- import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
212
- var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/", searchParams, crudify: crudify3 }) => {
213
- const [username, setUsername] = useState2("");
214
- const [password, setPassword] = useState2("");
215
- const [loading, setLoading] = useState2(false);
216
- const [errors, setErrors] = useState2([]);
217
- const [helperTextEmail, setHelperTextEmail] = useState2(null);
218
- const [helperTextPassword, setHelperTextPassword] = useState2(null);
756
+ import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
757
+ var LoginForm = ({ onScreenChange, onExternalNavigate, onLoginSuccess, onError, redirectUrl = "/" }) => {
758
+ const { crudify: crudify3 } = useCrudify();
759
+ const { state, updateFormData, setFieldError, clearErrors, setLoading } = useLoginState();
219
760
  const { t } = useTranslation();
220
761
  const usernameInputRef = useRef(null);
221
762
  const getRedirectUrl = () => {
222
- if (searchParams) {
223
- const redirectParam = searchParams.get("redirect");
224
- if (redirectParam) {
225
- try {
226
- const decodedPath = decodeURIComponent(redirectParam);
227
- if (decodedPath.startsWith("/") && !decodedPath.startsWith("//")) {
228
- return decodedPath;
229
- }
230
- } catch (error) {
763
+ if (state.searchParams.redirect) {
764
+ try {
765
+ const decodedPath = decodeURIComponent(state.searchParams.redirect);
766
+ if (decodedPath.startsWith("/") && !decodedPath.startsWith("//")) {
767
+ return decodedPath;
231
768
  }
769
+ } catch (error) {
232
770
  }
233
771
  }
234
772
  return redirectUrl || "/";
235
773
  };
236
- useEffect2(() => {
774
+ useEffect4(() => {
237
775
  const timer = setTimeout(() => {
238
776
  if (usernameInputRef.current) usernameInputRef.current.focus();
239
777
  }, 100);
240
778
  return () => clearTimeout(timer);
241
779
  }, []);
242
- const getSafeErrorTranslation = (errorCode) => {
780
+ const translateError = (parsedError) => {
243
781
  const possibleKeys = [
244
- `errors.auth.${errorCode}`,
245
- `errors.data.${errorCode}`,
246
- `errors.system.${errorCode}`,
247
- `errors.${errorCode}`,
248
- `login.${errorCode.toLowerCase()}`
782
+ `errors.auth.${parsedError.code}`,
783
+ `errors.data.${parsedError.code}`,
784
+ `errors.system.${parsedError.code}`,
785
+ `errors.${parsedError.code}`,
786
+ `login.${parsedError.code.toLowerCase()}`
249
787
  ];
250
788
  for (const key of possibleKeys) {
251
789
  const translated = t(key);
@@ -253,27 +791,25 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
253
791
  return translated;
254
792
  }
255
793
  }
256
- return t("error.unknown");
794
+ return parsedError.message || t("error.unknown");
257
795
  };
258
796
  const handleLogin = async () => {
259
- if (loading) return;
260
- if (!username.trim()) {
261
- setHelperTextEmail(t("login.usernameRequired"));
797
+ if (state.loading) return;
798
+ if (!state.formData.username.trim()) {
799
+ setFieldError("username", t("login.usernameRequired"));
262
800
  return;
263
801
  }
264
- if (!password.trim()) {
265
- setHelperTextPassword(t("login.passwordRequired"));
802
+ if (!state.formData.password.trim()) {
803
+ setFieldError("password", t("login.passwordRequired"));
266
804
  return;
267
805
  }
268
- setErrors([]);
269
- setHelperTextEmail(null);
270
- setHelperTextPassword(null);
806
+ clearErrors();
271
807
  setLoading(true);
272
808
  try {
273
809
  if (!crudify3) {
274
810
  throw new Error("Crudify not initialized");
275
811
  }
276
- const response = await crudify3.login(username, password);
812
+ const response = await crudify3.login(state.formData.username, state.formData.password);
277
813
  setLoading(false);
278
814
  if (response.success) {
279
815
  secureSessionStorage.setToken(response.data.token);
@@ -288,62 +824,31 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
288
824
  }
289
825
  } catch (error) {
290
826
  setLoading(false);
291
- console.error("Login error:", error);
292
- setErrors([t("error.unknown")]);
827
+ const parsedErrors = handleCrudifyError(error);
828
+ const translatedErrors = parsedErrors.map(translateError);
829
+ setFieldError("global", translatedErrors);
293
830
  if (onError) {
294
- onError(typeof error === "string" ? error : t("error.unknown"));
831
+ onError(translatedErrors.join(", "));
295
832
  }
296
833
  }
297
834
  };
298
835
  const handleLoginError = (response) => {
299
- if (response.data?.response) {
300
- const { data: errorMessage, status, fieldsWarning } = response.data.response;
301
- if (fieldsWarning) {
302
- if (fieldsWarning.username) setHelperTextEmail(fieldsWarning.username[0]);
303
- if (fieldsWarning.password) setHelperTextPassword(fieldsWarning.password[0]);
304
- } else if (status === "INVALID_CREDENTIALS") {
305
- const translatedError = getSafeErrorTranslation(status);
306
- setErrors([translatedError]);
307
- } else if (status === "TOO_MANY_REQUESTS") {
308
- const translatedError = getSafeErrorTranslation(status);
309
- setErrors([translatedError]);
310
- } else if (status) {
311
- setErrors([getSafeErrorTranslation(status)]);
836
+ const parsedErrors = handleCrudifyError(response);
837
+ parsedErrors.forEach((error) => {
838
+ if (error.field) {
839
+ setFieldError(error.field, translateError(error));
312
840
  } else {
313
- setErrors([typeof errorMessage === "string" ? errorMessage : t("error.unknown")]);
314
- }
315
- } else if (response.errors) {
316
- const errors2 = response.errors;
317
- if (typeof errors2 === "string") {
318
- setErrors([errors2]);
319
- } else if (typeof errors2 === "object") {
320
- const hasUsernameError = errors2.username && errors2.username.length > 0;
321
- const hasPasswordError = errors2.password && errors2.password.length > 0;
322
- if (hasUsernameError || hasPasswordError) {
323
- if (hasUsernameError) setHelperTextEmail(errors2.username[0]);
324
- if (hasPasswordError) setHelperTextPassword(errors2.password[0]);
325
- } else if (errors2._error && errors2._error.length > 0) {
326
- const errorMessage = errors2._error[0];
327
- if (typeof errorMessage === "string" && errorMessage.match(/^[A-Z_]+$/)) {
328
- const translatedError = getSafeErrorTranslation(errorMessage);
329
- setErrors([translatedError]);
330
- } else setErrors([errorMessage]);
331
- } else if (errors2._graphql && errors2._graphql[0] === "INVALID_CREDENTIALS") {
332
- setErrors([getSafeErrorTranslation("INVALID_CREDENTIALS")]);
333
- } else {
334
- setErrors([t("error.unknown")]);
335
- }
841
+ const currentGlobalErrors = state.errors.global || [];
842
+ setFieldError("global", [...currentGlobalErrors, translateError(error)]);
336
843
  }
337
- } else {
338
- setErrors([t("error.unknown")]);
339
- }
844
+ });
340
845
  };
341
846
  const handleSubmit = (e) => {
342
847
  e.preventDefault();
343
848
  handleLogin();
344
849
  };
345
850
  const handleKeyDown = (e) => {
346
- if (e.key === "Enter" && !loading) {
851
+ if (e.key === "Enter" && !state.loading) {
347
852
  e.preventDefault();
348
853
  handleLogin();
349
854
  }
@@ -359,7 +864,7 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
359
864
  sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 },
360
865
  children: [
361
866
  /* @__PURE__ */ jsxs(Box, { sx: { mb: 1 }, children: [
362
- /* @__PURE__ */ jsx2(
867
+ /* @__PURE__ */ jsx4(
363
868
  Typography,
364
869
  {
365
870
  variant: "body2",
@@ -369,18 +874,18 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
369
874
  children: t("login.usernameOrEmailLabel")
370
875
  }
371
876
  ),
372
- /* @__PURE__ */ jsx2(
877
+ /* @__PURE__ */ jsx4(
373
878
  TextField,
374
879
  {
375
880
  fullWidth: true,
376
881
  id: "email",
377
882
  name: "email",
378
883
  type: "email",
379
- value: username,
380
- disabled: loading,
381
- onChange: (e) => setUsername(e.target.value),
382
- error: !!helperTextEmail,
383
- helperText: helperTextEmail,
884
+ value: state.formData.username,
885
+ disabled: state.loading,
886
+ onChange: (e) => updateFormData({ username: e.target.value }),
887
+ error: !!state.errors.username,
888
+ helperText: state.errors.username,
384
889
  autoComplete: "email",
385
890
  placeholder: t("login.usernameOrEmailPlaceholder"),
386
891
  inputRef: usernameInputRef,
@@ -389,7 +894,7 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
389
894
  )
390
895
  ] }),
391
896
  /* @__PURE__ */ jsxs(Box, { sx: { mb: 1 }, children: [
392
- /* @__PURE__ */ jsx2(
897
+ /* @__PURE__ */ jsx4(
393
898
  Typography,
394
899
  {
395
900
  variant: "body2",
@@ -399,52 +904,52 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
399
904
  children: t("login.passwordLabel")
400
905
  }
401
906
  ),
402
- /* @__PURE__ */ jsx2(
907
+ /* @__PURE__ */ jsx4(
403
908
  TextField,
404
909
  {
405
910
  fullWidth: true,
406
911
  id: "password",
407
912
  name: "password",
408
913
  type: "password",
409
- value: password,
410
- disabled: loading,
411
- onChange: (e) => setPassword(e.target.value),
412
- error: !!helperTextPassword,
413
- helperText: helperTextPassword,
914
+ value: state.formData.password,
915
+ disabled: state.loading,
916
+ onChange: (e) => updateFormData({ password: e.target.value }),
917
+ error: !!state.errors.password,
918
+ helperText: state.errors.password,
414
919
  autoComplete: "current-password",
415
920
  placeholder: t("login.passwordPlaceholder"),
416
921
  required: true
417
922
  }
418
923
  )
419
924
  ] }),
420
- config.loginActions?.includes("forgotPassword") && /* @__PURE__ */ jsx2(Box, { sx: { display: "flex", justifyContent: "flex-end", alignItems: "center" }, children: /* @__PURE__ */ jsx2(
925
+ state.config.loginActions?.includes("forgotPassword") && /* @__PURE__ */ jsx4(Box, { sx: { display: "flex", justifyContent: "flex-end", alignItems: "center" }, children: /* @__PURE__ */ jsx4(
421
926
  Link,
422
927
  {
423
928
  sx: { cursor: "pointer" },
424
929
  onClick: () => {
425
- const searchString = searchParams ? `?${searchParams.toString()}` : "";
426
- onNavigate?.(`/login/forgotPassword${searchString}`);
930
+ onScreenChange?.("forgotPassword", state.searchParams);
427
931
  },
428
932
  variant: "body2",
429
933
  color: "secondary",
430
934
  children: t("login.forgotPasswordLink")
431
935
  }
432
936
  ) }),
433
- /* @__PURE__ */ jsx2(Button, { disabled: loading, type: "submit", fullWidth: true, variant: "contained", color: "primary", sx: { mt: 1, mb: 2 }, children: loading ? /* @__PURE__ */ jsx2(CircularProgress, { size: 20 }) : t("login.loginButton") })
937
+ /* @__PURE__ */ jsx4(Button, { disabled: state.loading, type: "submit", fullWidth: true, variant: "contained", color: "primary", sx: { mt: 1, mb: 2 }, children: state.loading ? /* @__PURE__ */ jsx4(CircularProgress, { size: 20 }) : t("login.loginButton") })
434
938
  ]
435
939
  }
436
940
  ),
437
- /* @__PURE__ */ jsx2(Box, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx2(Alert, { variant: "filled", sx: { mt: 2 }, severity: "error", children: /* @__PURE__ */ jsx2("div", { children: error }) }, index)) }),
438
- config.loginActions?.includes("createUser") && /* @__PURE__ */ jsxs(Typography, { variant: "body2", align: "center", sx: { color: "text.secondary", mt: 3 }, children: [
941
+ /* @__PURE__ */ jsx4(Box, { children: state.errors.global && state.errors.global.length > 0 && state.errors.global.map((error, index) => /* @__PURE__ */ jsx4(Alert, { variant: "filled", sx: { mt: 2 }, severity: "error", children: /* @__PURE__ */ jsx4("div", { children: error }) }, index)) }),
942
+ state.config.loginActions?.includes("createUser") && /* @__PURE__ */ jsxs(Typography, { variant: "body2", align: "center", sx: { color: "text.secondary", mt: 3 }, children: [
439
943
  t("login.noAccountPrompt"),
440
944
  " ",
441
- /* @__PURE__ */ jsx2(
945
+ /* @__PURE__ */ jsx4(
442
946
  Link,
443
947
  {
444
948
  sx: { cursor: "pointer" },
445
949
  onClick: () => {
446
- const searchString = searchParams ? `?${searchParams.toString()}` : "";
447
- onNavigate?.(`/public/users/create${searchString}`);
950
+ const searchString = Object.keys(state.searchParams).length > 0 ? `?${new URLSearchParams(state.searchParams).toString()}` : "";
951
+ const signupUrl = `/public/users/create${searchString}`;
952
+ onExternalNavigate?.(signupUrl);
448
953
  },
449
954
  fontWeight: "medium",
450
955
  color: "secondary",
@@ -459,8 +964,9 @@ var LoginForm_default = LoginForm;
459
964
  // src/components/CrudifyLogin/Forms/ForgotPasswordForm.tsx
460
965
  import { useState as useState3 } from "react";
461
966
  import { Typography as Typography2, TextField as TextField2, Button as Button2, Box as Box2, CircularProgress as CircularProgress2, Alert as Alert2, Link as Link2 } from "@mui/material";
462
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
463
- var ForgotPasswordForm = ({ onNavigate, onError, crudify: crudify3 }) => {
967
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
968
+ var ForgotPasswordForm = ({ onScreenChange, onError }) => {
969
+ const { crudify: crudify3 } = useCrudify();
464
970
  const [email, setEmail] = useState3("");
465
971
  const [loading, setLoading] = useState3(false);
466
972
  const [errors, setErrors] = useState3([]);
@@ -468,6 +974,22 @@ var ForgotPasswordForm = ({ onNavigate, onError, crudify: crudify3 }) => {
468
974
  const [emailSent, setEmailSent] = useState3(false);
469
975
  const [codeAlreadyExists, setCodeAlreadyExists] = useState3(false);
470
976
  const { t } = useTranslation();
977
+ const translateError = (parsedError) => {
978
+ const possibleKeys = [
979
+ `errors.auth.${parsedError.code}`,
980
+ `errors.data.${parsedError.code}`,
981
+ `errors.system.${parsedError.code}`,
982
+ `errors.${parsedError.code}`,
983
+ `forgotPassword.${parsedError.code.toLowerCase()}`
984
+ ];
985
+ for (const key of possibleKeys) {
986
+ const translated = t(key);
987
+ if (translated !== key) {
988
+ return translated;
989
+ }
990
+ }
991
+ return parsedError.message || t("error.unknown");
992
+ };
471
993
  const validateEmail = (email2) => {
472
994
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
473
995
  return emailRegex.test(email2);
@@ -495,80 +1017,57 @@ var ForgotPasswordForm = ({ onNavigate, onError, crudify: crudify3 }) => {
495
1017
  setEmailSent(true);
496
1018
  }
497
1019
  } else {
498
- const errorMessages = [];
499
- if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
500
- errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
501
- } else if (response.errors) {
502
- if (response.errors._error) {
503
- const errors2 = response.errors._error;
504
- const translatedErrors = errors2.map((error) => {
505
- if (error === "TOO_MANY_REQUESTS") {
506
- return t("errors.auth.TOO_MANY_REQUESTS");
507
- }
508
- return error;
509
- });
510
- errorMessages.push(...translatedErrors);
511
- } else {
512
- errorMessages.push(t("error.unknown"));
513
- }
514
- } else {
515
- errorMessages.push(t("error.unknown"));
516
- }
517
- setErrors(errorMessages);
1020
+ const parsedErrors = handleCrudifyError(response);
1021
+ const translatedErrors = parsedErrors.map(translateError);
1022
+ setErrors(translatedErrors);
518
1023
  }
519
1024
  } catch (error) {
520
- console.error("Forgot password error:", error);
521
- setErrors([t("error.unknown")]);
1025
+ const parsedErrors = handleCrudifyError(error);
1026
+ const translatedErrors = parsedErrors.map(translateError);
1027
+ setErrors(translatedErrors);
522
1028
  if (onError) {
523
- onError(typeof error === "string" ? error : t("error.unknown"));
1029
+ onError(translatedErrors.join(", "));
524
1030
  }
525
1031
  } finally {
526
1032
  setLoading(false);
527
1033
  }
528
1034
  };
529
1035
  const handleBack = () => {
530
- onNavigate?.("/login");
1036
+ onScreenChange?.("login");
531
1037
  };
532
1038
  const handleGoToCheckCode = () => {
533
- console.log("\u{1F680} handleGoToCheckCode called:", { email, emailSent, codeAlreadyExists });
534
1039
  if (emailSent || codeAlreadyExists) {
535
- console.log("\u2705 Navigating from success state");
536
- onNavigate?.(`/login/checkCode?email=${encodeURIComponent(email)}`);
1040
+ onScreenChange?.("checkCode", { email });
537
1041
  return;
538
1042
  }
539
1043
  if (!email) {
540
- console.log("\u274C Email required");
541
1044
  setHelperTextEmail(t("forgotPassword.emailRequired"));
542
1045
  return;
543
1046
  }
544
1047
  if (!validateEmail(email)) {
545
- console.log("\u274C Invalid email");
546
1048
  setHelperTextEmail(t("forgotPassword.invalidEmail"));
547
1049
  return;
548
1050
  }
549
- console.log("\u2705 Navigating with valid email");
550
- onNavigate?.(`/login/checkCode?email=${encodeURIComponent(email)}`);
1051
+ onScreenChange?.("checkCode", { email });
551
1052
  };
552
1053
  if (emailSent || codeAlreadyExists) {
553
- console.log("\u{1F4E7} Rendering SUCCESS state:", { emailSent, codeAlreadyExists });
554
- return /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsxs2(Box2, { sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2, textAlign: "center" }, children: [
1054
+ return /* @__PURE__ */ jsx5(Fragment2, { children: /* @__PURE__ */ jsxs2(Box2, { sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2, textAlign: "center" }, children: [
555
1055
  /* @__PURE__ */ jsxs2(Box2, { sx: { mb: 2 }, children: [
556
- /* @__PURE__ */ jsx3(Typography2, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: codeAlreadyExists ? t("forgotPassword.codeAlreadyExistsMessage") : t("forgotPassword.emailSentMessage") }),
557
- /* @__PURE__ */ jsx3(Typography2, { variant: "body2", sx: { color: codeAlreadyExists ? "success.main" : "grey.600" }, children: codeAlreadyExists ? t("forgotPassword.checkEmailInstructions") : t("forgotPassword.checkEmailInstructions") })
1056
+ /* @__PURE__ */ jsx5(Typography2, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: codeAlreadyExists ? t("forgotPassword.codeAlreadyExistsMessage") : t("forgotPassword.emailSentMessage") }),
1057
+ /* @__PURE__ */ jsx5(Typography2, { variant: "body2", sx: { color: codeAlreadyExists ? "success.main" : "grey.600" }, children: codeAlreadyExists ? t("forgotPassword.checkEmailInstructions") : t("forgotPassword.checkEmailInstructions") })
558
1058
  ] }),
559
- /* @__PURE__ */ jsx3(Button2, { type: "button", onClick: handleGoToCheckCode, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: t("forgotPassword.enterCodeLink") }),
560
- /* @__PURE__ */ jsx3(Box2, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ jsx3(Link2, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
1059
+ /* @__PURE__ */ jsx5(Button2, { type: "button", onClick: handleGoToCheckCode, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: t("forgotPassword.enterCodeLink") }),
1060
+ /* @__PURE__ */ jsx5(Box2, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ jsx5(Link2, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
561
1061
  ] }) });
562
1062
  }
563
- console.log("\u{1F4DD} Rendering FORM state");
564
1063
  return /* @__PURE__ */ jsxs2(Fragment2, { children: [
565
1064
  /* @__PURE__ */ jsxs2(Box2, { component: "form", noValidate: true, sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 }, children: [
566
1065
  /* @__PURE__ */ jsxs2(Box2, { sx: { mb: 2 }, children: [
567
- /* @__PURE__ */ jsx3(Typography2, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("forgotPassword.title") }),
568
- /* @__PURE__ */ jsx3(Typography2, { variant: "body2", sx: { color: "grey.600" }, children: t("forgotPassword.instructions") })
1066
+ /* @__PURE__ */ jsx5(Typography2, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("forgotPassword.title") }),
1067
+ /* @__PURE__ */ jsx5(Typography2, { variant: "body2", sx: { color: "grey.600" }, children: t("forgotPassword.instructions") })
569
1068
  ] }),
570
1069
  /* @__PURE__ */ jsxs2(Box2, { sx: { mb: 1 }, children: [
571
- /* @__PURE__ */ jsx3(
1070
+ /* @__PURE__ */ jsx5(
572
1071
  Typography2,
573
1072
  {
574
1073
  variant: "body2",
@@ -578,7 +1077,7 @@ var ForgotPasswordForm = ({ onNavigate, onError, crudify: crudify3 }) => {
578
1077
  children: t("forgotPassword.emailLabel")
579
1078
  }
580
1079
  ),
581
- /* @__PURE__ */ jsx3(
1080
+ /* @__PURE__ */ jsx5(
582
1081
  TextField2,
583
1082
  {
584
1083
  fullWidth: true,
@@ -596,23 +1095,24 @@ var ForgotPasswordForm = ({ onNavigate, onError, crudify: crudify3 }) => {
596
1095
  }
597
1096
  )
598
1097
  ] }),
599
- /* @__PURE__ */ jsx3(Button2, { disabled: loading, type: "button", onClick: handleSubmit, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ jsx3(CircularProgress2, { size: 20 }) : t("forgotPassword.sendCodeButton") }),
1098
+ /* @__PURE__ */ jsx5(Button2, { disabled: loading, type: "button", onClick: handleSubmit, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ jsx5(CircularProgress2, { size: 20 }) : t("forgotPassword.sendCodeButton") }),
600
1099
  /* @__PURE__ */ jsxs2(Box2, { sx: { display: "flex", justifyContent: "center", alignItems: "center", gap: 2 }, children: [
601
- /* @__PURE__ */ jsx3(Link2, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }),
602
- /* @__PURE__ */ jsx3(Typography2, { variant: "body2", sx: { color: "grey.400" }, children: "\u2022" }),
603
- /* @__PURE__ */ jsx3(Link2, { sx: { cursor: "pointer" }, onClick: handleGoToCheckCode, variant: "body2", color: "secondary", children: t("login.alreadyHaveCodeLink") })
1100
+ /* @__PURE__ */ jsx5(Link2, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }),
1101
+ /* @__PURE__ */ jsx5(Typography2, { variant: "body2", sx: { color: "grey.400" }, children: "\u2022" }),
1102
+ /* @__PURE__ */ jsx5(Link2, { sx: { cursor: "pointer" }, onClick: handleGoToCheckCode, variant: "body2", color: "secondary", children: t("login.alreadyHaveCodeLink") })
604
1103
  ] })
605
1104
  ] }),
606
- /* @__PURE__ */ jsx3(Box2, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx3(Alert2, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) })
1105
+ /* @__PURE__ */ jsx5(Box2, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx5(Alert2, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) })
607
1106
  ] });
608
1107
  };
609
1108
  var ForgotPasswordForm_default = ForgotPasswordForm;
610
1109
 
611
1110
  // src/components/CrudifyLogin/Forms/ResetPasswordForm.tsx
612
- import { useState as useState4, useEffect as useEffect3 } from "react";
1111
+ import { useState as useState4, useEffect as useEffect5 } from "react";
613
1112
  import { Typography as Typography3, TextField as TextField3, Button as Button3, Box as Box3, CircularProgress as CircularProgress3, Alert as Alert3, Link as Link3 } from "@mui/material";
614
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
615
- var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, crudify: crudify3 }) => {
1113
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
1114
+ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess }) => {
1115
+ const { crudify: crudify3 } = useCrudify();
616
1116
  const [newPassword, setNewPassword] = useState4("");
617
1117
  const [confirmPassword, setConfirmPassword] = useState4("");
618
1118
  const [loading, setLoading] = useState4(false);
@@ -627,12 +1127,26 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
627
1127
  const [pendingValidation, setPendingValidation] = useState4(null);
628
1128
  const [isValidating, setIsValidating] = useState4(false);
629
1129
  const { t } = useTranslation();
630
- useEffect3(() => {
1130
+ const translateError = (parsedError) => {
1131
+ const possibleKeys = [
1132
+ `errors.auth.${parsedError.code}`,
1133
+ `errors.data.${parsedError.code}`,
1134
+ `errors.system.${parsedError.code}`,
1135
+ `errors.${parsedError.code}`,
1136
+ `resetPassword.${parsedError.code.toLowerCase()}`
1137
+ ];
1138
+ for (const key of possibleKeys) {
1139
+ const translated = t(key);
1140
+ if (translated !== key) {
1141
+ return translated;
1142
+ }
1143
+ }
1144
+ return parsedError.message || t("error.unknown");
1145
+ };
1146
+ useEffect5(() => {
631
1147
  if (!searchParams) {
632
- console.log("\u{1F504} No searchParams yet, waiting...");
633
1148
  return;
634
1149
  }
635
- console.log("\u{1F504} Processing searchParams:", searchParams.toString());
636
1150
  if (searchParams) {
637
1151
  const fromCodeVerificationParam = searchParams.get("fromCodeVerification");
638
1152
  const emailParam = searchParams.get("email");
@@ -651,54 +1165,31 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
651
1165
  const decodedLink = decodeURIComponent(linkParam);
652
1166
  const [linkCode, linkEmail] = decodedLink.split("/");
653
1167
  if (linkCode && linkEmail && linkCode.length === 6) {
654
- console.log("\u{1F517} Reset link detected:", { linkCode, linkEmail });
655
1168
  setCode(linkCode);
656
1169
  setEmail(linkEmail);
657
1170
  setFromCodeVerification(false);
658
- console.log("\u23F3 Setting pending validation for reset link");
659
1171
  setPendingValidation({ email: linkEmail, code: linkCode });
660
1172
  return;
661
1173
  }
662
1174
  } catch (error) {
663
- console.error("Failed to parse reset link:", error);
664
1175
  }
665
1176
  }
666
1177
  if (emailParam && codeParam) {
667
1178
  setEmail(emailParam);
668
1179
  setCode(codeParam);
669
1180
  setFromCodeVerification(false);
670
- console.log("\u23F3 Setting pending validation for direct params");
671
1181
  setPendingValidation({ email: emailParam, code: codeParam });
672
1182
  return;
673
1183
  }
674
1184
  }
675
- console.log("\u274C No valid reset parameters found");
676
1185
  setErrors([t("resetPassword.invalidCode")]);
677
1186
  setValidatingCode(false);
678
- setTimeout(() => onNavigate?.("/login/forgotPassword"), 3e3);
679
- }, [searchParams, crudify3, t, onNavigate]);
680
- useEffect3(() => {
681
- console.log("\u{1F504} Pending validation useEffect triggered:", {
682
- crudify: !!crudify3,
683
- pendingValidation,
684
- crudifyType: typeof crudify3,
685
- crudifyKeys: crudify3 ? Object.keys(crudify3) : null
686
- });
1187
+ setTimeout(() => onScreenChange?.("forgotPassword"), 3e3);
1188
+ }, [searchParams, crudify3, t, onScreenChange]);
1189
+ useEffect5(() => {
687
1190
  if (crudify3 && pendingValidation && !isValidating) {
688
- console.log("\u{1F680} Crudify verified ready! Executing pending validation:", pendingValidation);
689
- console.log("\u{1F50D} Crudify object details:", {
690
- hasTransaction: typeof crudify3.transaction === "function",
691
- hasLogin: typeof crudify3.login === "function",
692
- crudifyInstance: crudify3
693
- });
694
1191
  setIsValidating(true);
695
1192
  const validateCode = async (emailToValidate, codeToValidate) => {
696
- console.log("\u{1F50D} Validating reset code:", { emailToValidate, codeToValidate });
697
- console.log("\u{1F4CB} Pre-validation crudify check:", {
698
- crudify: !!crudify3,
699
- transaction: typeof crudify3?.transaction,
700
- crudifyString: crudify3?.toString?.()
701
- });
702
1193
  try {
703
1194
  const data = [
704
1195
  {
@@ -706,62 +1197,27 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
706
1197
  data: { email: emailToValidate, codePassword: codeToValidate }
707
1198
  }
708
1199
  ];
709
- console.log("\u{1F4E4} Sending validation request:", data);
710
- console.log("\u{1F3AF} About to call crudify.transaction...");
711
1200
  const response = await crudify3.transaction(data);
712
- console.log("\u{1F4E5} Validation response:", response);
713
- console.log("\u{1F4E5} Raw response type:", typeof response);
714
- console.log("\u{1F4E5} Response keys:", Object.keys(response));
715
- if (response.data) {
716
- console.log("\u{1F4E5} Response.data type:", typeof response.data);
717
- console.log("\u{1F4E5} Response.data content:", response.data);
718
- }
719
1201
  if (response.data && Array.isArray(response.data)) {
720
- console.log("\u{1F50D} Checking array response data:", response.data);
721
1202
  const validationResult = response.data[0];
722
1203
  if (validationResult && validationResult.response && validationResult.response.status === "OK") {
723
- console.log("\u2705 Code validation successful (from array data)");
724
1204
  setCodeValidated(true);
725
1205
  return;
726
1206
  }
727
1207
  }
728
1208
  if (response.success) {
729
- console.log("\u2705 Code validation successful");
730
1209
  setCodeValidated(true);
731
1210
  } else {
732
- console.log("\u274C Code validation failed:", response);
733
- console.log("\u274C Full error details:", {
734
- success: response.success,
735
- data: response.data,
736
- errors: response.errors,
737
- errorCode: response.errorCode,
738
- fieldsWarning: response.fieldsWarning
739
- });
740
- if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
741
- setErrors([t("errors.auth.TOO_MANY_REQUESTS")]);
742
- } else {
743
- let errorMessage = t("resetPassword.invalidCode");
744
- if (response.errors?._error) {
745
- const error = response.errors._error[0];
746
- if (error === "TOO_MANY_REQUESTS") {
747
- errorMessage = t("errors.auth.TOO_MANY_REQUESTS");
748
- } else {
749
- const errorMsg = error?.toLowerCase() || "";
750
- if (errorMsg.includes("expired")) {
751
- errorMessage = t("resetPassword.codeExpiredOrInvalid");
752
- } else if (errorMsg.includes("invalid")) {
753
- errorMessage = t("resetPassword.invalidCode");
754
- }
755
- }
756
- }
757
- setErrors([errorMessage]);
758
- }
759
- setTimeout(() => onNavigate?.("/login/forgotPassword"), 3e3);
1211
+ const parsedErrors = handleCrudifyError(response);
1212
+ const translatedErrors = parsedErrors.map(translateError);
1213
+ setErrors(translatedErrors);
1214
+ setTimeout(() => onScreenChange?.("forgotPassword"), 3e3);
760
1215
  }
761
1216
  } catch (error) {
762
- console.error("Code validation error:", error);
763
- setErrors([t("resetPassword.invalidCode")]);
764
- setTimeout(() => onNavigate?.("/login/forgotPassword"), 3e3);
1217
+ const parsedErrors = handleCrudifyError(error);
1218
+ const translatedErrors = parsedErrors.map(translateError);
1219
+ setErrors(translatedErrors);
1220
+ setTimeout(() => onScreenChange?.("forgotPassword"), 3e3);
765
1221
  } finally {
766
1222
  setValidatingCode(false);
767
1223
  setPendingValidation(null);
@@ -770,7 +1226,7 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
770
1226
  };
771
1227
  validateCode(pendingValidation.email, pendingValidation.code);
772
1228
  }
773
- }, [crudify3, pendingValidation, t, onNavigate]);
1229
+ }, [crudify3, pendingValidation, t, onScreenChange]);
774
1230
  const validatePassword = (password) => {
775
1231
  if (password.length < 8) {
776
1232
  return t("resetPassword.passwordTooShort");
@@ -816,80 +1272,41 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
816
1272
  onResetSuccess?.();
817
1273
  }, 1e3);
818
1274
  } else {
819
- const errorMessages = [];
820
- if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
821
- errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
822
- } else if (response.errors?._transaction) {
823
- const transactionErrors = response.errors._transaction;
824
- if (Array.isArray(transactionErrors) && transactionErrors.length > 0) {
825
- const firstError = transactionErrors[0];
826
- let errorMsg = "";
827
- if (typeof firstError === "string") {
828
- try {
829
- const parsed = JSON.parse(firstError);
830
- if (parsed?.response?.message) {
831
- errorMsg = parsed.response.message.toLowerCase();
832
- }
833
- } catch {
834
- errorMsg = firstError.toLowerCase();
835
- }
836
- }
837
- if (errorMsg.includes("expired")) {
838
- errorMessages.push(t("resetPassword.codeExpiredOrInvalid"));
839
- } else if (errorMsg.includes("invalid")) {
840
- errorMessages.push(t("resetPassword.invalidCode"));
841
- } else {
842
- errorMessages.push(t("error.unknown"));
843
- }
844
- } else {
845
- errorMessages.push(t("error.unknown"));
846
- }
847
- } else if (response.errors?._error) {
848
- const error = response.errors._error[0];
849
- if (error === "TOO_MANY_REQUESTS") {
850
- errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
851
- } else {
852
- const errorMsg = error?.toLowerCase() || "";
853
- if (errorMsg.includes("expired")) {
854
- errorMessages.push(t("resetPassword.codeExpiredOrInvalid"));
855
- } else if (errorMsg.includes("invalid")) {
856
- errorMessages.push(t("resetPassword.invalidCode"));
857
- } else {
858
- errorMessages.push(error || t("error.unknown"));
859
- }
860
- }
861
- } else {
862
- errorMessages.push(t("error.unknown"));
863
- }
864
- setErrors(errorMessages);
1275
+ const parsedErrors = handleCrudifyError(response);
1276
+ const translatedErrors = parsedErrors.map(translateError);
1277
+ setErrors(translatedErrors);
865
1278
  }
866
1279
  } catch (error) {
867
- console.error("Reset password error:", error);
868
- setErrors([t("error.unknown")]);
1280
+ const parsedErrors = handleCrudifyError(error);
1281
+ const translatedErrors = parsedErrors.map(translateError);
1282
+ setErrors(translatedErrors);
869
1283
  if (onError) {
870
- onError(typeof error === "string" ? error : t("error.unknown"));
1284
+ onError(translatedErrors.join(", "));
871
1285
  }
872
1286
  }
873
1287
  setLoading(false);
874
1288
  };
875
1289
  const handleBack = () => {
876
- if (fromCodeVerification) onNavigate?.(`/login/checkCode?email=${encodeURIComponent(email)}`);
877
- else onNavigate?.("/login/forgotPassword");
1290
+ if (fromCodeVerification) {
1291
+ onScreenChange?.("checkCode", { email });
1292
+ } else {
1293
+ onScreenChange?.("forgotPassword");
1294
+ }
878
1295
  };
879
1296
  if (validatingCode) {
880
- return /* @__PURE__ */ jsx4(Box3, { sx: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "300px" }, children: /* @__PURE__ */ jsx4(CircularProgress3, {}) });
1297
+ return /* @__PURE__ */ jsx6(Box3, { sx: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "300px" }, children: /* @__PURE__ */ jsx6(CircularProgress3, {}) });
881
1298
  }
882
1299
  if (!codeValidated) {
883
- return /* @__PURE__ */ jsx4(Box3, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx4(Alert3, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) });
1300
+ return /* @__PURE__ */ jsx6(Box3, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx6(Alert3, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) });
884
1301
  }
885
1302
  return /* @__PURE__ */ jsxs3(Fragment3, { children: [
886
1303
  /* @__PURE__ */ jsxs3(Box3, { component: "form", noValidate: true, sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 }, children: [
887
1304
  /* @__PURE__ */ jsxs3(Box3, { sx: { mb: 2 }, children: [
888
- /* @__PURE__ */ jsx4(Typography3, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("resetPassword.title") }),
889
- /* @__PURE__ */ jsx4(Typography3, { variant: "body2", sx: { color: "grey.600" }, children: t("resetPassword.instructions") })
1305
+ /* @__PURE__ */ jsx6(Typography3, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("resetPassword.title") }),
1306
+ /* @__PURE__ */ jsx6(Typography3, { variant: "body2", sx: { color: "grey.600" }, children: t("resetPassword.instructions") })
890
1307
  ] }),
891
1308
  /* @__PURE__ */ jsxs3(Box3, { sx: { mb: 1 }, children: [
892
- /* @__PURE__ */ jsx4(
1309
+ /* @__PURE__ */ jsx6(
893
1310
  Typography3,
894
1311
  {
895
1312
  variant: "body2",
@@ -899,7 +1316,7 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
899
1316
  children: t("resetPassword.newPasswordLabel")
900
1317
  }
901
1318
  ),
902
- /* @__PURE__ */ jsx4(
1319
+ /* @__PURE__ */ jsx6(
903
1320
  TextField3,
904
1321
  {
905
1322
  fullWidth: true,
@@ -918,7 +1335,7 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
918
1335
  )
919
1336
  ] }),
920
1337
  /* @__PURE__ */ jsxs3(Box3, { sx: { mb: 1 }, children: [
921
- /* @__PURE__ */ jsx4(
1338
+ /* @__PURE__ */ jsx6(
922
1339
  Typography3,
923
1340
  {
924
1341
  variant: "body2",
@@ -928,7 +1345,7 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
928
1345
  children: t("resetPassword.confirmPasswordLabel")
929
1346
  }
930
1347
  ),
931
- /* @__PURE__ */ jsx4(
1348
+ /* @__PURE__ */ jsx6(
932
1349
  TextField3,
933
1350
  {
934
1351
  fullWidth: true,
@@ -946,33 +1363,50 @@ var ResetPasswordForm = ({ onNavigate, onError, searchParams, onResetSuccess, cr
946
1363
  }
947
1364
  )
948
1365
  ] }),
949
- /* @__PURE__ */ jsx4(Button3, { disabled: loading, type: "button", onClick: handleSubmit, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ jsx4(CircularProgress3, { size: 20 }) : t("resetPassword.resetPasswordButton") }),
950
- /* @__PURE__ */ jsx4(Box3, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ jsx4(Link3, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
1366
+ /* @__PURE__ */ jsx6(Button3, { disabled: loading, type: "button", onClick: handleSubmit, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ jsx6(CircularProgress3, { size: 20 }) : t("resetPassword.resetPasswordButton") }),
1367
+ /* @__PURE__ */ jsx6(Box3, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ jsx6(Link3, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
951
1368
  ] }),
952
- /* @__PURE__ */ jsx4(Box3, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx4(Alert3, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) })
1369
+ /* @__PURE__ */ jsx6(Box3, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx6(Alert3, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) })
953
1370
  ] });
954
1371
  };
955
1372
  var ResetPasswordForm_default = ResetPasswordForm;
956
1373
 
957
1374
  // src/components/CrudifyLogin/Forms/CheckCodeForm.tsx
958
- import { useState as useState5, useEffect as useEffect4 } from "react";
1375
+ import { useState as useState5, useEffect as useEffect6 } from "react";
959
1376
  import { Typography as Typography4, TextField as TextField4, Button as Button4, Box as Box4, CircularProgress as CircularProgress4, Alert as Alert4, Link as Link4 } from "@mui/material";
960
- import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
961
- var CheckCodeForm = ({ onNavigate, onError, searchParams, crudify: crudify3 }) => {
1377
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
1378
+ var CheckCodeForm = ({ onScreenChange, onError, searchParams }) => {
1379
+ const { crudify: crudify3 } = useCrudify();
962
1380
  const [code, setCode] = useState5("");
963
1381
  const [loading, setLoading] = useState5(false);
964
1382
  const [errors, setErrors] = useState5([]);
965
1383
  const [helperTextCode, setHelperTextCode] = useState5(null);
966
1384
  const [email, setEmail] = useState5("");
967
1385
  const { t } = useTranslation();
968
- useEffect4(() => {
1386
+ const translateError = (parsedError) => {
1387
+ const possibleKeys = [
1388
+ `errors.auth.${parsedError.code}`,
1389
+ `errors.data.${parsedError.code}`,
1390
+ `errors.system.${parsedError.code}`,
1391
+ `errors.${parsedError.code}`,
1392
+ `checkCode.${parsedError.code.toLowerCase()}`
1393
+ ];
1394
+ for (const key of possibleKeys) {
1395
+ const translated = t(key);
1396
+ if (translated !== key) {
1397
+ return translated;
1398
+ }
1399
+ }
1400
+ return parsedError.message || t("error.unknown");
1401
+ };
1402
+ useEffect6(() => {
969
1403
  const emailParam = searchParams?.get("email");
970
1404
  if (emailParam) {
971
1405
  setEmail(emailParam);
972
1406
  } else {
973
- onNavigate?.("/login/forgotPassword");
1407
+ onScreenChange?.("forgotPassword");
974
1408
  }
975
- }, [searchParams, onNavigate]);
1409
+ }, [searchParams, onScreenChange]);
976
1410
  const handleSubmit = async () => {
977
1411
  if (loading || !crudify3) return;
978
1412
  setErrors([]);
@@ -995,41 +1429,25 @@ var CheckCodeForm = ({ onNavigate, onError, searchParams, crudify: crudify3 }) =
995
1429
  ];
996
1430
  const response = await crudify3.transaction(data);
997
1431
  if (response.success) {
998
- onNavigate?.(`/login/resetPassword?email=${encodeURIComponent(email)}&code=${encodeURIComponent(code)}&fromCodeVerification=true`);
1432
+ onScreenChange?.("resetPassword", { email, code, fromCodeVerification: "true" });
999
1433
  } else {
1000
- const errorMessages = [];
1001
- if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
1002
- errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
1003
- } else if (response.errors) {
1004
- if (response.errors._error) {
1005
- const errors2 = response.errors._error;
1006
- const translatedErrors = errors2.map((error) => {
1007
- if (error === "TOO_MANY_REQUESTS") {
1008
- return t("errors.auth.TOO_MANY_REQUESTS");
1009
- }
1010
- return error;
1011
- });
1012
- errorMessages.push(...translatedErrors);
1013
- } else {
1014
- errorMessages.push(t("error.unknown"));
1015
- }
1016
- } else {
1017
- errorMessages.push(t("checkCode.verifyError"));
1018
- }
1019
- setErrors(errorMessages);
1434
+ const parsedErrors = handleCrudifyError(response);
1435
+ const translatedErrors = parsedErrors.map(translateError);
1436
+ setErrors(translatedErrors);
1020
1437
  setLoading(false);
1021
1438
  }
1022
1439
  } catch (error) {
1023
- console.error("Check code error:", error);
1024
- setErrors([t("error.unknown")]);
1440
+ const parsedErrors = handleCrudifyError(error);
1441
+ const translatedErrors = parsedErrors.map(translateError);
1442
+ setErrors(translatedErrors);
1025
1443
  setLoading(false);
1026
1444
  if (onError) {
1027
- onError(typeof error === "string" ? error : t("error.unknown"));
1445
+ onError(translatedErrors.join(", "));
1028
1446
  }
1029
1447
  }
1030
1448
  };
1031
1449
  const handleBack = () => {
1032
- onNavigate?.("/login/forgotPassword");
1450
+ onScreenChange?.("forgotPassword");
1033
1451
  };
1034
1452
  const handleCodeChange = (event) => {
1035
1453
  const value = event.target.value.replace(/\D/g, "").slice(0, 6);
@@ -1038,11 +1456,11 @@ var CheckCodeForm = ({ onNavigate, onError, searchParams, crudify: crudify3 }) =
1038
1456
  return /* @__PURE__ */ jsxs4(Fragment4, { children: [
1039
1457
  /* @__PURE__ */ jsxs4(Box4, { component: "form", noValidate: true, sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 }, children: [
1040
1458
  /* @__PURE__ */ jsxs4(Box4, { sx: { mb: 2 }, children: [
1041
- /* @__PURE__ */ jsx5(Typography4, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("checkCode.title") }),
1042
- /* @__PURE__ */ jsx5(Typography4, { variant: "body2", sx: { color: "grey.600" }, children: t("checkCode.instructions") })
1459
+ /* @__PURE__ */ jsx7(Typography4, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("checkCode.title") }),
1460
+ /* @__PURE__ */ jsx7(Typography4, { variant: "body2", sx: { color: "grey.600" }, children: t("checkCode.instructions") })
1043
1461
  ] }),
1044
1462
  /* @__PURE__ */ jsxs4(Box4, { sx: { mb: 1 }, children: [
1045
- /* @__PURE__ */ jsx5(
1463
+ /* @__PURE__ */ jsx7(
1046
1464
  Typography4,
1047
1465
  {
1048
1466
  variant: "body2",
@@ -1052,7 +1470,7 @@ var CheckCodeForm = ({ onNavigate, onError, searchParams, crudify: crudify3 }) =
1052
1470
  children: t("checkCode.codeLabel")
1053
1471
  }
1054
1472
  ),
1055
- /* @__PURE__ */ jsx5(
1473
+ /* @__PURE__ */ jsx7(
1056
1474
  TextField4,
1057
1475
  {
1058
1476
  fullWidth: true,
@@ -1073,7 +1491,7 @@ var CheckCodeForm = ({ onNavigate, onError, searchParams, crudify: crudify3 }) =
1073
1491
  }
1074
1492
  )
1075
1493
  ] }),
1076
- /* @__PURE__ */ jsx5(
1494
+ /* @__PURE__ */ jsx7(
1077
1495
  Button4,
1078
1496
  {
1079
1497
  disabled: loading || code.length !== 6,
@@ -1083,33 +1501,60 @@ var CheckCodeForm = ({ onNavigate, onError, searchParams, crudify: crudify3 }) =
1083
1501
  variant: "contained",
1084
1502
  color: "primary",
1085
1503
  sx: { mt: 2, mb: 2 },
1086
- children: loading ? /* @__PURE__ */ jsx5(CircularProgress4, { size: 20 }) : t("checkCode.verifyButton")
1504
+ children: loading ? /* @__PURE__ */ jsx7(CircularProgress4, { size: 20 }) : t("checkCode.verifyButton")
1087
1505
  }
1088
1506
  ),
1089
- /* @__PURE__ */ jsx5(Box4, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ jsx5(Link4, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
1507
+ /* @__PURE__ */ jsx7(Box4, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ jsx7(Link4, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
1090
1508
  ] }),
1091
- /* @__PURE__ */ jsx5(Box4, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx5(Alert4, { sx: { mt: 2 }, severity: "error", children: error }, index)) })
1509
+ /* @__PURE__ */ jsx7(Box4, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ jsx7(Alert4, { sx: { mt: 2 }, severity: "error", children: error }, index)) })
1092
1510
  ] });
1093
1511
  };
1094
1512
  var CheckCodeForm_default = CheckCodeForm;
1095
1513
 
1096
- // src/components/CrudifyLogin/hooks/useCrudifyLogin.ts
1097
- import { useMemo as useMemo2, useEffect as useEffect5, useState as useState6 } from "react";
1098
- import crudify from "@nocios/crudify-browser";
1099
-
1100
- // src/components/CrudifyLogin/utils/cookies.ts
1101
- var getCookie = (name) => {
1102
- const match = document.cookie.match(new RegExp("(^|;)\\s*" + name + "=([^;]+)"));
1103
- return match ? match[2] : null;
1514
+ // src/components/CrudifyLogin/components/CrudifyInitializer.tsx
1515
+ import { Box as Box5, CircularProgress as CircularProgress5, Alert as Alert5, Typography as Typography5 } from "@mui/material";
1516
+ import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1517
+ var CrudifyInitializer = ({
1518
+ children,
1519
+ fallback
1520
+ }) => {
1521
+ const { isLoading, error, isInitialized } = useCrudify();
1522
+ const { t } = useTranslation();
1523
+ if (isLoading) {
1524
+ return fallback || /* @__PURE__ */ jsxs5(
1525
+ Box5,
1526
+ {
1527
+ sx: {
1528
+ display: "flex",
1529
+ flexDirection: "column",
1530
+ alignItems: "center",
1531
+ justifyContent: "center",
1532
+ minHeight: "200px",
1533
+ gap: 2
1534
+ },
1535
+ children: [
1536
+ /* @__PURE__ */ jsx8(CircularProgress5, {}),
1537
+ /* @__PURE__ */ jsx8(Typography5, { variant: "body2", color: "text.secondary", children: t("login.initializing") !== "login.initializing" ? t("login.initializing") : "Initializing..." })
1538
+ ]
1539
+ }
1540
+ );
1541
+ }
1542
+ if (error) {
1543
+ return /* @__PURE__ */ jsx8(Alert5, { severity: "error", sx: { mt: 2 }, children: /* @__PURE__ */ jsxs5(Typography5, { variant: "body2", children: [
1544
+ t("login.initializationError") !== "login.initializationError" ? t("login.initializationError") : "Initialization error",
1545
+ ": ",
1546
+ error
1547
+ ] }) });
1548
+ }
1549
+ if (!isInitialized) {
1550
+ return /* @__PURE__ */ jsx8(Alert5, { severity: "warning", sx: { mt: 2 }, children: /* @__PURE__ */ jsx8(Typography5, { variant: "body2", children: t("login.notInitialized") !== "login.notInitialized" ? t("login.notInitialized") : "System not initialized" }) });
1551
+ }
1552
+ return /* @__PURE__ */ jsx8(Fragment5, { children });
1104
1553
  };
1105
1554
 
1106
1555
  // src/components/CrudifyLogin/hooks/useCrudifyLogin.ts
1107
- var globalInitPromise = null;
1108
- var isGloballyInitialized = false;
1109
- var lastApiKey = "";
1110
- var lastEnv = "";
1556
+ import { useMemo as useMemo2 } from "react";
1111
1557
  var useCrudifyLogin = (config, _options = {}) => {
1112
- const [isInitialized, setIsInitialized] = useState6(false);
1113
1558
  const finalConfig = useMemo2(() => {
1114
1559
  const publicApiKey = config.publicApiKey || getCookie("publicApiKey") || null;
1115
1560
  const rawEnv = config.env || getCookie("environment") || "prod";
@@ -1130,269 +1575,61 @@ var useCrudifyLogin = (config, _options = {}) => {
1130
1575
  loginActions
1131
1576
  };
1132
1577
  }, [config]);
1133
- useEffect5(() => {
1134
- console.log("\u{1F527} useCrudifyLogin useEffect triggered:", {
1135
- publicApiKey: !!finalConfig.publicApiKey,
1136
- env: finalConfig.env,
1137
- hasPublicApiKey: !!finalConfig.publicApiKey,
1138
- isGloballyInitialized,
1139
- lastApiKey: lastApiKey ? lastApiKey.substring(0, 10) + "..." : "none",
1140
- lastEnv
1141
- });
1142
- if (!finalConfig.publicApiKey) {
1143
- console.log("\u274C No publicApiKey, skipping crudify initialization");
1144
- setIsInitialized(false);
1145
- return;
1146
- }
1147
- const currentApiKey = finalConfig.publicApiKey;
1148
- const currentEnv = finalConfig.env;
1149
- if (isGloballyInitialized && lastApiKey === currentApiKey && lastEnv === currentEnv) {
1150
- console.log("\u2705 Crudify already initialized with same config, reusing");
1151
- setIsInitialized(true);
1152
- return;
1153
- }
1154
- const initializeCrudify = async () => {
1155
- if (globalInitPromise) {
1156
- console.log("\u23F3 Waiting for existing initialization to complete");
1157
- try {
1158
- await globalInitPromise;
1159
- setIsInitialized(isGloballyInitialized);
1160
- return;
1161
- } catch (error) {
1162
- console.error("\u274C Previous initialization failed:", error);
1163
- }
1164
- }
1165
- globalInitPromise = (async () => {
1166
- try {
1167
- console.log("\u2699\uFE0F Configuring crudify with env:", currentEnv);
1168
- crudify.config(currentEnv);
1169
- console.log("\u{1F680} Initializing crudify with publicApiKey:", currentApiKey.substring(0, 10) + "...");
1170
- await crudify.init(currentApiKey, "none");
1171
- console.log("\u{1F9EA} Testing crudify initialization...");
1172
- await new Promise((resolve) => setTimeout(resolve, 50));
1173
- if (typeof crudify.transaction === "function" && typeof crudify.login === "function") {
1174
- console.log("\u2705 Crudify initialization verified and ready");
1175
- isGloballyInitialized = true;
1176
- lastApiKey = currentApiKey;
1177
- lastEnv = currentEnv;
1178
- } else {
1179
- console.log("\u274C Crudify methods not properly initialized");
1180
- isGloballyInitialized = false;
1181
- }
1182
- console.log("\u{1F50D} Crudify state after init:", {
1183
- hasTransaction: typeof crudify.transaction === "function",
1184
- hasLogin: typeof crudify.login === "function",
1185
- isGloballyInitialized,
1186
- crudifyObject: crudify
1187
- });
1188
- } catch (error) {
1189
- console.error("\u274C Error initializing crudify:", error);
1190
- isGloballyInitialized = false;
1191
- throw error;
1192
- }
1193
- })();
1194
- try {
1195
- await globalInitPromise;
1196
- setIsInitialized(isGloballyInitialized);
1197
- } catch (error) {
1198
- setIsInitialized(false);
1199
- } finally {
1200
- globalInitPromise = null;
1201
- }
1202
- };
1203
- initializeCrudify();
1204
- }, [finalConfig.publicApiKey, finalConfig.env]);
1205
- const crudifyMethods = useMemo2(() => {
1206
- console.log("\u{1F504} crudifyMethods useMemo triggered:", {
1207
- publicApiKey: !!finalConfig.publicApiKey,
1208
- isInitialized,
1209
- isGloballyInitialized,
1210
- crudifyLogin: typeof crudify.login,
1211
- crudifyTransaction: typeof crudify.transaction
1212
- });
1213
- if (!finalConfig.publicApiKey || !isInitialized || !isGloballyInitialized) {
1214
- console.log("\u274C Crudify not ready:", {
1215
- publicApiKey: !!finalConfig.publicApiKey,
1216
- isInitialized,
1217
- isGloballyInitialized
1218
- });
1219
- return null;
1220
- }
1221
- const methods = {
1222
- login: async (identifier, password) => {
1223
- console.log("\u{1F517} Wrapper login called, isGloballyInitialized:", isGloballyInitialized);
1224
- return await crudify.login(identifier, password);
1225
- },
1226
- transaction: async (data, options) => {
1227
- console.log("\u{1F517} Wrapper transaction called, isGloballyInitialized:", isGloballyInitialized);
1228
- return await crudify.transaction(data, options);
1229
- }
1230
- };
1231
- console.log("\u2705 Returning ready crudifyMethods:", {
1232
- hasLogin: typeof methods.login === "function",
1233
- hasTransaction: typeof methods.transaction === "function",
1234
- isInitialized,
1235
- isGloballyInitialized,
1236
- methods
1237
- });
1238
- return methods;
1239
- }, [finalConfig.publicApiKey, isInitialized, isGloballyInitialized]);
1240
- return { crudify: crudifyMethods };
1578
+ return { config: finalConfig };
1241
1579
  };
1242
1580
 
1243
1581
  // src/components/CrudifyLogin/index.tsx
1244
- import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1582
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1245
1583
  var CrudifyLoginInternal = ({
1246
- config: providedConfig,
1247
- onNavigate,
1584
+ onScreenChange,
1585
+ onExternalNavigate,
1248
1586
  onLoginSuccess,
1249
1587
  onError,
1250
- initialScreen = "login",
1251
- redirectUrl = "/",
1252
- autoReadFromCookies = true
1588
+ redirectUrl = "/"
1253
1589
  }) => {
1254
1590
  const { t } = useTranslation();
1255
- const [currentScreen, setCurrentScreen] = useState7(initialScreen);
1256
- const [searchParams, setSearchParams] = useState7();
1257
- console.log("\u{1F504} CrudifyLoginInternal RENDER:", { currentScreen, initialScreen });
1258
- React2.useEffect(() => {
1259
- const urlParams = new URLSearchParams(window.location.search);
1260
- if (initialScreen === "checkCode") {
1261
- const email = urlParams.get("email");
1262
- const code = urlParams.get("code");
1263
- console.log("\u{1F517} CheckCode link detected:", { email, code });
1264
- if (email) {
1265
- setSearchParams(urlParams);
1266
- }
1267
- }
1268
- if (initialScreen === "resetPassword") {
1269
- const link = urlParams.get("link");
1270
- console.log("\u{1F517} ResetPassword link detected:", { link });
1271
- if (link) {
1272
- setSearchParams(urlParams);
1273
- }
1274
- }
1275
- }, [initialScreen]);
1276
- const finalConfig = useMemo3(() => {
1277
- let cookieConfig = {};
1278
- if (autoReadFromCookies) {
1279
- try {
1280
- let logoValue;
1281
- let appColorsValue = { primaryColor: "#1066BA" };
1282
- try {
1283
- const encodedLogo = getCookie("logo");
1284
- if (encodedLogo) {
1285
- const decodedLogo = decodeURIComponent(encodedLogo);
1286
- if (decodedLogo.startsWith("http")) logoValue = decodedLogo;
1287
- }
1288
- } catch (e) {
1289
- console.warn("Could not decode logo from cookie, using default.", e);
1290
- }
1291
- try {
1292
- const colorsCookie = getCookie("colors");
1293
- if (colorsCookie) {
1294
- const decodedColorsString = decodeURIComponent(colorsCookie);
1295
- const parsedColors = JSON.parse(decodedColorsString);
1296
- appColorsValue = { ...appColorsValue, ...parsedColors };
1297
- }
1298
- } catch (e) {
1299
- console.error("Failed to parse colors from cookie, using defaults.", e);
1300
- }
1301
- cookieConfig = {
1302
- logo: logoValue,
1303
- colors: appColorsValue
1304
- };
1305
- } catch (e) {
1306
- console.error("Error reading configuration from cookies:", e);
1307
- }
1308
- }
1309
- return {
1310
- publicApiKey: providedConfig?.publicApiKey,
1311
- env: providedConfig?.env,
1312
- appName: providedConfig?.appName,
1313
- logo: providedConfig?.logo || cookieConfig.logo,
1314
- colors: { ...cookieConfig.colors, ...providedConfig?.colors },
1315
- loginActions: providedConfig?.loginActions
1316
- };
1317
- }, [providedConfig, autoReadFromCookies]);
1318
- const { crudify: crudify3 } = useCrudifyLogin(finalConfig);
1319
- const handleNavigate = (path) => {
1320
- console.log("\u{1F680} INTERNAL handleNavigate called with:", path);
1321
- const [basePath, queryString] = path.split("?");
1322
- if (queryString) {
1323
- setSearchParams(new URLSearchParams(queryString));
1324
- } else {
1325
- setSearchParams(void 0);
1326
- }
1327
- let newScreen = "login";
1328
- if (basePath.includes("/forgotPassword")) {
1329
- newScreen = "forgotPassword";
1330
- } else if (basePath.includes("/checkCode")) {
1331
- newScreen = "checkCode";
1332
- } else if (basePath.includes("/resetPassword")) {
1333
- newScreen = "resetPassword";
1334
- } else {
1335
- newScreen = "login";
1336
- }
1337
- console.log("\u{1F3AF} INTERNAL Setting currentScreen from", currentScreen, "to", newScreen);
1338
- setCurrentScreen(newScreen);
1339
- console.log("\u{1F512} All navigation handled internally - no external calls");
1340
- };
1341
- const notifyExternal = (path, reason) => {
1342
- console.log(`\u{1F4E2} Notifying external: ${reason} - ${path}`);
1343
- onNavigate?.(path);
1591
+ const { state, setScreen } = useLoginState();
1592
+ const handleScreenChange = (screen2, params) => {
1593
+ setScreen(screen2, params);
1594
+ onScreenChange?.(screen2, params);
1344
1595
  };
1345
1596
  const renderCurrentForm = () => {
1346
- console.log("\u{1F3A8} renderCurrentForm for screen:", currentScreen);
1347
1597
  const commonProps = {
1348
- config: finalConfig,
1349
- onNavigate: handleNavigate,
1350
- // Navegación interna
1598
+ onScreenChange: handleScreenChange,
1599
+ onExternalNavigate,
1351
1600
  onError,
1352
- redirectUrl,
1353
- crudify: crudify3
1354
- // Pasar la instancia compartida de crudify
1601
+ redirectUrl
1355
1602
  };
1356
- switch (currentScreen) {
1603
+ switch (state.currentScreen) {
1357
1604
  case "forgotPassword":
1358
- console.log("\u{1F4CB} Rendering ForgotPasswordForm");
1359
- return /* @__PURE__ */ jsx6(ForgotPasswordForm_default, { ...commonProps });
1605
+ return /* @__PURE__ */ jsx9(ForgotPasswordForm_default, { ...commonProps });
1360
1606
  case "checkCode":
1361
- console.log("\u{1F522} Rendering CheckCodeForm");
1362
- return /* @__PURE__ */ jsx6(CheckCodeForm_default, { ...commonProps, searchParams });
1607
+ return /* @__PURE__ */ jsx9(CheckCodeForm_default, { ...commonProps });
1363
1608
  case "resetPassword":
1364
- console.log("\u{1F510} Rendering ResetPasswordForm");
1365
- return /* @__PURE__ */ jsx6(
1609
+ return /* @__PURE__ */ jsx9(
1366
1610
  ResetPasswordForm_default,
1367
1611
  {
1368
1612
  ...commonProps,
1369
- searchParams,
1370
1613
  onResetSuccess: () => {
1371
- notifyExternal(redirectUrl, "Password reset successful");
1614
+ handleScreenChange("login");
1372
1615
  }
1373
1616
  }
1374
1617
  );
1375
1618
  default:
1376
- console.log("\u{1F511} Rendering LoginForm");
1377
- return /* @__PURE__ */ jsx6(
1619
+ return /* @__PURE__ */ jsx9(
1378
1620
  LoginForm_default,
1379
1621
  {
1380
1622
  ...commonProps,
1381
- onLoginSuccess: (result) => {
1382
- if (onLoginSuccess) {
1383
- onLoginSuccess(result);
1384
- }
1385
- notifyExternal(redirectUrl, "Login successful");
1386
- }
1623
+ onLoginSuccess
1387
1624
  }
1388
1625
  );
1389
1626
  }
1390
1627
  };
1391
- return /* @__PURE__ */ jsxs5(Fragment5, { children: [
1392
- /* @__PURE__ */ jsx6(Box5, { sx: { display: "flex", justifyContent: "center", mb: 3 }, children: /* @__PURE__ */ jsx6(
1628
+ return /* @__PURE__ */ jsxs6(CrudifyInitializer, { children: [
1629
+ /* @__PURE__ */ jsx9(Box6, { sx: { display: "flex", justifyContent: "center", mb: 3 }, children: /* @__PURE__ */ jsx9(
1393
1630
  "img",
1394
1631
  {
1395
- src: finalConfig.logo || "/nocios-default.png",
1632
+ src: state.config.logo || "/nocios-default.png",
1396
1633
  alt: t("login.logoAlt"),
1397
1634
  style: {
1398
1635
  width: "100%",
@@ -1405,17 +1642,17 @@ var CrudifyLoginInternal = ({
1405
1642
  }
1406
1643
  }
1407
1644
  ) }),
1408
- finalConfig.appName && /* @__PURE__ */ jsx6(
1409
- Typography5,
1645
+ state.config.appName && /* @__PURE__ */ jsx9(
1646
+ Typography6,
1410
1647
  {
1411
1648
  variant: "h6",
1412
1649
  component: "h1",
1413
1650
  sx: {
1414
1651
  textAlign: "center",
1415
1652
  mb: 2,
1416
- color: finalConfig.colors?.primaryColor || "#1066BA"
1653
+ color: state.config.colors?.primaryColor || "#1066BA"
1417
1654
  },
1418
- children: finalConfig.appName
1655
+ children: state.config.appName
1419
1656
  }
1420
1657
  ),
1421
1658
  renderCurrentForm()
@@ -1426,22 +1663,33 @@ var CrudifyLogin = ({
1426
1663
  translationsUrl,
1427
1664
  language = "en",
1428
1665
  config = {},
1666
+ initialScreen = "login",
1667
+ autoReadFromCookies = true,
1429
1668
  ...props
1430
1669
  }) => {
1431
- return /* @__PURE__ */ jsx6(
1670
+ const { config: finalConfig } = useCrudifyLogin(config);
1671
+ return /* @__PURE__ */ jsx9(
1432
1672
  I18nProvider,
1433
1673
  {
1434
1674
  translations,
1435
1675
  translationsUrl,
1436
1676
  language,
1437
- children: /* @__PURE__ */ jsx6(CrudifyLoginInternal, { config, ...props })
1677
+ children: /* @__PURE__ */ jsx9(CrudifyProvider, { config: finalConfig, children: /* @__PURE__ */ jsx9(
1678
+ LoginStateProvider,
1679
+ {
1680
+ config,
1681
+ initialScreen,
1682
+ autoReadFromCookies,
1683
+ children: /* @__PURE__ */ jsx9(CrudifyLoginInternal, { config, ...props })
1684
+ }
1685
+ ) })
1438
1686
  }
1439
1687
  );
1440
1688
  };
1441
1689
  var CrudifyLogin_default = CrudifyLogin;
1442
1690
 
1443
1691
  // src/hooks/useUserProfile.ts
1444
- import { useState as useState8, useEffect as useEffect6, useCallback, useRef as useRef2 } from "react";
1692
+ import { useState as useState6, useEffect as useEffect7, useCallback, useRef as useRef2 } from "react";
1445
1693
  import crudify2 from "@nocios/crudify-browser";
1446
1694
 
1447
1695
  // src/utils/jwtUtils.ts
@@ -1487,9 +1735,9 @@ var isTokenExpired = (token) => {
1487
1735
  // src/hooks/useUserProfile.ts
1488
1736
  var useUserProfile = (options = {}) => {
1489
1737
  const { autoFetch = true, retryOnError = false, maxRetries = 3 } = options;
1490
- const [userProfile, setUserProfile] = useState8(null);
1491
- const [loading, setLoading] = useState8(false);
1492
- const [error, setError] = useState8(null);
1738
+ const [userProfile, setUserProfile] = useState6(null);
1739
+ const [loading, setLoading] = useState6(false);
1740
+ const [error, setError] = useState6(null);
1493
1741
  const abortControllerRef = useRef2(null);
1494
1742
  const mountedRef = useRef2(true);
1495
1743
  const requestIdRef = useRef2(0);
@@ -1535,11 +1783,11 @@ var useUserProfile = (options = {}) => {
1535
1783
  }
1536
1784
  } catch (err) {
1537
1785
  if (currentRequestId === requestIdRef.current && mountedRef.current) {
1538
- if (err.name === "AbortError") {
1786
+ const error2 = err;
1787
+ if (error2.name === "AbortError") {
1539
1788
  return;
1540
1789
  }
1541
- console.error("Error loading user profile:", err);
1542
- const shouldRetry = retryOnError && retryCountRef.current < maxRetries && (err.message?.includes("Network Error") || err.message?.includes("Failed to fetch"));
1790
+ const shouldRetry = retryOnError && retryCountRef.current < maxRetries && (error2.message?.includes("Network Error") || error2.message?.includes("Failed to fetch"));
1543
1791
  if (shouldRetry) {
1544
1792
  retryCountRef.current++;
1545
1793
  setTimeout(() => {
@@ -1561,12 +1809,12 @@ var useUserProfile = (options = {}) => {
1561
1809
  }
1562
1810
  }
1563
1811
  }, [retryOnError, maxRetries]);
1564
- useEffect6(() => {
1812
+ useEffect7(() => {
1565
1813
  if (autoFetch) {
1566
1814
  refreshProfile();
1567
1815
  }
1568
1816
  }, [autoFetch, refreshProfile]);
1569
- useEffect6(() => {
1817
+ useEffect7(() => {
1570
1818
  mountedRef.current = true;
1571
1819
  return () => {
1572
1820
  mountedRef.current = false;
@@ -1586,11 +1834,18 @@ var useUserProfile = (options = {}) => {
1586
1834
  };
1587
1835
  export {
1588
1836
  CrudifyLogin_default as CrudifyLogin,
1837
+ ERROR_CODES,
1838
+ ERROR_SEVERITY_MAP,
1589
1839
  default2 as crudify,
1590
1840
  decodeJwtSafely,
1591
1841
  getCookie,
1592
1842
  getCurrentUserEmail,
1843
+ getErrorMessage,
1844
+ handleCrudifyError,
1593
1845
  isTokenExpired,
1846
+ parseApiError,
1847
+ parseJavaScriptError,
1848
+ parseTransactionError,
1594
1849
  secureLocalStorage,
1595
1850
  secureSessionStorage,
1596
1851
  useCrudifyLogin,