2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
|
|
|
|
2023-07-25 20:27:29 +03:00
|
|
|
import { createContext, useCallback, useContext, useLayoutEffect, useState } from 'react';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2024-07-24 23:20:59 +03:00
|
|
|
import { DataCallback } from '@/backend/apiTransport';
|
2024-02-25 20:55:30 +03:00
|
|
|
import {
|
|
|
|
getAuth,
|
|
|
|
patchPassword,
|
|
|
|
postLogin,
|
|
|
|
postLogout,
|
|
|
|
postRequestPasswordReset,
|
|
|
|
postResetPassword,
|
|
|
|
postSignup,
|
|
|
|
postValidatePasswordToken
|
2024-07-24 23:20:59 +03:00
|
|
|
} from '@/backend/users';
|
2024-04-27 15:19:20 +03:00
|
|
|
import { type ErrorData } from '@/components/info/InfoError';
|
2024-05-26 14:54:02 +03:00
|
|
|
import {
|
|
|
|
ICurrentUser,
|
|
|
|
IPasswordTokenData,
|
|
|
|
IRequestPasswordData,
|
|
|
|
IResetPasswordData,
|
|
|
|
IUserInfo,
|
|
|
|
IUserLoginData,
|
|
|
|
IUserProfile,
|
|
|
|
IUserSignupData,
|
|
|
|
IUserUpdatePassword
|
|
|
|
} from '@/models/user';
|
2024-06-06 23:11:53 +03:00
|
|
|
import { contextOutsideScope } from '@/utils/labels';
|
2023-12-13 14:32:57 +03:00
|
|
|
|
2023-08-27 15:39:49 +03:00
|
|
|
import { useUsers } from './UsersContext';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
interface IAuthContext {
|
2023-12-28 14:04:44 +03:00
|
|
|
user: ICurrentUser | undefined;
|
|
|
|
login: (data: IUserLoginData, callback?: DataCallback) => void;
|
|
|
|
logout: (callback?: DataCallback) => void;
|
|
|
|
signup: (data: IUserSignupData, callback?: DataCallback<IUserProfile>) => void;
|
|
|
|
updatePassword: (data: IUserUpdatePassword, callback?: () => void) => void;
|
2024-02-25 20:55:30 +03:00
|
|
|
requestPasswordReset: (data: IRequestPasswordData, callback?: () => void) => void;
|
|
|
|
validateToken: (data: IPasswordTokenData, callback?: () => void) => void;
|
|
|
|
resetPassword: (data: IResetPasswordData, callback?: () => void) => void;
|
2023-12-28 14:04:44 +03:00
|
|
|
loading: boolean;
|
|
|
|
error: ErrorData;
|
|
|
|
setError: (error: ErrorData) => void;
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-07-25 00:20:37 +03:00
|
|
|
const AuthContext = createContext<IAuthContext | null>(null);
|
|
|
|
export const useAuth = () => {
|
|
|
|
const context = useContext(AuthContext);
|
|
|
|
if (!context) {
|
2024-06-06 23:11:53 +03:00
|
|
|
throw new Error(contextOutsideScope('useAuth', 'AuthState'));
|
2023-07-25 00:20:37 +03:00
|
|
|
}
|
|
|
|
return context;
|
2023-12-28 14:04:44 +03:00
|
|
|
};
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2024-09-19 17:49:25 +03:00
|
|
|
export const AuthState = ({ children }: React.PropsWithChildren) => {
|
2023-08-27 15:39:49 +03:00
|
|
|
const { users } = useUsers();
|
2024-03-27 15:32:59 +03:00
|
|
|
const [user, setUser] = useState<ICurrentUser | undefined>(undefined);
|
2024-04-27 15:19:20 +03:00
|
|
|
const [loading, setLoading] = useState(true);
|
2023-12-13 14:32:57 +03:00
|
|
|
const [error, setError] = useState<ErrorData>(undefined);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
const reload = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(callback?: () => void) => {
|
|
|
|
getAuth({
|
|
|
|
onError: () => setUser(undefined),
|
2024-04-27 15:19:20 +03:00
|
|
|
setLoading: setLoading,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: currentUser => {
|
|
|
|
if (currentUser.id) {
|
|
|
|
setUser(currentUser);
|
|
|
|
} else {
|
|
|
|
setUser(undefined);
|
|
|
|
}
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.();
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
});
|
|
|
|
},
|
|
|
|
[setUser]
|
|
|
|
);
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
function login(data: IUserLoginData, callback?: DataCallback) {
|
2023-07-15 17:46:19 +03:00
|
|
|
setError(undefined);
|
2023-07-15 17:57:25 +03:00
|
|
|
postLogin({
|
2023-07-26 23:11:00 +03:00
|
|
|
data: data,
|
2024-02-03 15:58:55 +03:00
|
|
|
showError: false,
|
2023-07-26 23:11:00 +03:00
|
|
|
setLoading: setLoading,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData =>
|
|
|
|
reload(() => {
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.(newData);
|
2023-12-28 14:04:44 +03:00
|
|
|
})
|
2023-07-26 23:11:00 +03:00
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
function logout(callback?: DataCallback) {
|
2023-07-15 17:46:19 +03:00
|
|
|
setError(undefined);
|
2023-07-15 17:57:25 +03:00
|
|
|
postLogout({
|
|
|
|
showError: true,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData =>
|
|
|
|
reload(() => {
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.(newData);
|
2023-12-28 14:04:44 +03:00
|
|
|
})
|
2023-07-26 23:11:00 +03:00
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
function signup(data: IUserSignupData, callback?: DataCallback<IUserProfile>) {
|
2023-07-15 17:46:19 +03:00
|
|
|
setError(undefined);
|
2023-07-15 17:57:25 +03:00
|
|
|
postSignup({
|
2023-07-26 23:11:00 +03:00
|
|
|
data: data,
|
2023-07-15 17:57:25 +03:00
|
|
|
showError: true,
|
2023-07-26 23:11:00 +03:00
|
|
|
setLoading: setLoading,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: newData =>
|
|
|
|
reload(() => {
|
|
|
|
users.push(newData as IUserInfo);
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.(newData);
|
2023-12-28 14:04:44 +03:00
|
|
|
})
|
2023-07-26 23:11:00 +03:00
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
}
|
|
|
|
|
2023-08-11 17:36:09 +03:00
|
|
|
const updatePassword = useCallback(
|
2023-12-28 14:04:44 +03:00
|
|
|
(data: IUserUpdatePassword, callback?: () => void) => {
|
|
|
|
setError(undefined);
|
|
|
|
patchPassword({
|
|
|
|
data: data,
|
|
|
|
showError: true,
|
|
|
|
setLoading: setLoading,
|
2024-01-04 22:10:57 +03:00
|
|
|
onError: setError,
|
2023-12-28 14:04:44 +03:00
|
|
|
onSuccess: () =>
|
|
|
|
reload(() => {
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.();
|
2023-12-28 14:04:44 +03:00
|
|
|
})
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[reload]
|
|
|
|
);
|
2023-08-11 17:36:09 +03:00
|
|
|
|
2024-02-25 20:55:30 +03:00
|
|
|
const requestPasswordReset = useCallback(
|
|
|
|
(data: IRequestPasswordData, callback?: () => void) => {
|
|
|
|
setError(undefined);
|
|
|
|
postRequestPasswordReset({
|
|
|
|
data: data,
|
|
|
|
showError: false,
|
|
|
|
setLoading: setLoading,
|
|
|
|
onError: setError,
|
|
|
|
onSuccess: () =>
|
|
|
|
reload(() => {
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.();
|
2024-02-25 20:55:30 +03:00
|
|
|
})
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[reload]
|
|
|
|
);
|
|
|
|
|
|
|
|
const validateToken = useCallback(
|
|
|
|
(data: IPasswordTokenData, callback?: () => void) => {
|
|
|
|
setError(undefined);
|
|
|
|
postValidatePasswordToken({
|
|
|
|
data: data,
|
|
|
|
showError: false,
|
|
|
|
setLoading: setLoading,
|
|
|
|
onError: setError,
|
|
|
|
onSuccess: () =>
|
|
|
|
reload(() => {
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.();
|
2024-02-25 20:55:30 +03:00
|
|
|
})
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[reload]
|
|
|
|
);
|
|
|
|
|
|
|
|
const resetPassword = useCallback(
|
|
|
|
(data: IResetPasswordData, callback?: () => void) => {
|
|
|
|
setError(undefined);
|
|
|
|
postResetPassword({
|
|
|
|
data: data,
|
|
|
|
showError: false,
|
|
|
|
setLoading: setLoading,
|
|
|
|
onError: setError,
|
|
|
|
onSuccess: () =>
|
|
|
|
reload(() => {
|
2024-12-04 22:53:01 +03:00
|
|
|
callback?.();
|
2024-02-25 20:55:30 +03:00
|
|
|
})
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[reload]
|
|
|
|
);
|
|
|
|
|
2023-07-25 00:20:37 +03:00
|
|
|
useLayoutEffect(() => {
|
2023-07-26 23:11:00 +03:00
|
|
|
reload();
|
2023-12-28 14:04:44 +03:00
|
|
|
}, [reload]);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
return (
|
2024-02-25 20:55:30 +03:00
|
|
|
<AuthContext.Provider
|
|
|
|
value={{
|
|
|
|
user,
|
|
|
|
login,
|
|
|
|
logout,
|
|
|
|
signup,
|
|
|
|
loading,
|
|
|
|
error,
|
|
|
|
setError,
|
|
|
|
updatePassword,
|
|
|
|
requestPasswordReset,
|
|
|
|
validateToken,
|
|
|
|
resetPassword
|
|
|
|
}}
|
|
|
|
>
|
2023-12-28 14:04:44 +03:00
|
|
|
{children}
|
|
|
|
</AuthContext.Provider>
|
|
|
|
);
|
|
|
|
};
|