Refactor context dependencies

This commit is contained in:
IRBorisov 2023-08-11 17:36:09 +03:00
parent df4dc7bf23
commit b9d0dd4c20
4 changed files with 43 additions and 46 deletions

View File

@ -2,14 +2,15 @@ import { createContext, useCallback, useContext, useLayoutEffect, useState } fro
import { type ErrorInfo } from '../components/BackendError';
import useLocalStorage from '../hooks/useLocalStorage';
import { type DataCallback, getAuth, postLogin, postLogout, postSignup } from '../utils/backendAPI';
import { ICurrentUser, IUserLoginData, IUserProfile, IUserSignupData } from '../utils/models';
import { type DataCallback, getAuth, patchPassword,postLogin, postLogout, postSignup } from '../utils/backendAPI';
import { ICurrentUser, IUserLoginData, IUserProfile, IUserSignupData, IUserUpdatePassword } from '../utils/models';
interface IAuthContext {
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
reload: (callback?: () => void) => void
loading: boolean
error: ErrorInfo
@ -85,13 +86,28 @@ export const AuthState = ({ children }: AuthStateProps) => {
});
}
const updatePassword = useCallback(
(data: IUserUpdatePassword, callback?: () => void) => {
setError(undefined);
patchPassword({
data: data,
showError: true,
setLoading: setLoading,
onError: error => { setError(error); },
onSuccess: () => {
setUser(undefined);
reload();
if (callback) callback();
}});
}, [setUser, reload]);
useLayoutEffect(() => {
reload();
}, [reload])
return (
<AuthContext.Provider
value={{ user, login, logout, signup, loading, error, reload, setError }}
value={{ user, login, logout, signup, loading, error, reload, setError, updatePassword }}
>
{children}
</AuthContext.Provider>

View File

@ -1,9 +1,8 @@
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { ErrorInfo } from '../components/BackendError';
import { DataCallback, getProfile, patchPassword,patchProfile } from '../utils/backendAPI';
import { IUserProfile, IUserUpdateData, IUserUpdatePassword } from '../utils/models';
import { useAuth } from './AuthContext';
import { DataCallback, getProfile, patchProfile } from '../utils/backendAPI';
import { IUserProfile, IUserUpdateData } from '../utils/models';
interface IUserProfileContext {
user: IUserProfile | undefined
@ -12,7 +11,6 @@ interface IUserProfileContext {
error: ErrorInfo
setError: (error: ErrorInfo) => void
updateUser: (data: IUserUpdateData, callback?: DataCallback<IUserProfile>) => void
updatePassword: (data: IUserUpdatePassword, callback?: () => void) => void
}
const ProfileContext = createContext<IUserProfileContext | null>(null);
@ -36,7 +34,6 @@ export const UserProfileState = ({ children }: UserProfileStateProps) => {
const [loading, setLoading] = useState(false);
const [processing, setProcessing] = useState(false);
const [error, setError] = useState<ErrorInfo>(undefined);
const auth = useAuth()
const reload = useCallback(
() => {
@ -67,29 +64,13 @@ export const UserProfileState = ({ children }: UserProfileStateProps) => {
}, [setUser]
);
const updatePassword = useCallback(
(data: IUserUpdatePassword, callback?: () => void) => {
setError(undefined);
patchPassword({
data: data,
showError: true,
setLoading: setProcessing,
onError: error => { setError(error); },
onSuccess: () => {
setUser(undefined);
auth.reload();
if (callback) callback();
}});
}, [setUser, auth]
);
useEffect(() => {
reload();
}, [reload]);
return (
<ProfileContext.Provider
value={{user, updateUser, updatePassword, error, loading, setError, processing}}
value={{user, updateUser, error, loading, setError, processing}}
>
{children}
</ProfileContext.Provider>

View File

@ -1,31 +1,34 @@
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { toast } from 'react-toastify';
import BackendError from '../../components/BackendError';
import TextInput from '../../components/Common/TextInput';
import { useUserProfile } from '../../context/UserProfileContext';
import { useAuth } from '../../context/AuthContext';
import { IUserUpdatePassword } from '../../utils/models';
export function ChangePassword() {
const { updatePassword, processing } = useUserProfile();
const { updatePassword, error, loading } = useAuth();
const [old_password, setOldPassword] = useState('');
const [new_password, setNewPassword] = useState('');
const [new_password_repeat, setNewPasswordRepeat] = useState('');
const [new_pass_color, setNewPassColor] = useState('');
const [oldPassword, setOldPassword] = useState('');
const [newPassword, setNewPassword] = useState('');
const [newPasswordRepeat, setNewPasswordRepeat] = useState('');
const navigate = useNavigate();
const colorClass = useMemo(() => {
return !!newPassword && !!newPasswordRepeat && newPassword !== newPasswordRepeat ? 'bg-red-500' : '';
}, [newPassword, newPasswordRepeat]);
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
if (new_password !== new_password_repeat) {
setNewPassColor('bg-red-500');
if (newPassword !== newPasswordRepeat) {
toast.error('Пароли не совпадают');
}
else {
const data: IUserUpdatePassword = {
old_password: old_password,
new_password: new_password,
old_password: oldPassword,
new_password: newPassword,
};
updatePassword(data, () => {toast.success('Изменения сохранены'); navigate('/login')});
}
@ -37,36 +40,34 @@ export function ChangePassword() {
<TextInput id='old_password'
type='password'
label='Введите старый пароль:'
value={old_password}
value={oldPassword}
onChange={event => setOldPassword(event.target.value)}
/>
<TextInput id='new_password'
colorClass={new_pass_color}
colorClass={colorClass}
label="Введите новый пароль:"
value={new_password}
value={newPassword}
onChange={event => {
setNewPassword(event.target.value);
setNewPassColor('');
}}
/>
<TextInput id='new_password_repeat'
colorClass={new_pass_color}
colorClass={colorClass}
label="Повторите новый пароль:"
value={new_password_repeat}
value={newPasswordRepeat}
onChange={event => {
setNewPasswordRepeat(event.target.value);
setNewPassColor('');
}}
/>
<div className='relative flex justify-center my-4 border'>
<button
type='submit'
className='absolute bottom-0 px-2 py-1 bg-blue-500 border'
disabled={processing}>
disabled={loading}>
<span>Сменить пароль</span>
</button>
</div>
{ error && <BackendError error={error} />}
</form>
</div>
)}

View File

@ -17,7 +17,6 @@ export function initBackend() {
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'x-csrftoken';
axios.defaults.baseURL = `${config.backend}`;
}
// ================ Data transfer types ================