generated from ctc-uci/npo-frontend-vite-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Account Page Pagination Approve Decline Multiple (#76)
* Create a pull trequest for branch 69-account-page-pagination-approve-decline-multiple * added search to approved accounts * added pagination (still need to refresh table when data changes) and fixed sign up account type bug * added delete all users when all checkbox selected for approved accounts * adding functionality for pending all checkbox + just a search bar * finished everything but account table refresh * refresh pagination on delete, fixed multiselect bugs, fixed catalog pagination next to empty page bug * fixed account page styling * fixed indentation of some code, fixed spacing issues --------- Co-authored-by: Cheryl Chen <[email protected]> Co-authored-by: chloecheng8 <[email protected]> Co-authored-by: ThatMegamind <[email protected]> Co-authored-by: ThatMegamind <[email protected]>
- Loading branch information
1 parent
d515e50
commit 6afd3e4
Showing
6 changed files
with
381 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.