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
156 changes: 132 additions & 24 deletions src/components/Accounts/ApprovedAccounts.jsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,175 @@
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 [totalRowCount, setTotalRowCount] = useState(0);
const { currentPage, setCurrentPage, pagesCount, offset, pageSize, setPageSize } = usePagination({
initialState: { currentPage: 1, pageSize: 10 },
pagesCount: Math.ceil(totalRowCount / 10),
});
const [individualChecked, setIndividualChecked] = useState(new Array(approvedAccounts.length).fill(false));
const [checkedAccountIds, setCheckedAccountIds] = useState([]);
const [dataShouldRevalidate, setDataShouldRevalidate] = useState(false);

// useEffect(() => {
// const renderTable = 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);
// }
// };
// renderTable();
// }, [searchQuery, totalRowCount, currentPage, pageSize, accountType]);

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, totalRowCount, currentPage, pageSize, accountType]);
ThatMegamind marked this conversation as resolved.
Show resolved Hide resolved

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

useEffect(() => {
if (dataShouldRevalidate) {
console.log(dataShouldRevalidate);
fetchTableData();
setDataShouldRevalidate(false);
}
}, [dataShouldRevalidate, fetchTableData]);

useEffect(() => {
const renderTable = async () => {
const { data } = await NPOBackend.get('/users/approved-accounts');
setApprovedAccounts(data);
};
renderTable();
}, [approvedAccounts])
setCurrentPage(1);
}, [searchQuery, setCurrentPage]);

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

const updateAllCheckedAccountIds = (e) => {
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) => {
let newCheckedAccountIds = [... checkedAccountIds];
if (e.target.checked) {
newCheckedAccountIds.push(id);
setCheckedAccountIds(newCheckedAccountIds);
} else {
let index = newCheckedAccountIds.indexOf(id);
newCheckedAccountIds.splice(index, 1);
setCheckedAccountIds(newCheckedAccountIds);
}
console.log(newCheckedAccountIds);
}

return (
<Box>
<TableContainer>
<TableContainer border="1px solid #ededed" borderRadius="10px">
<Table variant='simple'>
<Thead>
<Tr>
<Th width="5%"><Checkbox isDisabled /></Th>
<Th w="5%"><Checkbox onChange={(e) => {setIndividualChecked(new Array(approvedAccounts.length).fill(e.target.checked));
updateAllCheckedAccountIds(e)}}/>
</Th>
<Th>Name</Th>
<Th>Email</Th>
<Th>Deactivate</Th>
<Th w="0">Deactivate</Th>
<Th>
<Button isDisabled={checkedAccountIds.length === 0}
onClick={() => { handleDeleteClick(checkedAccountIds) }}
size='sm'
variant='outline'
borderColor={checkedAccountIds.length != 0 ? 'red' : 'gray'}>
<CloseIcon w={3} h={3} color={checkedAccountIds.length != 0 ? 'red' : 'gray'}/>
</Button>
</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>
) : (
<></>
)
<Tr key={i}>
<Td>
<Checkbox
isChecked={individualChecked[i]}
onChange={(e) => {const newIndividualChecked = [...individualChecked];
newIndividualChecked[i] = e.target.checked;
setIndividualChecked(newIndividualChecked);
updateIndividualCheckedAccountIds(e, account.id)}}>
</Checkbox>
</Td>
<Td>{account.firstName} {account.lastName}</Td>
<Td>{account.email}</Td>
<Td></Td>
<Td>
<Button onClick={() => { handleDeleteClick([account.id]) }} size='sm' variant='outline'><CloseIcon w={3} h={3} color='gray'/></Button>
</Td>
</Tr>
))
}
</Tbody>
</Table>
<PaginationFooter
pagesCount={pagesCount}
totalRowCount={totalRowCount}
setPageSize={setPageSize}
currentPage={currentPage}
setCurrentPage={setCurrentPage}
rangeString={`${offset + 1} - ${offset + Number(pageSize)}`}
/>
</TableContainer>
<DeleteAccountModal isOpen={isDeleteOpen} onClose={onDeleteClose} deleteItemId={deleteItemId} />
<DeleteAccountModal
isOpen={isDeleteOpen}
onClose={onDeleteClose}
deleteItemId={deleteItemId}
setDataShouldRevalidate={setDataShouldRevalidate}
/>
</Box>
)
}

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

export default ApprovedAccounts;
9 changes: 6 additions & 3 deletions src/components/Accounts/DeleteAccountModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ 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();
} catch (error) {
console.error(error);
Expand All @@ -30,7 +32,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); setDataShouldRevalidate(true);}} colorScheme='red'>Delete</Button>
</ModalFooter>
</ModalContent>
</Modal>
Expand All @@ -41,6 +43,7 @@ DeleteAccountModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
deleteItemId: PropTypes.string.isRequired,
setDataShouldRevalidate: PropTypes.func.isRequired
};

export default DeleteAccountModal;
Loading
Loading