Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Account Page Pagination Approve Decline Multiple #76

Merged
merged 10 commits into from
Apr 28, 2024
190 changes: 150 additions & 40 deletions src/components/Accounts/ApprovedAccounts.jsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,177 @@
import { NPOBackend } from '../../utils/auth_utils.js';
import { useEffect, useState } from 'react';
import { useEffect, useState, useCallback } from 'react';
import { Box, Table, Thead, Tbody, Tr, Th, Td, TableContainer, Button, Checkbox, useDisclosure } from '@chakra-ui/react'
import { CloseIcon } from '@chakra-ui/icons'
import DeleteAccountModal from './DeleteAccountModal.jsx';
import PropTypes from 'prop-types';
import PaginationFooter from "../../components/Catalog/PaginationFooter/PaginationFooter";
import { usePagination } from '@ajna/pagination';

const ApprovedAccounts = ( {accountType} ) => {
const ApprovedAccounts = ( {accountType, searchQuery} ) => {
const [approvedAccounts, setApprovedAccounts] = useState([]);
const { isOpen: isDeleteOpen, onOpen: onDeleteOpen, onClose: onDeleteClose } = useDisclosure();
const [deleteItemId, setDeleteItemId] = useState("");
const [deleteItemId, setDeleteItemId] = useState([]);
const [totalRowCount, setTotalRowCount] = useState(0);
const { currentPage, setCurrentPage, pagesCount, offset, pageSize, setPageSize} = usePagination({
initialState: { currentPage: 1, pageSize: 10 },
total: totalRowCount,
});
const [individualChecked, setIndividualChecked] = useState(new Array(approvedAccounts.length).fill(false));
const [checkedAccountIds, setCheckedAccountIds] = useState([]);
const [dataShouldRevalidate, setDataShouldRevalidate] = useState(false);

const fetchTableData = useCallback(async () => {
try {
const { data } = await NPOBackend.get(`/users/approved-accounts`, {
params: {
keyword: (searchQuery && searchQuery.length) && searchQuery,
page: currentPage,
limit: pageSize,
accountType: accountType}
});
setApprovedAccounts(data.accounts);
setTotalRowCount(Number(data.count[0].count));
} catch (error) {
console.error('Error fetching data:', error);
}
}, [searchQuery, currentPage, pageSize, accountType]);

useEffect(() => {
fetchTableData();
}, [fetchTableData]);

useEffect(() => {
if (dataShouldRevalidate) {
fetchTableData();
setDataShouldRevalidate(false);
setIndividualChecked(new Array(totalRowCount).fill(false));
setCheckedAccountIds([]);
}
}, [dataShouldRevalidate, fetchTableData, totalRowCount]);

useEffect(() => {
setCurrentPage(1);
}, [searchQuery, setCurrentPage, pageSize]);

useEffect(() => {
const renderTable = async () => {
const { data } = await NPOBackend.get('/users/approved-accounts');
setApprovedAccounts(data);
};
renderTable();
}, [approvedAccounts])
setIndividualChecked(new Array(totalRowCount).fill(false));
setCheckedAccountIds([]);
}, [searchQuery, currentPage, totalRowCount]);

const handleDeleteClick = id => {
setDeleteItemId(id);
onDeleteOpen();
}

const updateAllCheckedAccountIds = (e) => {
setIndividualChecked(new Array(approvedAccounts.length).fill(e.target.checked));
if (e.target.checked) {
let allIds = [];
for (let i = 0; i < approvedAccounts.length; i++) {
allIds.push(approvedAccounts[i].id)
}
setCheckedAccountIds(allIds);
} else {
setCheckedAccountIds([]);
}
}

const updateIndividualCheckedAccountIds = (e, id, index) => {
const newIndividualChecked = [...individualChecked];
newIndividualChecked[index] = e.target.checked;
setIndividualChecked(newIndividualChecked);
let newCheckedAccountIds = [... checkedAccountIds];
if (e.target.checked) {
newCheckedAccountIds.push(id);
setCheckedAccountIds(newCheckedAccountIds);
} else {
let index = newCheckedAccountIds.indexOf(id);
newCheckedAccountIds.splice(index, 1);
setCheckedAccountIds(newCheckedAccountIds);
}
}

return (
<Box>
<TableContainer>
<Table variant='simple'>
<Thead>
<Tr>
<Th width="5%"><Checkbox isDisabled /></Th>
<Th>Name</Th>
<Th>Email</Th>
<Th>Deactivate</Th>
</Tr>
</Thead>
<Tbody>
{
approvedAccounts.map((account, i) => (
accountType === account.type ? (
<Tr key={i}>
<Td><Checkbox></Checkbox></Td>
<Td>{account.firstName} {account.lastName}</Td>
<Td>{account.email}</Td>
<Td>
<Button onClick={() => { handleDeleteClick(account.id) }} size='sm' variant='outline'><CloseIcon w={3} h={3} color='gray'/></Button>
</Td>
</Tr>
) : (
<></>
)
))
<TableContainer border="1px solid #ededed" borderRadius="10px">
<Table variant='simple'>
<Thead>
<Tr>
<Th w="5%" h="50px"><Checkbox onChange={(e) => { updateAllCheckedAccountIds(e) }}/></Th>
<Th w="30%">Name</Th>
<Th w="30%">Email</Th>
<Th w="0" textAlign="right" >Deactivate</Th>
{checkedAccountIds.length > 0 &&
<Th w="20%" textAlign="right">
<Button isDisabled={checkedAccountIds.length === 0}
onClick={() => { handleDeleteClick(checkedAccountIds) }}
size="xs"
variant="outline"
borderRadius="4px"
borderWidth="1px"
padding="0"
borderColor={checkedAccountIds.length != 0 ? 'red' : 'gray.500'}>
<CloseIcon w="10px" h="10px" color={checkedAccountIds.length != 0 ? 'red' : 'gray'}/>
</Button>
</Th>
}
</Tr>
</Thead>
<Tbody>
{
approvedAccounts.map((account, i) => (
<Tr key={i}>
<Td>
<Checkbox
isChecked={individualChecked[i]}
onChange={(e) => { updateIndividualCheckedAccountIds(e, account.id, i)}}>
</Checkbox>
</Td>
<Td>{account.firstName} {account.lastName}</Td>
<Td>{account.email}</Td>
{checkedAccountIds.length > 0 &&
<Td></Td>
}
</Tbody>
</Table>
</TableContainer>
<DeleteAccountModal isOpen={isDeleteOpen} onClose={onDeleteClose} deleteItemId={deleteItemId} />
<Td textAlign="right">
<Button
onClick={() => { handleDeleteClick([account.id]) }}
size="xs"
variant="outline"
borderColor="gray.500"
borderRadius="4px"
borderWidth="1px"
padding="0"
>
<CloseIcon w="10px" h="10px" color="gray.500"/>
</Button>
</Td>
</Tr>
))
}
</Tbody>
</Table>
<PaginationFooter
pagesCount={pagesCount}
totalRowCount={totalRowCount}
setPageSize={setPageSize}
currentPage={currentPage}
setCurrentPage={setCurrentPage}
rangeString={`${offset + 1} - ${offset + approvedAccounts.length}`}
/>
</TableContainer>
<DeleteAccountModal
isOpen={isDeleteOpen}
onClose={onDeleteClose}
deleteItemId={deleteItemId}
setDataShouldRevalidate={setDataShouldRevalidate}
/>
</Box>
)
}

ApprovedAccounts.propTypes = {
accountType: PropTypes.string.isRequired,
searchQuery: PropTypes.string
};

export default ApprovedAccounts;
export default ApprovedAccounts;
12 changes: 8 additions & 4 deletions src/components/Accounts/DeleteAccountModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import {
} from '@chakra-ui/react';
import { NPOBackend } from '../../utils/auth_utils.js';

const DeleteAccountModal = ({ isOpen, onClose, deleteItemId}) => {
const DeleteAccountModal = ({ isOpen, onClose, deleteItemId, setDataShouldRevalidate}) => {
const handleConfirmDelete = async idToDelete => {
try {
await NPOBackend.delete(`/users/${idToDelete}`);
for (let i = 0; i < idToDelete.length; i++) {
await NPOBackend.delete(`/users/${idToDelete[i]}`);
}
onClose();
setDataShouldRevalidate(true);
} catch (error) {
console.error(error);
}
Expand All @@ -30,7 +33,7 @@ const DeleteAccountModal = ({ isOpen, onClose, deleteItemId}) => {
<ModalBody>Are you sure? You cannot undo this action afterwards.</ModalBody>
<ModalFooter gap='3'>
<Button onClick={onClose}>Cancel</Button>
<Button onClick={() => handleConfirmDelete(deleteItemId)} colorScheme='red'>Delete</Button>
<Button onClick={() => {handleConfirmDelete(deleteItemId)}} colorScheme='red'>Delete</Button>
</ModalFooter>
</ModalContent>
</Modal>
Expand All @@ -40,7 +43,8 @@ const DeleteAccountModal = ({ isOpen, onClose, deleteItemId}) => {
DeleteAccountModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
deleteItemId: PropTypes.string.isRequired,
deleteItemId: PropTypes.array.isRequired,
setDataShouldRevalidate: PropTypes.func.isRequired
};

export default DeleteAccountModal;
Loading
Loading