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.
* disabled delete own account and more responsive styling * select all checkbox resets when page changes; fix bug clear ids after each accept/decline * changed format 2 spaces * undo works except for mixing individual/multiselect consecutive transactions * finally done :') --------- Co-authored-by: Cheryl Chen <[email protected]>
- Loading branch information
Showing
3 changed files
with
574 additions
and
406 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,177 +1,223 @@ | ||
import { NPOBackend } from '../../utils/auth_utils.js'; | ||
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 { | ||
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 PaginationFooter from '../../components/Catalog/PaginationFooter/PaginationFooter'; | ||
import { usePagination } from '@ajna/pagination'; | ||
import { useAuthContext } from '../../common/AuthContext.jsx'; | ||
|
||
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 }, | ||
total: totalRowCount, | ||
}); | ||
const [individualChecked, setIndividualChecked] = useState(new Array(approvedAccounts.length).fill(false)); | ||
const [checkedAccountIds, setCheckedAccountIds] = useState([]); | ||
const [dataShouldRevalidate, setDataShouldRevalidate] = useState(false); | ||
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 }, | ||
total: totalRowCount, | ||
}); | ||
const [individualChecked, setIndividualChecked] = useState( | ||
new Array(approvedAccounts.length).fill(false), | ||
); | ||
const [checkedAccountIds, setCheckedAccountIds] = useState([]); | ||
const [dataShouldRevalidate, setDataShouldRevalidate] = useState(false); | ||
const { currentUser } = useAuthContext(); | ||
const [isSelectAll, setIsSelectAll] = 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]); | ||
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(() => { | ||
fetchTableData(); | ||
}, [fetchTableData]); | ||
|
||
useEffect(() => { | ||
if (dataShouldRevalidate) { | ||
fetchTableData(); | ||
setDataShouldRevalidate(false); | ||
setIndividualChecked(new Array(totalRowCount).fill(false)); | ||
setCheckedAccountIds([]); | ||
} | ||
}, [dataShouldRevalidate, fetchTableData, totalRowCount]); | ||
useEffect(() => { | ||
if (dataShouldRevalidate) { | ||
fetchTableData(); | ||
setDataShouldRevalidate(false); | ||
setIndividualChecked(new Array(totalRowCount).fill(false)); | ||
setCheckedAccountIds([]); | ||
} | ||
}, [dataShouldRevalidate, fetchTableData, totalRowCount]); | ||
|
||
useEffect(() => { | ||
setCurrentPage(1); | ||
}, [searchQuery, setCurrentPage, pageSize]); | ||
useEffect(() => { | ||
setCurrentPage(1); | ||
}, [searchQuery, setCurrentPage, pageSize]); | ||
|
||
useEffect(() => { | ||
setIndividualChecked(new Array(totalRowCount).fill(false)); | ||
setCheckedAccountIds([]); | ||
}, [searchQuery, currentPage, totalRowCount]); | ||
useEffect(() => { | ||
setIndividualChecked(new Array(totalRowCount).fill(false)); | ||
setCheckedAccountIds([]); | ||
setIsSelectAll(false); | ||
}, [searchQuery, currentPage, totalRowCount]); | ||
|
||
const handleDeleteClick = id => { | ||
setDeleteItemId(id); | ||
onDeleteOpen(); | ||
} | ||
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); | ||
const updateAllCheckedAccountIds = e => { | ||
let newIndividualChecked = new Array(approvedAccounts.length).fill(e.target.checked); | ||
if (e.target.checked) { | ||
let allIds = []; | ||
for (let i = 0; i < approvedAccounts.length; i++) { | ||
if (approvedAccounts[i].id != currentUser.id) { | ||
allIds.push(approvedAccounts[i].id); | ||
} else { | ||
setCheckedAccountIds([]); | ||
newIndividualChecked[i] = false; | ||
} | ||
} | ||
setCheckedAccountIds(allIds); | ||
} else { | ||
setCheckedAccountIds([]); | ||
} | ||
setIndividualChecked(newIndividualChecked); | ||
setIsSelectAll(e.target.checked); | ||
}; | ||
|
||
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); | ||
} | ||
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 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> | ||
} | ||
<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> | ||
) | ||
} | ||
return ( | ||
<Box> | ||
<TableContainer border="1px solid #ededed" borderRadius="10px"> | ||
<Table variant="simple"> | ||
<Thead> | ||
<Tr> | ||
<Th w="5%" h="50px"> | ||
<Checkbox | ||
isChecked={isSelectAll} | ||
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 | ||
isDisabled={account.id === currentUser.id} | ||
isChecked={individualChecked[i]} | ||
onChange={e => { | ||
updateIndividualCheckedAccountIds(e, account.id, i); | ||
}} | ||
></Checkbox> | ||
</Td> | ||
<Td color={account.id === currentUser.id ? 'gray' : 'black'}> | ||
{account.firstName} {account.lastName} | ||
</Td> | ||
<Td color={account.id === currentUser.id ? 'gray' : 'black'}>{account.email}</Td> | ||
{checkedAccountIds.length > 0 && <Td></Td>} | ||
<Td textAlign="right"> | ||
<Button | ||
onClick={() => { | ||
handleDeleteClick([account.id]); | ||
}} | ||
size="xs" | ||
variant="outline" | ||
borderColor="gray.500" | ||
borderRadius="4px" | ||
borderWidth="1px" | ||
padding="0" | ||
isDisabled={account.id === currentUser.id} | ||
> | ||
<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 | ||
accountType: PropTypes.string.isRequired, | ||
searchQuery: PropTypes.string, | ||
}; | ||
|
||
export default ApprovedAccounts; |
Oops, something went wrong.