Merge pull request #113 from anik-ghosh-au7/fix/dashboard
Fix/dashboard
This commit is contained in:
commit
2a91f3e7d8
112
dashboard/src/components/DeleteUserModal.tsx
Normal file
112
dashboard/src/components/DeleteUserModal.tsx
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Center,
|
||||||
|
Flex,
|
||||||
|
MenuItem,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalContent,
|
||||||
|
ModalFooter,
|
||||||
|
ModalHeader,
|
||||||
|
ModalOverlay,
|
||||||
|
useDisclosure,
|
||||||
|
Text,
|
||||||
|
useToast,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { useClient } from 'urql';
|
||||||
|
import { FaRegTrashAlt } from 'react-icons/fa';
|
||||||
|
import { DeleteUser } from '../graphql/mutation';
|
||||||
|
import { capitalizeFirstLetter } from '../utils';
|
||||||
|
|
||||||
|
interface userDataTypes {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeleteUserModal = ({
|
||||||
|
user,
|
||||||
|
updateUserList,
|
||||||
|
}: {
|
||||||
|
user: userDataTypes;
|
||||||
|
updateUserList: Function;
|
||||||
|
}) => {
|
||||||
|
const client = useClient();
|
||||||
|
const toast = useToast();
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
const [userData, setUserData] = React.useState<userDataTypes>({
|
||||||
|
id: '',
|
||||||
|
email: '',
|
||||||
|
});
|
||||||
|
React.useEffect(() => {
|
||||||
|
setUserData(user);
|
||||||
|
}, []);
|
||||||
|
const deleteHandler = async () => {
|
||||||
|
const res = await client
|
||||||
|
.mutation(DeleteUser, { params: { email: userData.email } })
|
||||||
|
.toPromise();
|
||||||
|
if (res.error) {
|
||||||
|
toast({
|
||||||
|
title: capitalizeFirstLetter(res.error.message),
|
||||||
|
isClosable: true,
|
||||||
|
status: 'error',
|
||||||
|
position: 'bottom-right',
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (res.data?._delete_user) {
|
||||||
|
toast({
|
||||||
|
title: capitalizeFirstLetter(res.data?._delete_user.message),
|
||||||
|
isClosable: true,
|
||||||
|
status: 'success',
|
||||||
|
position: 'bottom-right',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onClose();
|
||||||
|
updateUserList();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<MenuItem onClick={onOpen}>Delete User</MenuItem>
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Delete User</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody>
|
||||||
|
<Text fontSize="md">Are you sure?</Text>
|
||||||
|
<Flex
|
||||||
|
padding="5%"
|
||||||
|
marginTop="5%"
|
||||||
|
marginBottom="2%"
|
||||||
|
border="1px solid #ff7875"
|
||||||
|
borderRadius="5px"
|
||||||
|
flexDirection="column"
|
||||||
|
>
|
||||||
|
<Text fontSize="sm">
|
||||||
|
User <b>{user.email}</b> will be deleted permanently!
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
leftIcon={<FaRegTrashAlt />}
|
||||||
|
colorScheme="red"
|
||||||
|
variant="solid"
|
||||||
|
onClick={deleteHandler}
|
||||||
|
isDisabled={false}
|
||||||
|
>
|
||||||
|
<Center h="100%" pt="5%">
|
||||||
|
Delete
|
||||||
|
</Center>
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DeleteUserModal;
|
|
@ -23,9 +23,7 @@ export const AdminLogout = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const UpdateEnvVariables = `
|
export const UpdateEnvVariables = `
|
||||||
mutation updateEnvVariables(
|
mutation updateEnvVariables($params: UpdateEnvInput!) {
|
||||||
$params: UpdateEnvInput!
|
|
||||||
) {
|
|
||||||
_update_env(params: $params) {
|
_update_env(params: $params) {
|
||||||
message
|
message
|
||||||
}
|
}
|
||||||
|
@ -33,11 +31,17 @@ export const UpdateEnvVariables = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const UpdateUser = `
|
export const UpdateUser = `
|
||||||
mutation updateUser(
|
mutation updateUser($params: UpdateUserInput!) {
|
||||||
$params: UpdateUserInput!
|
|
||||||
) {
|
|
||||||
_update_user(params: $params) {
|
_update_user(params: $params) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const DeleteUser = `
|
||||||
|
mutation deleteUser($params: DeleteUserInput!) {
|
||||||
|
_delete_user(params: $params) {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import {
|
||||||
MenuList,
|
MenuList,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
useToast,
|
useToast,
|
||||||
|
Spinner,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FaAngleLeft,
|
FaAngleLeft,
|
||||||
|
@ -40,6 +41,7 @@ import {
|
||||||
import { UserDetailsQuery } from '../graphql/queries';
|
import { UserDetailsQuery } from '../graphql/queries';
|
||||||
import { UpdateUser } from '../graphql/mutation';
|
import { UpdateUser } from '../graphql/mutation';
|
||||||
import EditUserModal from '../components/EditUserModal';
|
import EditUserModal from '../components/EditUserModal';
|
||||||
|
import DeleteUserModal from '../components/DeleteUserModal';
|
||||||
|
|
||||||
interface paginationPropTypes {
|
interface paginationPropTypes {
|
||||||
limit: number;
|
limit: number;
|
||||||
|
@ -98,7 +100,9 @@ export default function Users() {
|
||||||
maxPages: 1,
|
maxPages: 1,
|
||||||
});
|
});
|
||||||
const [userList, setUserList] = React.useState<userDataTypes[]>([]);
|
const [userList, setUserList] = React.useState<userDataTypes[]>([]);
|
||||||
|
const [loading, setLoading] = React.useState<boolean>(false);
|
||||||
const updateUserList = async () => {
|
const updateUserList = async () => {
|
||||||
|
setLoading(true);
|
||||||
const { data } = await client
|
const { data } = await client
|
||||||
.query(UserDetailsQuery, {
|
.query(UserDetailsQuery, {
|
||||||
params: {
|
params: {
|
||||||
|
@ -112,9 +116,21 @@ export default function Users() {
|
||||||
if (data?._users) {
|
if (data?._users) {
|
||||||
const { pagination, users } = data._users;
|
const { pagination, users } = data._users;
|
||||||
const maxPages = getMaxPages(pagination);
|
const maxPages = getMaxPages(pagination);
|
||||||
|
if (users && users.length > 0) {
|
||||||
setPaginationProps({ ...paginationProps, ...pagination, maxPages });
|
setPaginationProps({ ...paginationProps, ...pagination, maxPages });
|
||||||
setUserList(users);
|
setUserList(users);
|
||||||
|
} else {
|
||||||
|
if (paginationProps.page !== 1) {
|
||||||
|
setPaginationProps({
|
||||||
|
...paginationProps,
|
||||||
|
...pagination,
|
||||||
|
maxPages,
|
||||||
|
page: 1,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
};
|
};
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
updateUserList();
|
updateUserList();
|
||||||
|
@ -162,14 +178,13 @@ export default function Users() {
|
||||||
Users
|
Users
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
{userList.length > 0 ? (
|
{!loading ? (
|
||||||
|
userList.length > 0 ? (
|
||||||
<Table variant="simple">
|
<Table variant="simple">
|
||||||
<Thead>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>Email</Th>
|
<Th>Email</Th>
|
||||||
<Th>Created At</Th>
|
<Th>Created At</Th>
|
||||||
<Th>Signup Methods</Th>
|
|
||||||
<Th>Roles</Th>
|
|
||||||
<Th>Verified</Th>
|
<Th>Verified</Th>
|
||||||
<Th>Actions</Th>
|
<Th>Actions</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
|
@ -180,11 +195,7 @@ export default function Users() {
|
||||||
return (
|
return (
|
||||||
<Tr key={user.id} style={{ fontSize: 14 }}>
|
<Tr key={user.id} style={{ fontSize: 14 }}>
|
||||||
<Td>{user.email}</Td>
|
<Td>{user.email}</Td>
|
||||||
<Td>
|
<Td>{dayjs(user.created_at).format('MMM DD, YYYY')}</Td>
|
||||||
{dayjs(user.created_at * 1000).format('MMM DD, YYYY')}
|
|
||||||
</Td>
|
|
||||||
<Td>{user.signup_methods}</Td>
|
|
||||||
<Td>{user.roles.join(', ')}</Td>
|
|
||||||
<Td>
|
<Td>
|
||||||
<Tag
|
<Tag
|
||||||
size="sm"
|
size="sm"
|
||||||
|
@ -208,10 +219,6 @@ export default function Users() {
|
||||||
</Flex>
|
</Flex>
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<MenuList>
|
<MenuList>
|
||||||
<EditUserModal
|
|
||||||
user={rest}
|
|
||||||
updateUserList={updateUserList}
|
|
||||||
/>
|
|
||||||
{!user.email_verified && (
|
{!user.email_verified && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => userVerificationHandler(user)}
|
onClick={() => userVerificationHandler(user)}
|
||||||
|
@ -219,6 +226,14 @@ export default function Users() {
|
||||||
Verify User
|
Verify User
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
<EditUserModal
|
||||||
|
user={rest}
|
||||||
|
updateUserList={updateUserList}
|
||||||
|
/>
|
||||||
|
<DeleteUserModal
|
||||||
|
user={rest}
|
||||||
|
updateUserList={updateUserList}
|
||||||
|
/>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
</Td>
|
</Td>
|
||||||
|
@ -226,9 +241,13 @@ export default function Users() {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Tbody>
|
</Tbody>
|
||||||
{paginationProps.maxPages > 1 && (
|
{(paginationProps.maxPages > 1 || paginationProps.total >= 5) && (
|
||||||
<TableCaption>
|
<TableCaption>
|
||||||
<Flex justifyContent="space-between" alignItems="center" m="2% 0">
|
<Flex
|
||||||
|
justifyContent="space-between"
|
||||||
|
alignItems="center"
|
||||||
|
m="2% 0"
|
||||||
|
>
|
||||||
<Flex flex="1">
|
<Flex flex="1">
|
||||||
<Tooltip label="First Page">
|
<Tooltip label="First Page">
|
||||||
<IconButton
|
<IconButton
|
||||||
|
@ -364,6 +383,11 @@ export default function Users() {
|
||||||
No Data
|
No Data
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Center minH="25vh">
|
||||||
|
<Spinner />
|
||||||
|
</Center>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user