@pagamio/frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
151 lines (150 loc) • 4.78 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
function createInitialState() {
return {
user: null,
isAuthenticated: false,
isLoading: true,
error: null,
};
}
/**
* Authentication context with generic type parameter
*/
export const AuthContext = createContext({
...createInitialState(),
login: async () => {
return {};
},
logout: async () => { },
updateUser: () => { },
clearError: () => { },
authService: {},
});
/**
* Authentication context provider component with generic type parameter
*/
export function AuthProvider({ children, authService, validateOnInit = false, }) {
const [state, setState] = useState(() => createInitialState());
const setPartialState = useCallback((newState) => {
setState((prev) => ({ ...prev, ...newState }));
}, []);
// Initialize auth state from service
useEffect(() => {
const initializeAuth = async () => {
try {
const user = authService.getUser();
if (!user) {
setPartialState({
isAuthenticated: false,
isLoading: false,
});
return;
}
if (validateOnInit) {
const isValid = await authService.validateSession();
if (!isValid) {
await authService.logout();
setPartialState({
user: null,
isAuthenticated: false,
isLoading: false,
});
return;
}
}
setPartialState({
user,
isAuthenticated: true,
isLoading: false,
});
}
catch (error) {
setPartialState({
error: {
code: 'AUTH_INIT_ERROR',
message: 'Failed to initialize authentication',
},
isLoading: false,
});
}
};
initializeAuth().then();
}, [authService, setPartialState, validateOnInit]);
const login = useCallback(async (credentials, rememberMe = false) => {
try {
const response = await authService.login(credentials, rememberMe);
setPartialState({
user: response.user,
isAuthenticated: true,
error: null,
});
return response;
}
catch (error) {
setPartialState({
error: {
code: 'LOGIN_ERROR',
message: 'Failed to process login response',
},
});
throw error;
}
}, [authService, setPartialState]);
const logout = useCallback(async () => {
try {
await authService.logout();
setPartialState({
user: null,
isAuthenticated: false,
error: null,
});
}
catch (error) {
setPartialState({
error: {
code: 'LOGOUT_ERROR',
message: 'Failed to logout properly',
},
});
}
}, [authService, setPartialState]);
const updateUser = useCallback(async (userData) => {
try {
const updatedUser = await authService.updateProfile(userData);
setPartialState({
user: updatedUser,
});
}
catch (error) {
setPartialState({
error: {
code: 'UPDATE_USER_ERROR',
message: 'Failed to update user profile',
},
});
}
}, [authService, setPartialState]);
const clearError = useCallback(() => {
setPartialState({ error: null });
}, [setPartialState]);
const contextValue = useMemo(() => ({
...state,
authService,
login,
logout,
updateUser,
clearError,
}), [state, login, logout, updateUser, clearError, authService]);
return _jsx(AuthContext.Provider, { value: contextValue, children: children });
}
/**
* Custom hook for using auth context with generic type parameter
*/
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}