@nocios/crudify-ui 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -1108
- package/README_DEPTH.md +1046 -0
- package/dist/index.d.mts +181 -1
- package/dist/index.d.ts +181 -1
- package/dist/index.js +393 -20
- package/dist/index.mjs +388 -19
- package/package.json +1 -1
- package/MIGRATION-GUIDE.md +0 -312
- package/MIGRATION.md +0 -201
- package/MIGRATION_EXAMPLE.md +0 -538
- package/TECHNICAL_SPECIFICATION.md +0 -344
- package/example-app.tsx +0 -197
- package/mejoras_npm_lib.md +0 -790
- package/tsup.config.ts +0 -9
package/dist/index.mjs
CHANGED
|
@@ -704,7 +704,7 @@ var useCrudifyAuth = () => {
|
|
|
704
704
|
// src/components/CrudifyLogin/Forms/LoginForm.tsx
|
|
705
705
|
import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
706
706
|
var LoginForm = ({ onScreenChange, onExternalNavigate, onLoginSuccess, onError, redirectUrl = "/" }) => {
|
|
707
|
-
const { crudify:
|
|
707
|
+
const { crudify: crudify9 } = useCrudify();
|
|
708
708
|
const { state, updateFormData, setFieldError, clearErrors, setLoading } = useLoginState();
|
|
709
709
|
const { setToken } = useCrudifyAuth();
|
|
710
710
|
const { t } = useTranslation();
|
|
@@ -756,10 +756,10 @@ var LoginForm = ({ onScreenChange, onExternalNavigate, onLoginSuccess, onError,
|
|
|
756
756
|
clearErrors();
|
|
757
757
|
setLoading(true);
|
|
758
758
|
try {
|
|
759
|
-
if (!
|
|
759
|
+
if (!crudify9) {
|
|
760
760
|
throw new Error("Crudify not initialized");
|
|
761
761
|
}
|
|
762
|
-
const response = await
|
|
762
|
+
const response = await crudify9.login(state.formData.username, state.formData.password);
|
|
763
763
|
setLoading(false);
|
|
764
764
|
if (response.success) {
|
|
765
765
|
console.log("\u{1F510} LoginForm - Login successful, setting tokens");
|
|
@@ -922,7 +922,7 @@ import { useState as useState3 } from "react";
|
|
|
922
922
|
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";
|
|
923
923
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
924
924
|
var ForgotPasswordForm = ({ onScreenChange, onError }) => {
|
|
925
|
-
const { crudify:
|
|
925
|
+
const { crudify: crudify9 } = useCrudify();
|
|
926
926
|
const [email, setEmail] = useState3("");
|
|
927
927
|
const [loading, setLoading] = useState3(false);
|
|
928
928
|
const [errors, setErrors] = useState3([]);
|
|
@@ -951,7 +951,7 @@ var ForgotPasswordForm = ({ onScreenChange, onError }) => {
|
|
|
951
951
|
return emailRegex.test(email2);
|
|
952
952
|
};
|
|
953
953
|
const handleSubmit = async () => {
|
|
954
|
-
if (loading || !
|
|
954
|
+
if (loading || !crudify9) return;
|
|
955
955
|
setErrors([]);
|
|
956
956
|
setHelperTextEmail(null);
|
|
957
957
|
if (!email) {
|
|
@@ -965,7 +965,7 @@ var ForgotPasswordForm = ({ onScreenChange, onError }) => {
|
|
|
965
965
|
setLoading(true);
|
|
966
966
|
try {
|
|
967
967
|
const data = [{ operation: "requestPasswordReset", data: { email } }];
|
|
968
|
-
const response = await
|
|
968
|
+
const response = await crudify9.transaction(data);
|
|
969
969
|
if (response.success) {
|
|
970
970
|
if (response.data && response.data.existingCodeValid) {
|
|
971
971
|
setCodeAlreadyExists(true);
|
|
@@ -1068,7 +1068,7 @@ import { useState as useState4, useEffect as useEffect5 } from "react";
|
|
|
1068
1068
|
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";
|
|
1069
1069
|
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1070
1070
|
var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess }) => {
|
|
1071
|
-
const { crudify:
|
|
1071
|
+
const { crudify: crudify9 } = useCrudify();
|
|
1072
1072
|
const [newPassword, setNewPassword] = useState4("");
|
|
1073
1073
|
const [confirmPassword, setConfirmPassword] = useState4("");
|
|
1074
1074
|
const [loading, setLoading] = useState4(false);
|
|
@@ -1148,9 +1148,9 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
1148
1148
|
setErrors([t("resetPassword.invalidCode")]);
|
|
1149
1149
|
setValidatingCode(false);
|
|
1150
1150
|
setTimeout(() => onScreenChange?.("forgotPassword"), 3e3);
|
|
1151
|
-
}, [searchParams,
|
|
1151
|
+
}, [searchParams, crudify9, t, onScreenChange]);
|
|
1152
1152
|
useEffect5(() => {
|
|
1153
|
-
if (
|
|
1153
|
+
if (crudify9 && pendingValidation && !isValidating) {
|
|
1154
1154
|
setIsValidating(true);
|
|
1155
1155
|
const validateCode = async (emailToValidate, codeToValidate) => {
|
|
1156
1156
|
try {
|
|
@@ -1160,7 +1160,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
1160
1160
|
data: { email: emailToValidate, codePassword: codeToValidate }
|
|
1161
1161
|
}
|
|
1162
1162
|
];
|
|
1163
|
-
const response = await
|
|
1163
|
+
const response = await crudify9.transaction(data);
|
|
1164
1164
|
if (response.data && Array.isArray(response.data)) {
|
|
1165
1165
|
const validationResult = response.data[0];
|
|
1166
1166
|
if (validationResult && validationResult.response && validationResult.response.status === "OK") {
|
|
@@ -1189,7 +1189,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
1189
1189
|
};
|
|
1190
1190
|
validateCode(pendingValidation.email, pendingValidation.code);
|
|
1191
1191
|
}
|
|
1192
|
-
}, [
|
|
1192
|
+
}, [crudify9, pendingValidation, t, onScreenChange]);
|
|
1193
1193
|
const validatePassword = (password) => {
|
|
1194
1194
|
if (password.length < 8) {
|
|
1195
1195
|
return t("resetPassword.passwordTooShort");
|
|
@@ -1197,7 +1197,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
1197
1197
|
return null;
|
|
1198
1198
|
};
|
|
1199
1199
|
const handleSubmit = async () => {
|
|
1200
|
-
if (loading || !
|
|
1200
|
+
if (loading || !crudify9) return;
|
|
1201
1201
|
setErrors([]);
|
|
1202
1202
|
setHelperTextNewPassword(null);
|
|
1203
1203
|
setHelperTextConfirmPassword(null);
|
|
@@ -1228,7 +1228,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
1228
1228
|
data: { email, codePassword: code, newPassword }
|
|
1229
1229
|
}
|
|
1230
1230
|
];
|
|
1231
|
-
const response = await
|
|
1231
|
+
const response = await crudify9.transaction(data);
|
|
1232
1232
|
if (response.success) {
|
|
1233
1233
|
setErrors([]);
|
|
1234
1234
|
setTimeout(() => {
|
|
@@ -1339,7 +1339,7 @@ import { useState as useState5, useEffect as useEffect6 } from "react";
|
|
|
1339
1339
|
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";
|
|
1340
1340
|
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1341
1341
|
var CheckCodeForm = ({ onScreenChange, onError, searchParams }) => {
|
|
1342
|
-
const { crudify:
|
|
1342
|
+
const { crudify: crudify9 } = useCrudify();
|
|
1343
1343
|
const [code, setCode] = useState5("");
|
|
1344
1344
|
const [loading, setLoading] = useState5(false);
|
|
1345
1345
|
const [errors, setErrors] = useState5([]);
|
|
@@ -1378,7 +1378,7 @@ var CheckCodeForm = ({ onScreenChange, onError, searchParams }) => {
|
|
|
1378
1378
|
}
|
|
1379
1379
|
}, [searchParams, onScreenChange]);
|
|
1380
1380
|
const handleSubmit = async () => {
|
|
1381
|
-
if (loading || !
|
|
1381
|
+
if (loading || !crudify9) return;
|
|
1382
1382
|
setErrors([]);
|
|
1383
1383
|
setHelperTextCode(null);
|
|
1384
1384
|
if (!code) {
|
|
@@ -1397,7 +1397,7 @@ var CheckCodeForm = ({ onScreenChange, onError, searchParams }) => {
|
|
|
1397
1397
|
data: { email, codePassword: code }
|
|
1398
1398
|
}
|
|
1399
1399
|
];
|
|
1400
|
-
const response = await
|
|
1400
|
+
const response = await crudify9.transaction(data);
|
|
1401
1401
|
if (response.success) {
|
|
1402
1402
|
onScreenChange?.("resetPassword", { email, code, fromCodeVerification: "true" });
|
|
1403
1403
|
} else {
|
|
@@ -3154,12 +3154,40 @@ function useSession(options = {}) {
|
|
|
3154
3154
|
}
|
|
3155
3155
|
|
|
3156
3156
|
// src/providers/SessionProvider.tsx
|
|
3157
|
-
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
3157
|
+
import { createContext as createContext4, useContext as useContext4, useMemo as useMemo3 } from "react";
|
|
3158
3158
|
import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3159
3159
|
var SessionContext = createContext4(void 0);
|
|
3160
3160
|
function SessionProvider({ children, options = {} }) {
|
|
3161
|
-
const
|
|
3162
|
-
|
|
3161
|
+
const sessionHook = useSession(options);
|
|
3162
|
+
const sessionData = useMemo3(() => {
|
|
3163
|
+
if (!sessionHook.tokens?.accessToken || !sessionHook.isAuthenticated) {
|
|
3164
|
+
return null;
|
|
3165
|
+
}
|
|
3166
|
+
try {
|
|
3167
|
+
const decoded = decodeJwtSafely(sessionHook.tokens.accessToken);
|
|
3168
|
+
if (decoded && decoded.sub && decoded.email && decoded.subscriber) {
|
|
3169
|
+
const result = {
|
|
3170
|
+
_id: decoded.sub,
|
|
3171
|
+
email: decoded.email,
|
|
3172
|
+
subscriberKey: decoded.subscriber
|
|
3173
|
+
};
|
|
3174
|
+
Object.keys(decoded).forEach((key) => {
|
|
3175
|
+
if (!["sub", "email", "subscriber"].includes(key)) {
|
|
3176
|
+
result[key] = decoded[key];
|
|
3177
|
+
}
|
|
3178
|
+
});
|
|
3179
|
+
return result;
|
|
3180
|
+
}
|
|
3181
|
+
} catch (error) {
|
|
3182
|
+
console.error("Error decoding JWT token for sessionData:", error);
|
|
3183
|
+
}
|
|
3184
|
+
return null;
|
|
3185
|
+
}, [sessionHook.tokens?.accessToken, sessionHook.isAuthenticated]);
|
|
3186
|
+
const contextValue = {
|
|
3187
|
+
...sessionHook,
|
|
3188
|
+
sessionData
|
|
3189
|
+
};
|
|
3190
|
+
return /* @__PURE__ */ jsx11(SessionContext.Provider, { value: contextValue, children });
|
|
3163
3191
|
}
|
|
3164
3192
|
function useSessionContext() {
|
|
3165
3193
|
const context = useContext4(SessionContext);
|
|
@@ -3401,6 +3429,344 @@ function SessionStatus() {
|
|
|
3401
3429
|
] })
|
|
3402
3430
|
] });
|
|
3403
3431
|
}
|
|
3432
|
+
|
|
3433
|
+
// src/hooks/useUserData.ts
|
|
3434
|
+
import { useState as useState11, useEffect as useEffect10, useCallback as useCallback6, useRef as useRef4 } from "react";
|
|
3435
|
+
import crudify7 from "@nocios/crudify-browser";
|
|
3436
|
+
var useUserData = (options = {}) => {
|
|
3437
|
+
const { autoFetch = true, retryOnError = false, maxRetries = 3 } = options;
|
|
3438
|
+
const { isAuthenticated, isInitialized, sessionData, tokens } = useSessionContext();
|
|
3439
|
+
const [userData, setUserData] = useState11(null);
|
|
3440
|
+
const [loading, setLoading] = useState11(false);
|
|
3441
|
+
const [error, setError] = useState11(null);
|
|
3442
|
+
const abortControllerRef = useRef4(null);
|
|
3443
|
+
const mountedRef = useRef4(true);
|
|
3444
|
+
const requestIdRef = useRef4(0);
|
|
3445
|
+
const retryCountRef = useRef4(0);
|
|
3446
|
+
const getUserEmail = useCallback6(() => {
|
|
3447
|
+
if (!sessionData) return null;
|
|
3448
|
+
return sessionData.email || sessionData["cognito:username"] || null;
|
|
3449
|
+
}, [sessionData]);
|
|
3450
|
+
const clearProfile = useCallback6(() => {
|
|
3451
|
+
setUserData(null);
|
|
3452
|
+
setError(null);
|
|
3453
|
+
setLoading(false);
|
|
3454
|
+
retryCountRef.current = 0;
|
|
3455
|
+
}, []);
|
|
3456
|
+
const refreshProfile = useCallback6(async () => {
|
|
3457
|
+
const userEmail = getUserEmail();
|
|
3458
|
+
console.log("\u{1F464} useUserData - Refreshing profile for:", userEmail);
|
|
3459
|
+
if (!userEmail) {
|
|
3460
|
+
if (mountedRef.current) {
|
|
3461
|
+
setError("No user email available from session data");
|
|
3462
|
+
setLoading(false);
|
|
3463
|
+
}
|
|
3464
|
+
return;
|
|
3465
|
+
}
|
|
3466
|
+
if (!isInitialized) {
|
|
3467
|
+
if (mountedRef.current) {
|
|
3468
|
+
setError("Session not initialized");
|
|
3469
|
+
setLoading(false);
|
|
3470
|
+
}
|
|
3471
|
+
return;
|
|
3472
|
+
}
|
|
3473
|
+
if (abortControllerRef.current) {
|
|
3474
|
+
abortControllerRef.current.abort();
|
|
3475
|
+
}
|
|
3476
|
+
const abortController = new AbortController();
|
|
3477
|
+
abortControllerRef.current = abortController;
|
|
3478
|
+
const currentRequestId = ++requestIdRef.current;
|
|
3479
|
+
try {
|
|
3480
|
+
if (mountedRef.current) {
|
|
3481
|
+
setLoading(true);
|
|
3482
|
+
setError(null);
|
|
3483
|
+
}
|
|
3484
|
+
console.log("\u{1F464} useUserData - Fetching profile data from database");
|
|
3485
|
+
const response = await crudify7.readItems("users", {
|
|
3486
|
+
filter: { email: userEmail },
|
|
3487
|
+
pagination: { limit: 1 }
|
|
3488
|
+
});
|
|
3489
|
+
console.log("\u{1F464} useUserData - Database response:", response);
|
|
3490
|
+
console.log("\u{1F464} useUserData - response.data:", response.data);
|
|
3491
|
+
console.log("\u{1F464} useUserData - response.data type:", typeof response.data);
|
|
3492
|
+
if (currentRequestId === requestIdRef.current && mountedRef.current && !abortController.signal.aborted) {
|
|
3493
|
+
let userData2 = null;
|
|
3494
|
+
if (response.success) {
|
|
3495
|
+
console.log("\u{1F464} useUserData - Processing successful response:", {
|
|
3496
|
+
dataType: typeof response.data,
|
|
3497
|
+
isArray: Array.isArray(response.data),
|
|
3498
|
+
hasResponse: !!response.data?.response,
|
|
3499
|
+
hasResponseData: !!response.data?.response?.data,
|
|
3500
|
+
responseDataType: typeof response.data?.response?.data
|
|
3501
|
+
});
|
|
3502
|
+
if (Array.isArray(response.data) && response.data.length > 0) {
|
|
3503
|
+
console.log("\u{1F464} useUserData - Found direct array format");
|
|
3504
|
+
userData2 = response.data[0];
|
|
3505
|
+
} else if (response.data?.response?.data) {
|
|
3506
|
+
console.log("\u{1F464} useUserData - Found nested response.data format");
|
|
3507
|
+
try {
|
|
3508
|
+
const rawData = response.data.response.data;
|
|
3509
|
+
console.log("\u{1F464} useUserData - Raw nested data:", rawData);
|
|
3510
|
+
console.log("\u{1F464} useUserData - Raw data type:", typeof rawData);
|
|
3511
|
+
const parsedData = typeof rawData === "string" ? JSON.parse(rawData) : rawData;
|
|
3512
|
+
console.log("\u{1F464} useUserData - Parsed nested data:", parsedData);
|
|
3513
|
+
if (parsedData && parsedData.items && Array.isArray(parsedData.items) && parsedData.items.length > 0) {
|
|
3514
|
+
userData2 = parsedData.items[0];
|
|
3515
|
+
console.log("\u{1F464} useUserData - Extracted user from nested items:", userData2);
|
|
3516
|
+
} else {
|
|
3517
|
+
console.log("\u{1F464} useUserData - No items found in parsed data or items array is empty");
|
|
3518
|
+
}
|
|
3519
|
+
} catch (parseError) {
|
|
3520
|
+
console.error("\u{1F464} useUserData - Error parsing nested response data:", parseError);
|
|
3521
|
+
}
|
|
3522
|
+
} else if (response.data && typeof response.data === "object") {
|
|
3523
|
+
console.log("\u{1F464} useUserData - Found object format, checking for items");
|
|
3524
|
+
if (response.data.items && Array.isArray(response.data.items) && response.data.items.length > 0) {
|
|
3525
|
+
console.log("\u{1F464} useUserData - Found items in object format");
|
|
3526
|
+
userData2 = response.data.items[0];
|
|
3527
|
+
} else {
|
|
3528
|
+
console.log("\u{1F464} useUserData - No items found in object format");
|
|
3529
|
+
}
|
|
3530
|
+
} else if (response.data?.data?.response?.data) {
|
|
3531
|
+
console.log("\u{1F464} useUserData - Found double-nested data.data.response.data format");
|
|
3532
|
+
try {
|
|
3533
|
+
const rawData = response.data.data.response.data;
|
|
3534
|
+
console.log("\u{1F464} useUserData - Raw double-nested data:", rawData);
|
|
3535
|
+
const parsedData = typeof rawData === "string" ? JSON.parse(rawData) : rawData;
|
|
3536
|
+
console.log("\u{1F464} useUserData - Parsed double-nested data:", parsedData);
|
|
3537
|
+
if (parsedData && parsedData.items && Array.isArray(parsedData.items) && parsedData.items.length > 0) {
|
|
3538
|
+
userData2 = parsedData.items[0];
|
|
3539
|
+
console.log("\u{1F464} useUserData - Extracted user from double-nested items:", userData2);
|
|
3540
|
+
}
|
|
3541
|
+
} catch (parseError) {
|
|
3542
|
+
console.error("\u{1F464} useUserData - Error parsing double-nested response data:", parseError);
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
if (userData2) {
|
|
3547
|
+
console.log("\u{1F464} useUserData - User data found:", userData2);
|
|
3548
|
+
setUserData(userData2);
|
|
3549
|
+
setError(null);
|
|
3550
|
+
retryCountRef.current = 0;
|
|
3551
|
+
console.log("\u{1F464} useUserData - Profile loaded successfully:", userData2);
|
|
3552
|
+
} else {
|
|
3553
|
+
setError("User profile not found in database");
|
|
3554
|
+
setUserData(null);
|
|
3555
|
+
console.warn("\u{1F464} useUserData - User not found for email:", userEmail);
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
} catch (err) {
|
|
3559
|
+
if (currentRequestId === requestIdRef.current && mountedRef.current) {
|
|
3560
|
+
const error2 = err;
|
|
3561
|
+
console.error("\u{1F464} useUserData - Error fetching profile:", error2);
|
|
3562
|
+
if (error2.name === "AbortError") {
|
|
3563
|
+
return;
|
|
3564
|
+
}
|
|
3565
|
+
const shouldRetry = retryOnError && retryCountRef.current < maxRetries && (error2.message?.includes("Network Error") || error2.message?.includes("Failed to fetch"));
|
|
3566
|
+
if (shouldRetry) {
|
|
3567
|
+
retryCountRef.current++;
|
|
3568
|
+
console.log(`\u{1F464} useUserData - Retrying profile fetch (${retryCountRef.current}/${maxRetries})`);
|
|
3569
|
+
setTimeout(() => {
|
|
3570
|
+
if (mountedRef.current) {
|
|
3571
|
+
refreshProfile();
|
|
3572
|
+
}
|
|
3573
|
+
}, 1e3 * retryCountRef.current);
|
|
3574
|
+
} else {
|
|
3575
|
+
setError("Failed to load user profile from database");
|
|
3576
|
+
setUserData(null);
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
} finally {
|
|
3580
|
+
if (currentRequestId === requestIdRef.current && mountedRef.current) {
|
|
3581
|
+
setLoading(false);
|
|
3582
|
+
}
|
|
3583
|
+
if (abortControllerRef.current === abortController) {
|
|
3584
|
+
abortControllerRef.current = null;
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
}, [isInitialized, getUserEmail, retryOnError, maxRetries]);
|
|
3588
|
+
useEffect10(() => {
|
|
3589
|
+
if (autoFetch && isAuthenticated && isInitialized) {
|
|
3590
|
+
refreshProfile();
|
|
3591
|
+
} else if (!isAuthenticated) {
|
|
3592
|
+
clearProfile();
|
|
3593
|
+
}
|
|
3594
|
+
}, [autoFetch, isAuthenticated, isInitialized, refreshProfile, clearProfile]);
|
|
3595
|
+
useEffect10(() => {
|
|
3596
|
+
mountedRef.current = true;
|
|
3597
|
+
return () => {
|
|
3598
|
+
mountedRef.current = false;
|
|
3599
|
+
if (abortControllerRef.current) {
|
|
3600
|
+
abortControllerRef.current.abort();
|
|
3601
|
+
abortControllerRef.current = null;
|
|
3602
|
+
}
|
|
3603
|
+
};
|
|
3604
|
+
}, []);
|
|
3605
|
+
const user = {
|
|
3606
|
+
session: sessionData,
|
|
3607
|
+
// Usar sessionData del nuevo sistema
|
|
3608
|
+
data: userData
|
|
3609
|
+
// Mantener userData del database igual que legacy
|
|
3610
|
+
};
|
|
3611
|
+
return {
|
|
3612
|
+
user,
|
|
3613
|
+
loading,
|
|
3614
|
+
error,
|
|
3615
|
+
refreshProfile,
|
|
3616
|
+
clearProfile
|
|
3617
|
+
};
|
|
3618
|
+
};
|
|
3619
|
+
|
|
3620
|
+
// src/hooks/useAuth.ts
|
|
3621
|
+
import { useCallback as useCallback7 } from "react";
|
|
3622
|
+
var useAuth = () => {
|
|
3623
|
+
const {
|
|
3624
|
+
isAuthenticated,
|
|
3625
|
+
isLoading,
|
|
3626
|
+
isInitialized,
|
|
3627
|
+
tokens,
|
|
3628
|
+
error,
|
|
3629
|
+
sessionData,
|
|
3630
|
+
login,
|
|
3631
|
+
logout,
|
|
3632
|
+
refreshTokens,
|
|
3633
|
+
clearError,
|
|
3634
|
+
getTokenInfo,
|
|
3635
|
+
isExpiringSoon,
|
|
3636
|
+
expiresIn,
|
|
3637
|
+
refreshExpiresIn
|
|
3638
|
+
} = useSessionContext();
|
|
3639
|
+
const setToken = useCallback7((token) => {
|
|
3640
|
+
if (token) {
|
|
3641
|
+
console.warn("useAuth.setToken() is deprecated. Use login() method instead for better security.");
|
|
3642
|
+
} else {
|
|
3643
|
+
logout();
|
|
3644
|
+
}
|
|
3645
|
+
}, [logout]);
|
|
3646
|
+
const tokenExpiration = tokens?.expiresAt ? new Date(tokens.expiresAt) : null;
|
|
3647
|
+
return {
|
|
3648
|
+
// Estado básico (compatible con legacy)
|
|
3649
|
+
isAuthenticated,
|
|
3650
|
+
loading: isLoading,
|
|
3651
|
+
// En el nuevo sistema se llama isLoading
|
|
3652
|
+
error,
|
|
3653
|
+
// Datos del token (compatible con legacy + mejorado)
|
|
3654
|
+
token: tokens?.accessToken || null,
|
|
3655
|
+
user: sessionData,
|
|
3656
|
+
// sessionData del nuevo sistema (más rico que legacy)
|
|
3657
|
+
tokenExpiration,
|
|
3658
|
+
// Acciones (compatible con legacy + mejorado)
|
|
3659
|
+
setToken,
|
|
3660
|
+
logout,
|
|
3661
|
+
refreshToken: refreshTokens,
|
|
3662
|
+
// Funcionalidad real en el nuevo sistema
|
|
3663
|
+
// Nuevas funcionalidades del sistema de refresh tokens
|
|
3664
|
+
login,
|
|
3665
|
+
isExpiringSoon,
|
|
3666
|
+
expiresIn,
|
|
3667
|
+
refreshExpiresIn,
|
|
3668
|
+
getTokenInfo,
|
|
3669
|
+
clearError
|
|
3670
|
+
};
|
|
3671
|
+
};
|
|
3672
|
+
|
|
3673
|
+
// src/hooks/useData.ts
|
|
3674
|
+
import { useCallback as useCallback8 } from "react";
|
|
3675
|
+
import crudify8 from "@nocios/crudify-browser";
|
|
3676
|
+
var useData = () => {
|
|
3677
|
+
const {
|
|
3678
|
+
isInitialized,
|
|
3679
|
+
isLoading,
|
|
3680
|
+
error,
|
|
3681
|
+
isAuthenticated,
|
|
3682
|
+
login: sessionLogin
|
|
3683
|
+
} = useSessionContext();
|
|
3684
|
+
const isReady = useCallback8(() => {
|
|
3685
|
+
return isInitialized && !isLoading && !error;
|
|
3686
|
+
}, [isInitialized, isLoading, error]);
|
|
3687
|
+
const waitForReady = useCallback8(async () => {
|
|
3688
|
+
return new Promise((resolve, reject) => {
|
|
3689
|
+
const checkReady = () => {
|
|
3690
|
+
if (isReady()) {
|
|
3691
|
+
resolve();
|
|
3692
|
+
} else if (error) {
|
|
3693
|
+
reject(new Error(error));
|
|
3694
|
+
} else {
|
|
3695
|
+
setTimeout(checkReady, 100);
|
|
3696
|
+
}
|
|
3697
|
+
};
|
|
3698
|
+
checkReady();
|
|
3699
|
+
});
|
|
3700
|
+
}, [isReady, error]);
|
|
3701
|
+
const ensureReady = useCallback8(async () => {
|
|
3702
|
+
if (!isReady()) {
|
|
3703
|
+
throw new Error("System not ready. Check isInitialized, isLoading, and error states.");
|
|
3704
|
+
}
|
|
3705
|
+
}, [isReady]);
|
|
3706
|
+
const readItems = useCallback8(async (moduleKey, filter, options) => {
|
|
3707
|
+
await ensureReady();
|
|
3708
|
+
return await crudify8.readItems(moduleKey, filter || {}, options);
|
|
3709
|
+
}, [ensureReady]);
|
|
3710
|
+
const readItem = useCallback8(async (moduleKey, filter, options) => {
|
|
3711
|
+
await ensureReady();
|
|
3712
|
+
return await crudify8.readItem(moduleKey, filter, options);
|
|
3713
|
+
}, [ensureReady]);
|
|
3714
|
+
const createItem = useCallback8(async (moduleKey, data, options) => {
|
|
3715
|
+
await ensureReady();
|
|
3716
|
+
return await crudify8.createItem(moduleKey, data, options);
|
|
3717
|
+
}, [ensureReady]);
|
|
3718
|
+
const updateItem = useCallback8(async (moduleKey, data, options) => {
|
|
3719
|
+
await ensureReady();
|
|
3720
|
+
return await crudify8.updateItem(moduleKey, data, options);
|
|
3721
|
+
}, [ensureReady]);
|
|
3722
|
+
const deleteItem = useCallback8(async (moduleKey, id, options) => {
|
|
3723
|
+
await ensureReady();
|
|
3724
|
+
return await crudify8.deleteItem(moduleKey, id, options);
|
|
3725
|
+
}, [ensureReady]);
|
|
3726
|
+
const transaction = useCallback8(async (operations, options) => {
|
|
3727
|
+
await ensureReady();
|
|
3728
|
+
return await crudify8.transaction(operations, options);
|
|
3729
|
+
}, [ensureReady]);
|
|
3730
|
+
const login = useCallback8(async (email, password) => {
|
|
3731
|
+
try {
|
|
3732
|
+
const result = await sessionLogin(email, password);
|
|
3733
|
+
if (result.success) {
|
|
3734
|
+
return {
|
|
3735
|
+
success: true,
|
|
3736
|
+
data: result.tokens
|
|
3737
|
+
};
|
|
3738
|
+
} else {
|
|
3739
|
+
return {
|
|
3740
|
+
success: false,
|
|
3741
|
+
errors: result.error || "Login failed"
|
|
3742
|
+
};
|
|
3743
|
+
}
|
|
3744
|
+
} catch (error2) {
|
|
3745
|
+
return {
|
|
3746
|
+
success: false,
|
|
3747
|
+
errors: error2 instanceof Error ? error2.message : "Login failed"
|
|
3748
|
+
};
|
|
3749
|
+
}
|
|
3750
|
+
}, [sessionLogin]);
|
|
3751
|
+
return {
|
|
3752
|
+
// CRUD operations
|
|
3753
|
+
readItems,
|
|
3754
|
+
readItem,
|
|
3755
|
+
createItem,
|
|
3756
|
+
updateItem,
|
|
3757
|
+
deleteItem,
|
|
3758
|
+
transaction,
|
|
3759
|
+
login,
|
|
3760
|
+
// Estado
|
|
3761
|
+
isInitialized,
|
|
3762
|
+
isInitializing: isLoading,
|
|
3763
|
+
// El nuevo sistema usa isLoading
|
|
3764
|
+
initializationError: error,
|
|
3765
|
+
// Utilidades
|
|
3766
|
+
isReady,
|
|
3767
|
+
waitForReady
|
|
3768
|
+
};
|
|
3769
|
+
};
|
|
3404
3770
|
export {
|
|
3405
3771
|
CrudifyDataProvider,
|
|
3406
3772
|
CrudifyLogin_default as CrudifyLogin,
|
|
@@ -3431,6 +3797,7 @@ export {
|
|
|
3431
3797
|
secureLocalStorage,
|
|
3432
3798
|
secureSessionStorage,
|
|
3433
3799
|
tokenManager,
|
|
3800
|
+
useAuth,
|
|
3434
3801
|
useCrudifyAuth,
|
|
3435
3802
|
useCrudifyConfig,
|
|
3436
3803
|
useCrudifyData,
|
|
@@ -3438,7 +3805,9 @@ export {
|
|
|
3438
3805
|
useCrudifyInstance,
|
|
3439
3806
|
useCrudifyLogin,
|
|
3440
3807
|
useCrudifyUser,
|
|
3808
|
+
useData,
|
|
3441
3809
|
useSession,
|
|
3442
3810
|
useSessionContext,
|
|
3811
|
+
useUserData,
|
|
3443
3812
|
useUserProfile
|
|
3444
3813
|
};
|