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; 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( export async function getUsersPage(
skip: number, skip: number,
limit: number, limit: number,
@ -476,42 +464,6 @@ export async function getUsersPage(
return []; 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() { export async function getApiKey() {
try { try {
const res = await api.get(`${BASE_URL_API}api_key/`); const res = await api.get(`${BASE_URL_API}api_key/`);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,8 +1,19 @@
import FeatureFlags from "@/../feature-config.json"; 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 { usePostAddApiKey } from "@/controllers/API/queries/api-keys";
import {
useResetPassword,
useUpdateUser,
} from "@/controllers/API/queries/auth";
import { useGetProfilePicturesQuery } from "@/controllers/API/queries/files"; import { useGetProfilePicturesQuery } from "@/controllers/API/queries/files";
import useAuthStore from "@/stores/authStore"; 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 { useParams } from "react-router-dom";
import { CONTROL_PATCH_USER_STATE } from "../../../../constants/constants"; import { CONTROL_PATCH_USER_STATE } from "../../../../constants/constants";
import { AuthContext } from "../../../../contexts/authContext"; import { AuthContext } from "../../../../contexts/authContext";
@ -13,13 +24,10 @@ import {
inputHandlerEventType, inputHandlerEventType,
patchUserInputStateType, patchUserInputStateType,
} from "../../../../types/components"; } 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 useScrollToElement from "../hooks/use-scroll-to-element";
import GeneralPageHeaderComponent from "./components/GeneralPageHeader"; import GeneralPageHeaderComponent from "./components/GeneralPageHeader";
import PasswordFormComponent from "./components/PasswordForm"; import PasswordFormComponent from "./components/PasswordForm";
import ProfilePictureFormComponent from "./components/ProfilePictureForm"; import ProfilePictureFormComponent from "./components/ProfilePictureForm";
import useGetProfilePictures from "./components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures";
import StoreApiKeyFormComponent from "./components/StoreApiKeyForm"; import StoreApiKeyFormComponent from "./components/StoreApiKeyForm";
export const GeneralPage = () => { export const GeneralPage = () => {
@ -48,20 +56,61 @@ export const GeneralPage = () => {
const setValidApiKey = useStoreStore((state) => state.updateValidApiKey); const setValidApiKey = useStoreStore((state) => state.updateValidApiKey);
const setLoadingApiKey = useStoreStore((state) => state.updateLoadingApiKey); const setLoadingApiKey = useStoreStore((state) => state.updateLoadingApiKey);
const { handlePatchPassword } = usePatchPassword( const { mutate: mutateResetPassword } = useResetPassword();
userData, const { mutate: mutatePatchUser } = useUpdateUser();
setSuccessData,
setErrorData, 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 handleGetProfilePictures = useGetProfilePicturesQuery();
const { handlePatchProfilePicture } = usePatchProfilePicture( const handlePatchProfilePicture = (profile_picture) => {
setSuccessData, if (profile_picture !== "") {
setErrorData, mutatePatchUser(
userData, { user_id: userData!.id, user: { profile_image: profile_picture } },
setUserData, {
); 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); 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 * as Form from "@radix-ui/react-form";
import { FormEvent, useEffect, useState } from "react"; import { FormEvent, useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
@ -9,7 +10,6 @@ import {
CONTROL_INPUT_STATE, CONTROL_INPUT_STATE,
SIGN_UP_SUCCESS, SIGN_UP_SUCCESS,
} from "../../constants/constants"; } from "../../constants/constants";
import { addUser } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import { import {
UserInputType, UserInputType,
@ -28,6 +28,8 @@ export default function SignUp(): JSX.Element {
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
const navigate = useNavigate(); const navigate = useNavigate();
const { mutate: mutateAddUser } = useAddUser();
function handleInput({ function handleInput({
target: { name, value }, target: { name, value },
}: inputHandlerEventType): void { }: inputHandlerEventType): void {
@ -47,14 +49,15 @@ export default function SignUp(): JSX.Element {
username: username.trim(), username: username.trim(),
password: password.trim(), password: password.trim(),
}; };
addUser(newUser)
.then((user) => { mutateAddUser(newUser, {
onSuccess: () => {
setSuccessData({ setSuccessData({
title: SIGN_UP_SUCCESS, title: SIGN_UP_SUCCESS,
}); });
navigate("/login"); navigate("/login");
}) },
.catch((error) => { onError: (error) => {
const { const {
response: { response: {
data: { detail }, data: { detail },
@ -64,8 +67,8 @@ export default function SignUp(): JSX.Element {
title: SIGNUP_ERROR_ALERT, title: SIGNUP_ERROR_ALERT,
list: [detail], list: [detail],
}); });
return; },
}); });
} }
return ( return (

View file

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