refactor: change user's endpoints requests to use useQuery (#3088)

This commit is contained in:
Cristhian Zanforlin Lousa 2024-07-30 22:56:56 -03:00 committed by GitHub
commit 02ed87e8e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 232 additions and 286 deletions

View file

@ -447,18 +447,6 @@ export async function getLoggedUser(): Promise<Users | null> {
return null;
}
export async function addUser(user: UserInputType): Promise<Array<Users>> {
try {
const res = await api.post(`${BASE_URL_API}users/`, user);
if (res.status !== 201) {
throw new Error(res.data.detail);
}
return res.data;
} catch (error) {
throw error;
}
}
export async function getUsersPage(
skip: number,
limit: number,
@ -476,42 +464,6 @@ export async function getUsersPage(
return [];
}
export async function deleteUser(user_id: string) {
try {
const res = await api.delete(`${BASE_URL_API}users/${user_id}`);
if (res.status === 200) {
return res.data;
}
} catch (error) {
throw error;
}
}
export async function updateUser(user_id: string, user: changeUser) {
try {
const res = await api.patch(`${BASE_URL_API}users/${user_id}`, user);
if (res.status === 200) {
return res.data;
}
} catch (error) {
throw error;
}
}
export async function resetPassword(user_id: string, user: resetPasswordType) {
try {
const res = await api.patch(
`${BASE_URL_API}users/${user_id}/reset-password`,
user,
);
if (res.status === 200) {
return res.data;
}
} catch (error) {
throw error;
}
}
export async function getApiKey() {
try {
const res = await api.get(`${BASE_URL_API}api_key/`);

View file

@ -8,7 +8,7 @@ interface DeleteUserParams {
user_id: string;
}
export const useDeleteMessages: useMutationFunctionType<
export const useDeleteUsers: useMutationFunctionType<
undefined,
DeleteUserParams
> = (options?) => {
@ -20,7 +20,7 @@ export const useDeleteMessages: useMutationFunctionType<
};
const mutation: UseMutationResult<DeleteUserParams, any, DeleteUserParams> =
mutate(["useDeleteMessages"], deleteMessage, options);
mutate(["useDeleteUsers"], deleteMessage, options);
return mutation;
};

View file

@ -1,3 +1,8 @@
import {
useAddUser,
useDeleteUsers,
useUpdateUser,
} from "@/controllers/API/queries/auth";
import { cloneDeep } from "lodash";
import { useContext, useEffect, useRef, useState } from "react";
import IconComponent from "../../components/genericIconComponent";
@ -29,12 +34,7 @@ import {
ADMIN_HEADER_TITLE,
} from "../../constants/constants";
import { AuthContext } from "../../contexts/authContext";
import {
addUser,
deleteUser,
getUsersPage,
updateUser,
} from "../../controllers/API";
import { getUsersPage } from "../../controllers/API";
import ConfirmationModal from "../../modals/confirmationModal";
import UserManagementModal from "../../modals/userManagementModal";
import useAlertStore from "../../stores/alertStore";
@ -45,7 +45,7 @@ import { UserInputType } from "../../types/components";
export default function AdminPage() {
const [inputValue, setInputValue] = useState("");
const [size, setPageSize] = useState(10);
const [size, setPageSize] = useState(12);
const [index, setPageIndex] = useState(1);
const [loadingUsers, setLoadingUsers] = useState(true);
const setSuccessData = useAlertStore((state) => state.setSuccessData);
@ -56,6 +56,10 @@ export default function AdminPage() {
(state) => state.setCurrentFlowId,
);
const { mutate: mutateDeleteUser } = useDeleteUsers();
const { mutate: mutateUpdateUser } = useUpdateUser();
const { mutate: mutateAddUser } = useAddUser();
// set null id
useEffect(() => {
setCurrentFlowId("");
@ -121,93 +125,125 @@ export default function AdminPage() {
}
function handleDeleteUser(user) {
deleteUser(user.id)
.then((res) => {
resetFilter();
setSuccessData({
title: USER_DEL_SUCCESS_ALERT,
});
})
.catch((error) => {
setErrorData({
title: USER_DEL_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
});
mutateDeleteUser(
{ user_id: user.id },
{
onSuccess: () => {
resetFilter();
setSuccessData({
title: USER_DEL_SUCCESS_ALERT,
});
},
onError: (error) => {
setErrorData({
title: USER_DEL_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
},
},
);
}
function handleEditUser(userId, user) {
updateUser(userId, user)
.then((res) => {
resetFilter();
setSuccessData({
title: USER_EDIT_SUCCESS_ALERT,
});
})
.catch((error) => {
setErrorData({
title: USER_EDIT_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
});
mutateUpdateUser(
{ user_id: userId, user: user },
{
onSuccess: () => {
resetFilter();
setSuccessData({
title: USER_EDIT_SUCCESS_ALERT,
});
},
onError: (error) => {
setErrorData({
title: USER_EDIT_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
},
},
);
}
function handleDisableUser(check, userId, user) {
const userEdit = cloneDeep(user);
userEdit.is_active = !check;
updateUser(userId, userEdit)
.then((res) => {
resetFilter();
setSuccessData({
title: USER_EDIT_SUCCESS_ALERT,
});
})
.catch((error) => {
setErrorData({
title: USER_EDIT_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
});
mutateUpdateUser(
{ user_id: userId, user: userEdit },
{
onSuccess: () => {
resetFilter();
setSuccessData({
title: USER_EDIT_SUCCESS_ALERT,
});
},
onError: (error) => {
setErrorData({
title: USER_EDIT_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
},
},
);
}
function handleSuperUserEdit(check, userId, user) {
const userEdit = cloneDeep(user);
userEdit.is_superuser = !check;
updateUser(userId, userEdit)
.then((res) => {
resetFilter();
setSuccessData({
title: USER_EDIT_SUCCESS_ALERT,
});
})
.catch((error) => {
setErrorData({
title: USER_EDIT_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
});
mutateUpdateUser(
{ user_id: userId, user: userEdit },
{
onSuccess: () => {
resetFilter();
setSuccessData({
title: USER_EDIT_SUCCESS_ALERT,
});
},
onError: (error) => {
setErrorData({
title: USER_EDIT_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
},
},
);
}
function handleNewUser(user: UserInputType) {
addUser(user)
.then((res) => {
updateUser(res["id"], {
is_active: user.is_active,
is_superuser: user.is_superuser,
}).then((res) => {
resetFilter();
setSuccessData({
title: USER_ADD_SUCCESS_ALERT,
});
});
})
.catch((error) => {
mutateAddUser(user, {
onSuccess: (res) => {
mutateUpdateUser(
{
user_id: res["id"],
user: {
is_active: user.is_active,
is_superuser: user.is_superuser,
},
},
{
onSuccess: () => {
resetFilter();
setSuccessData({
title: USER_ADD_SUCCESS_ALERT,
});
},
onError: (error) => {
setErrorData({
title: USER_ADD_ERROR_ALERT,
list: [error["response"]["data"]["detail"]],
});
},
},
);
},
onError: (error) => {
setErrorData({
title: USER_ADD_ERROR_ALERT,
list: [error.response.data.detail],
list: [error["response"]["data"]["detail"]],
});
});
},
});
}
return (

View file

@ -1,3 +1,7 @@
import {
useResetPassword,
useUpdateUser,
} from "@/controllers/API/queries/auth";
import * as Form from "@radix-ui/react-form";
import { cloneDeep } from "lodash";
import { useContext, useEffect, useState } from "react";
@ -13,7 +17,6 @@ import {
} from "../../constants/alerts_constants";
import { CONTROL_PATCH_USER_STATE } from "../../constants/constants";
import { AuthContext } from "../../contexts/authContext";
import { resetPassword, updateUser } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import {
@ -40,6 +43,9 @@ export default function ProfileSettingsPage(): JSX.Element {
const { userData, setUserData } = useContext(AuthContext);
const { password, cnfPassword, gradient } = inputState;
const { mutate: mutateResetPassword } = useResetPassword();
const { mutate: mutatePatchUser } = useUpdateUser();
async function handlePatchUser() {
if (password !== cnfPassword) {
setErrorData({
@ -48,27 +54,44 @@ export default function ProfileSettingsPage(): JSX.Element {
});
return;
}
try {
if (password !== "") await resetPassword(userData!.id, { password });
if (gradient !== "")
await updateUser(userData!.id, { profile_image: gradient });
if (gradient !== "") {
let newUserData = cloneDeep(userData);
newUserData!.profile_image = gradient;
setUserData(newUserData);
}
handleInput({ target: { name: "password", value: "" } });
handleInput({ target: { name: "cnfPassword", value: "" } });
setSuccessData({ title: SAVE_SUCCESS_ALERT });
} catch (error) {
setErrorData({
title: SAVE_ERROR_ALERT,
list: [(error as any).response.data.detail],
});
if (password !== "") {
mutateResetPassword(
{ user_id: userData!.id, password: { password } },
{
onSuccess: successUpdates,
onError: errorUpdates,
},
);
}
if (gradient !== "") {
mutatePatchUser(
{ user_id: userData!.id, user: { profile_image: gradient } },
{
onSuccess: successUpdates,
onError: errorUpdates,
},
);
}
}
const errorUpdates = (error) => {
setErrorData({
title: SAVE_ERROR_ALERT,
list: [(error as any).response.data.detail],
});
};
const successUpdates = () => {
if (gradient !== "") {
let newUserData = cloneDeep(userData);
newUserData!.profile_image = gradient;
setUserData(newUserData);
}
handleInput({ target: { name: "password", value: "" } });
handleInput({ target: { name: "cnfPassword", value: "" } });
setSuccessData({ title: SAVE_SUCCESS_ALERT });
};
function handleInput({
target: { name, value },
}: inputHandlerEventType): void {

View file

@ -2,7 +2,7 @@ import { useEffect } from "react";
import { BASE_URL_API } from "../../../../../../../../../constants/constants";
const usePreloadImages = (
profilePictures: { [key: string]: string[] },
profilePictures?: { [key: string]: string[] },
setImagesLoaded: (value: boolean) => void,
loading: boolean,
) => {

View file

@ -8,7 +8,7 @@ import { cn } from "../../../../../../../../utils/utils";
import usePreloadImages from "./hooks/use-preload-images";
type ProfilePictureChooserComponentProps = {
profilePictures: ProfilePicturesQueryResponse | undefined;
profilePictures?: ProfilePicturesQueryResponse;
loading: boolean;
value: string;
onChange: (value: string) => void;
@ -30,7 +30,7 @@ export default function ProfilePictureChooserComponent({
}
}, [ref, value]);
usePreloadImages(profilePictures!, setImagesLoaded, loading);
usePreloadImages(profilePictures, setImagesLoaded, loading);
return (
<div className="flex flex-col justify-center gap-2">

View file

@ -1,8 +1,19 @@
import FeatureFlags from "@/../feature-config.json";
import {
EDIT_PASSWORD_ALERT_LIST,
EDIT_PASSWORD_ERROR_ALERT,
SAVE_ERROR_ALERT,
SAVE_SUCCESS_ALERT,
} from "@/constants/alerts_constants";
import { usePostAddApiKey } from "@/controllers/API/queries/api-keys";
import {
useResetPassword,
useUpdateUser,
} from "@/controllers/API/queries/auth";
import { useGetProfilePicturesQuery } from "@/controllers/API/queries/files";
import useAuthStore from "@/stores/authStore";
import { useContext, useEffect, useState } from "react";
import { cloneDeep } from "lodash";
import { useContext, useState } from "react";
import { useParams } from "react-router-dom";
import { CONTROL_PATCH_USER_STATE } from "../../../../constants/constants";
import { AuthContext } from "../../../../contexts/authContext";
@ -13,13 +24,10 @@ import {
inputHandlerEventType,
patchUserInputStateType,
} from "../../../../types/components";
import usePatchPassword from "../hooks/use-patch-password";
import usePatchProfilePicture from "../hooks/use-patch-profile-picture";
import useScrollToElement from "../hooks/use-scroll-to-element";
import GeneralPageHeaderComponent from "./components/GeneralPageHeader";
import PasswordFormComponent from "./components/PasswordForm";
import ProfilePictureFormComponent from "./components/ProfilePictureForm";
import useGetProfilePictures from "./components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures";
import StoreApiKeyFormComponent from "./components/StoreApiKeyForm";
export const GeneralPage = () => {
@ -48,20 +56,61 @@ export const GeneralPage = () => {
const setValidApiKey = useStoreStore((state) => state.updateValidApiKey);
const setLoadingApiKey = useStoreStore((state) => state.updateLoadingApiKey);
const { handlePatchPassword } = usePatchPassword(
userData,
setSuccessData,
setErrorData,
);
const { mutate: mutateResetPassword } = useResetPassword();
const { mutate: mutatePatchUser } = useUpdateUser();
const handlePatchPassword = () => {
if (password !== cnfPassword) {
setErrorData({
title: EDIT_PASSWORD_ERROR_ALERT,
list: [EDIT_PASSWORD_ALERT_LIST],
});
return;
}
if (password !== "") {
mutateResetPassword(
{ user_id: userData!.id, password: { password } },
{
onSuccess: () => {
handleInput({ target: { name: "password", value: "" } });
handleInput({ target: { name: "cnfPassword", value: "" } });
setSuccessData({ title: SAVE_SUCCESS_ALERT });
},
onError: (error) => {
setErrorData({
title: SAVE_ERROR_ALERT,
list: [(error as any)?.response?.data?.detail],
});
},
},
);
}
};
const handleGetProfilePictures = useGetProfilePicturesQuery();
const { handlePatchProfilePicture } = usePatchProfilePicture(
setSuccessData,
setErrorData,
userData,
setUserData,
);
const handlePatchProfilePicture = (profile_picture) => {
if (profile_picture !== "") {
mutatePatchUser(
{ user_id: userData!.id, user: { profile_image: profile_picture } },
{
onSuccess: () => {
let newUserData = cloneDeep(userData);
newUserData!.profile_image = profile_picture;
setUserData(newUserData);
setSuccessData({ title: SAVE_SUCCESS_ALERT });
},
onError: (error) => {
setErrorData({
title: SAVE_ERROR_ALERT,
list: [(error as any)?.response?.data?.detail],
});
},
},
);
}
};
useScrollToElement(scrollId, setCurrentFlowId);

View file

@ -1,37 +0,0 @@
import cloneDeep from "lodash/cloneDeep";
import {
SAVE_ERROR_ALERT,
SAVE_SUCCESS_ALERT,
} from "../../../../constants/alerts_constants";
import { updateUser } from "../../../../controllers/API";
const usePatchGradient = (
setSuccessData,
setErrorData,
currentUserData,
setUserData,
) => {
const handlePatchGradient = async (gradient) => {
try {
if (gradient !== "") {
await updateUser(currentUserData.id, { profile_image: gradient });
let newUserData = cloneDeep(currentUserData);
newUserData.profile_image = gradient;
setUserData(newUserData);
}
setSuccessData({ title: SAVE_SUCCESS_ALERT });
} catch (error) {
setErrorData({
title: SAVE_ERROR_ALERT,
list: [(error as any)?.response?.data?.detail],
});
}
};
return {
currentUserData,
handlePatchGradient,
};
};
export default usePatchGradient;

View file

@ -1,41 +0,0 @@
import {
EDIT_PASSWORD_ALERT_LIST,
EDIT_PASSWORD_ERROR_ALERT,
SAVE_ERROR_ALERT,
SAVE_SUCCESS_ALERT,
} from "../../../../constants/alerts_constants";
import { resetPassword } from "../../../../controllers/API";
import { Users } from "../../../../types/api";
const usePatchPassword = (
userData: Users | null,
setSuccessData: (data: { title: string; list?: string[] }) => void,
setErrorData: (data: { title: string; list: string[] }) => void,
) => {
const handlePatchPassword = async (password, cnfPassword, handleInput) => {
if (password !== cnfPassword) {
setErrorData({
title: EDIT_PASSWORD_ERROR_ALERT,
list: [EDIT_PASSWORD_ALERT_LIST],
});
return;
}
try {
if (password !== "") await resetPassword(userData!.id, { password });
handleInput({ target: { name: "password", value: "" } });
handleInput({ target: { name: "cnfPassword", value: "" } });
setSuccessData({ title: SAVE_SUCCESS_ALERT });
} catch (error) {
setErrorData({
title: SAVE_ERROR_ALERT,
list: [(error as any)?.response?.data?.detail],
});
}
};
return {
handlePatchPassword,
};
};
export default usePatchPassword;

View file

@ -1,40 +0,0 @@
import cloneDeep from "lodash/cloneDeep";
import {
SAVE_ERROR_ALERT,
SAVE_SUCCESS_ALERT,
} from "../../../../constants/alerts_constants";
import { updateUser } from "../../../../controllers/API";
import { Users } from "../../../../types/api";
const usePatchProfilePicture = (
setSuccessData: (data: { title: string; list?: string[] }) => void,
setErrorData: (data: { title: string; list: string[] }) => void,
currentUserData: Users | null,
setUserData: (data: any) => void,
) => {
const handlePatchProfilePicture = async (profile_picture) => {
try {
if (profile_picture !== "") {
await updateUser(currentUserData!.id, {
profile_image: profile_picture,
});
let newUserData = cloneDeep(currentUserData);
newUserData!.profile_image = profile_picture;
setUserData(newUserData);
}
setSuccessData({ title: SAVE_SUCCESS_ALERT });
} catch (error) {
setErrorData({
title: SAVE_ERROR_ALERT,
list: [(error as any)?.response?.data?.detail],
});
}
};
return {
currentUserData,
handlePatchProfilePicture,
};
};
export default usePatchProfilePicture;

View file

@ -1,3 +1,4 @@
import { useAddUser } from "@/controllers/API/queries/auth";
import * as Form from "@radix-ui/react-form";
import { FormEvent, useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
@ -9,7 +10,6 @@ import {
CONTROL_INPUT_STATE,
SIGN_UP_SUCCESS,
} from "../../constants/constants";
import { addUser } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore";
import {
UserInputType,
@ -28,6 +28,8 @@ export default function SignUp(): JSX.Element {
const setErrorData = useAlertStore((state) => state.setErrorData);
const navigate = useNavigate();
const { mutate: mutateAddUser } = useAddUser();
function handleInput({
target: { name, value },
}: inputHandlerEventType): void {
@ -47,14 +49,15 @@ export default function SignUp(): JSX.Element {
username: username.trim(),
password: password.trim(),
};
addUser(newUser)
.then((user) => {
mutateAddUser(newUser, {
onSuccess: () => {
setSuccessData({
title: SIGN_UP_SUCCESS,
});
navigate("/login");
})
.catch((error) => {
},
onError: (error) => {
const {
response: {
data: { detail },
@ -64,8 +67,8 @@ export default function SignUp(): JSX.Element {
title: SIGNUP_ERROR_ALERT,
list: [detail],
});
return;
});
},
});
}
return (

View file

@ -451,6 +451,7 @@ export type patchUserInputStateType = {
cnfPassword: string;
profilePicture: string;
apikey: string;
gradient?: any;
};
export type UserInputType = {