diff --git a/src/config/Pages.ts b/src/config/Pages.ts index 5271b4b..341f8ad 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -66,6 +66,7 @@ export const Pages = { users: { list: "/users/list", create: "/users/create", + detail: "/users/detail/", roleList: "/users/roles-all", roleCreate: "/users/roles-add", groupAdd: "/users/group-add", diff --git a/src/pages/users/List.tsx b/src/pages/users/List.tsx index 985b811..2e71299 100644 --- a/src/pages/users/List.tsx +++ b/src/pages/users/List.tsx @@ -1,14 +1,16 @@ import { FC, useState } from 'react' import { useTranslation } from 'react-i18next' import Button from '../../components/Button' -import { Add, Eye } from 'iconsax-react' +import { Add, Eye, Trash } from 'iconsax-react' import Input from '../../components/Input' import Td from '../../components/Td' import { Link, useNavigate } from 'react-router-dom' import { Pages } from '../../config/Pages' -import { useGetUsers } from './hooks/useUserData' +import { useDeleteUser, useGetUsers } from './hooks/useUserData' import { UserItemType } from './types/UserTypes' import PageLoading from '../../components/PageLoading' +import { toast } from 'react-toastify' +import { ErrorType } from '../../helpers/types' const UsersList: FC = () => { @@ -16,6 +18,19 @@ const UsersList: FC = () => { const { t } = useTranslation('global') const [search, setSearch] = useState('') const getUsers = useGetUsers(search) + const deleteUser = useDeleteUser() + + const handleDeleteUser = (id: string) => { + deleteUser.mutate(id, { + onSuccess: () => { + toast.success(t('success')) + getUsers.refetch() + }, + onError: (error: ErrorType) => { + toast.error(error.response?.data?.error?.message[0]) + } + }) + } return (
@@ -83,9 +98,17 @@ const UsersList: FC = () => { } - - - +
+ + + + + handleDeleteUser(item.id)} + /> +
diff --git a/src/pages/users/Update.tsx b/src/pages/users/Update.tsx new file mode 100644 index 0000000..2b476c8 --- /dev/null +++ b/src/pages/users/Update.tsx @@ -0,0 +1,199 @@ +import { FC, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import Button from '../../components/Button' +import { TickCircle } from 'iconsax-react' +import Input from '../../components/Input' +import Select from '../../components/Select' +import UploadBoxDraggble from '../../components/UploadBoxDraggble' +import { useFormik } from 'formik' +import { CreateUserType, RoleItemType } from './types/UserTypes' +import * as Yup from 'yup' +import { useSingleUpload } from '../service/hooks/useServiceData' +import { useGetRoles, useGetUserDetail, useUpdateUser } from './hooks/useUserData' +import { toast } from 'react-toastify' +import { ErrorType } from '../../helpers/types' +import { useNavigate, useParams } from 'react-router-dom' +import { Pages } from '../../config/Pages' + +const UpdateUser: FC = () => { + const { id } = useParams() + const navigate = useNavigate() + const { t } = useTranslation('global') + const [file, setFile] = useState() + const getRoles = useGetRoles('') + const singleUpload = useSingleUpload() + const updateUser = useUpdateUser() + const { data: userDetail } = useGetUserDetail(id || '') + + const handleUpdateUser = (values: CreateUserType) => { + updateUser.mutate({ id: id || '', params: values }, { + onSuccess: () => { + toast.success(t('success')) + navigate(Pages.users.list) + }, + onError: (error: ErrorType) => { + toast.error(error.response?.data?.error?.message[0]) + } + }) + } + + const formik = useFormik({ + initialValues: { + email: '', + firstName: '', + lastName: '', + password: '', + repeatPassword: '', + phone: '', + profilePic: '', + roleId: '' + }, + validationSchema: Yup.object({ + email: Yup.string().email('Invalid email').required(t('errors.required')), + firstName: Yup.string().required(t('errors.required')), + lastName: Yup.string().required(t('errors.required')), + phone: Yup.string().required(t('errors.required')), + roleId: Yup.string().required(t('errors.required')), + }), + onSubmit: async (values) => { + if (values.password === '') { + values.password = undefined + values.repeatPassword = undefined + } + if (file) { + const formData = new FormData() + formData.append('file', file) + await singleUpload.mutateAsync(formData, { + onSuccess: (data) => { + values.profilePic = data?.data?.url + handleUpdateUser(values) + }, + onError: (error: ErrorType) => { + toast.error(error.response?.data?.error?.message[0]) + } + }) + } else { + values.profilePic = undefined + handleUpdateUser(values) + } + } + }) + + useEffect(() => { + if (userDetail?.data) { + formik.setValues(userDetail?.data?.admin) + formik.setFieldValue('roleId', userDetail?.data?.admin?.roles?.[0]?.id) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [userDetail]) + + return ( +
+
+
+ {t('service.cateory_services')} +
+ +
+ +
+
+
+ {t('user.info_user')} +
+ +
+ + +
+
+ {/* */} + + +
+ +
+ +
+ + +
+ +
+ +
+
+ {t('user.image')} +
+
+ setFile(file[0])} + /> +
+
+
+
+ +
+ ) +} + +export default UpdateUser \ No newline at end of file diff --git a/src/pages/users/hooks/useUserData.ts b/src/pages/users/hooks/useUserData.ts index 482177c..97ed957 100644 --- a/src/pages/users/hooks/useUserData.ts +++ b/src/pages/users/hooks/useUserData.ts @@ -39,6 +39,26 @@ export const useGetUsers = (search: string, permission?: string) => { }); }; +export const useGetUserDetail = (id: string) => { + return useQuery({ + queryKey: ["user-detail", id], + queryFn: () => api.getUserDetail(id), + }); +}; + +export const useUpdateUser = () => { + return useMutation({ + mutationFn: ({ id, params }: { id: string; params: CreateUserType }) => + api.updateUser(id, params), + }); +}; + +export const useDeleteUser = () => { + return useMutation({ + mutationFn: (id: string) => api.deleteUser(id), + }); +}; + export const useCreateGroup = () => { return useMutation({ mutationFn: (variables: CreateGroupType) => api.createGroup(variables), diff --git a/src/pages/users/service/UserService.ts b/src/pages/users/service/UserService.ts index ff268ad..fa37190 100644 --- a/src/pages/users/service/UserService.ts +++ b/src/pages/users/service/UserService.ts @@ -32,6 +32,21 @@ export const getUsers = async (search: string, permission?: string) => { return data; }; +export const getUserDetail = async (id: string) => { + const { data } = await axios.get(`/users/admins/${id}`); + return data; +}; + +export const updateUser = async (id: string, params: CreateUserType) => { + const { data } = await axios.patch(`/users/admins/${id}`, params); + return data; +}; + +export const deleteUser = async (id: string) => { + const { data } = await axios.delete(`/users/admins/${id}`); + return data; +}; + export const createGroup = async (params: CreateGroupType) => { const { data } = await axios.post(`/users/user-group`, params); return data; diff --git a/src/pages/users/types/UserTypes.ts b/src/pages/users/types/UserTypes.ts index 87e6f4c..258f067 100644 --- a/src/pages/users/types/UserTypes.ts +++ b/src/pages/users/types/UserTypes.ts @@ -16,8 +16,8 @@ export type CreateUserType = { phone: string; firstName: string; lastName: string; - password: string; - repeatPassword: string; + password?: string; + repeatPassword?: string; email: string; roleId: string; profilePic?: string; diff --git a/src/router/Main.tsx b/src/router/Main.tsx index e62f622..c18a470 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -60,6 +60,7 @@ import UpdateCustomer from '../pages/customer/Update' import UpdateBlog from '../pages/blog/Update' import Update from '../pages/annoncement/Update' import UpdateDiscount from '../pages/discounts/UpdateDiscount' +import UpdateUser from '../pages/users/Update' const MainRouter: FC = () => { const { hasSubMenu } = useSharedStore() @@ -123,6 +124,7 @@ const MainRouter: FC = () => { } /> } /> } /> + } /> } /> } /> } />