|
1 | 1 | import { NPOBackend } from '../../utils/auth_utils.js';
|
2 | 2 | import { useEffect, useState, useCallback } from 'react';
|
3 |
| -import { Box, Table, Thead, Tbody, Tr, Th, Td, TableContainer, Button, Checkbox, useDisclosure } from '@chakra-ui/react' |
4 |
| -import { CloseIcon } from '@chakra-ui/icons' |
| 3 | +import { |
| 4 | + Box, |
| 5 | + Table, |
| 6 | + Thead, |
| 7 | + Tbody, |
| 8 | + Tr, |
| 9 | + Th, |
| 10 | + Td, |
| 11 | + TableContainer, |
| 12 | + Button, |
| 13 | + Checkbox, |
| 14 | + useDisclosure, |
| 15 | +} from '@chakra-ui/react'; |
| 16 | +import { CloseIcon } from '@chakra-ui/icons'; |
5 | 17 | import DeleteAccountModal from './DeleteAccountModal.jsx';
|
6 | 18 | import PropTypes from 'prop-types';
|
7 |
| -import PaginationFooter from "../../components/Catalog/PaginationFooter/PaginationFooter"; |
| 19 | +import PaginationFooter from '../../components/Catalog/PaginationFooter/PaginationFooter'; |
8 | 20 | import { usePagination } from '@ajna/pagination';
|
| 21 | +import { useAuthContext } from '../../common/AuthContext.jsx'; |
9 | 22 |
|
10 |
| -const ApprovedAccounts = ( {accountType, searchQuery} ) => { |
11 |
| - const [approvedAccounts, setApprovedAccounts] = useState([]); |
12 |
| - const { isOpen: isDeleteOpen, onOpen: onDeleteOpen, onClose: onDeleteClose } = useDisclosure(); |
13 |
| - const [deleteItemId, setDeleteItemId] = useState([]); |
14 |
| - const [totalRowCount, setTotalRowCount] = useState(0); |
15 |
| - const { currentPage, setCurrentPage, pagesCount, offset, pageSize, setPageSize} = usePagination({ |
16 |
| - initialState: { currentPage: 1, pageSize: 10 }, |
17 |
| - total: totalRowCount, |
18 |
| - }); |
19 |
| - const [individualChecked, setIndividualChecked] = useState(new Array(approvedAccounts.length).fill(false)); |
20 |
| - const [checkedAccountIds, setCheckedAccountIds] = useState([]); |
21 |
| - const [dataShouldRevalidate, setDataShouldRevalidate] = useState(false); |
| 23 | +const ApprovedAccounts = ({ accountType, searchQuery }) => { |
| 24 | + const [approvedAccounts, setApprovedAccounts] = useState([]); |
| 25 | + const { isOpen: isDeleteOpen, onOpen: onDeleteOpen, onClose: onDeleteClose } = useDisclosure(); |
| 26 | + const [deleteItemId, setDeleteItemId] = useState([]); |
| 27 | + const [totalRowCount, setTotalRowCount] = useState(0); |
| 28 | + const { currentPage, setCurrentPage, pagesCount, offset, pageSize, setPageSize } = usePagination({ |
| 29 | + initialState: { currentPage: 1, pageSize: 10 }, |
| 30 | + total: totalRowCount, |
| 31 | + }); |
| 32 | + const [individualChecked, setIndividualChecked] = useState( |
| 33 | + new Array(approvedAccounts.length).fill(false), |
| 34 | + ); |
| 35 | + const [checkedAccountIds, setCheckedAccountIds] = useState([]); |
| 36 | + const [dataShouldRevalidate, setDataShouldRevalidate] = useState(false); |
| 37 | + const { currentUser } = useAuthContext(); |
| 38 | + const [isSelectAll, setIsSelectAll] = useState(false); |
22 | 39 |
|
23 |
| - const fetchTableData = useCallback(async () => { |
24 |
| - try { |
25 |
| - const { data } = await NPOBackend.get(`/users/approved-accounts`, { |
26 |
| - params: { |
27 |
| - keyword: (searchQuery && searchQuery.length) && searchQuery, |
28 |
| - page: currentPage, |
29 |
| - limit: pageSize, |
30 |
| - accountType: accountType} |
31 |
| - }); |
32 |
| - setApprovedAccounts(data.accounts); |
33 |
| - setTotalRowCount(Number(data.count[0].count)); |
34 |
| - } catch (error) { |
35 |
| - console.error('Error fetching data:', error); |
36 |
| - } |
37 |
| - }, [searchQuery, currentPage, pageSize, accountType]); |
| 40 | + const fetchTableData = useCallback(async () => { |
| 41 | + try { |
| 42 | + const { data } = await NPOBackend.get(`/users/approved-accounts`, { |
| 43 | + params: { |
| 44 | + keyword: searchQuery && searchQuery.length && searchQuery, |
| 45 | + page: currentPage, |
| 46 | + limit: pageSize, |
| 47 | + accountType: accountType, |
| 48 | + }, |
| 49 | + }); |
| 50 | + setApprovedAccounts(data.accounts); |
| 51 | + setTotalRowCount(Number(data.count[0].count)); |
| 52 | + } catch (error) { |
| 53 | + console.error('Error fetching data:', error); |
| 54 | + } |
| 55 | + }, [searchQuery, currentPage, pageSize, accountType]); |
38 | 56 |
|
39 |
| - useEffect(() => { |
40 |
| - fetchTableData(); |
41 |
| - }, [fetchTableData]); |
| 57 | + useEffect(() => { |
| 58 | + fetchTableData(); |
| 59 | + }, [fetchTableData]); |
42 | 60 |
|
43 |
| - useEffect(() => { |
44 |
| - if (dataShouldRevalidate) { |
45 |
| - fetchTableData(); |
46 |
| - setDataShouldRevalidate(false); |
47 |
| - setIndividualChecked(new Array(totalRowCount).fill(false)); |
48 |
| - setCheckedAccountIds([]); |
49 |
| - } |
50 |
| - }, [dataShouldRevalidate, fetchTableData, totalRowCount]); |
| 61 | + useEffect(() => { |
| 62 | + if (dataShouldRevalidate) { |
| 63 | + fetchTableData(); |
| 64 | + setDataShouldRevalidate(false); |
| 65 | + setIndividualChecked(new Array(totalRowCount).fill(false)); |
| 66 | + setCheckedAccountIds([]); |
| 67 | + } |
| 68 | + }, [dataShouldRevalidate, fetchTableData, totalRowCount]); |
51 | 69 |
|
52 |
| - useEffect(() => { |
53 |
| - setCurrentPage(1); |
54 |
| - }, [searchQuery, setCurrentPage, pageSize]); |
| 70 | + useEffect(() => { |
| 71 | + setCurrentPage(1); |
| 72 | + }, [searchQuery, setCurrentPage, pageSize]); |
55 | 73 |
|
56 |
| - useEffect(() => { |
57 |
| - setIndividualChecked(new Array(totalRowCount).fill(false)); |
58 |
| - setCheckedAccountIds([]); |
59 |
| - }, [searchQuery, currentPage, totalRowCount]); |
| 74 | + useEffect(() => { |
| 75 | + setIndividualChecked(new Array(totalRowCount).fill(false)); |
| 76 | + setCheckedAccountIds([]); |
| 77 | + setIsSelectAll(false); |
| 78 | + }, [searchQuery, currentPage, totalRowCount]); |
60 | 79 |
|
61 |
| - const handleDeleteClick = id => { |
62 |
| - setDeleteItemId(id); |
63 |
| - onDeleteOpen(); |
64 |
| - } |
| 80 | + const handleDeleteClick = id => { |
| 81 | + setDeleteItemId(id); |
| 82 | + onDeleteOpen(); |
| 83 | + }; |
65 | 84 |
|
66 |
| - const updateAllCheckedAccountIds = (e) => { |
67 |
| - setIndividualChecked(new Array(approvedAccounts.length).fill(e.target.checked)); |
68 |
| - if (e.target.checked) { |
69 |
| - let allIds = []; |
70 |
| - for (let i = 0; i < approvedAccounts.length; i++) { |
71 |
| - allIds.push(approvedAccounts[i].id) |
72 |
| - } |
73 |
| - setCheckedAccountIds(allIds); |
| 85 | + const updateAllCheckedAccountIds = e => { |
| 86 | + let newIndividualChecked = new Array(approvedAccounts.length).fill(e.target.checked); |
| 87 | + if (e.target.checked) { |
| 88 | + let allIds = []; |
| 89 | + for (let i = 0; i < approvedAccounts.length; i++) { |
| 90 | + if (approvedAccounts[i].id != currentUser.id) { |
| 91 | + allIds.push(approvedAccounts[i].id); |
74 | 92 | } else {
|
75 |
| - setCheckedAccountIds([]); |
| 93 | + newIndividualChecked[i] = false; |
76 | 94 | }
|
| 95 | + } |
| 96 | + setCheckedAccountIds(allIds); |
| 97 | + } else { |
| 98 | + setCheckedAccountIds([]); |
77 | 99 | }
|
| 100 | + setIndividualChecked(newIndividualChecked); |
| 101 | + setIsSelectAll(e.target.checked); |
| 102 | + }; |
78 | 103 |
|
79 |
| - const updateIndividualCheckedAccountIds = (e, id, index) => { |
80 |
| - const newIndividualChecked = [...individualChecked]; |
81 |
| - newIndividualChecked[index] = e.target.checked; |
82 |
| - setIndividualChecked(newIndividualChecked); |
83 |
| - let newCheckedAccountIds = [... checkedAccountIds]; |
84 |
| - if (e.target.checked) { |
85 |
| - newCheckedAccountIds.push(id); |
86 |
| - setCheckedAccountIds(newCheckedAccountIds); |
87 |
| - } else { |
88 |
| - let index = newCheckedAccountIds.indexOf(id); |
89 |
| - newCheckedAccountIds.splice(index, 1); |
90 |
| - setCheckedAccountIds(newCheckedAccountIds); |
91 |
| - } |
| 104 | + const updateIndividualCheckedAccountIds = (e, id, index) => { |
| 105 | + const newIndividualChecked = [...individualChecked]; |
| 106 | + newIndividualChecked[index] = e.target.checked; |
| 107 | + setIndividualChecked(newIndividualChecked); |
| 108 | + let newCheckedAccountIds = [...checkedAccountIds]; |
| 109 | + if (e.target.checked) { |
| 110 | + newCheckedAccountIds.push(id); |
| 111 | + setCheckedAccountIds(newCheckedAccountIds); |
| 112 | + } else { |
| 113 | + let index = newCheckedAccountIds.indexOf(id); |
| 114 | + newCheckedAccountIds.splice(index, 1); |
| 115 | + setCheckedAccountIds(newCheckedAccountIds); |
92 | 116 | }
|
| 117 | + }; |
93 | 118 |
|
94 |
| - return ( |
95 |
| - <Box> |
96 |
| - <TableContainer border="1px solid #ededed" borderRadius="10px"> |
97 |
| - <Table variant='simple'> |
98 |
| - <Thead> |
99 |
| - <Tr> |
100 |
| - <Th w="5%" h="50px"><Checkbox onChange={(e) => { updateAllCheckedAccountIds(e) }}/></Th> |
101 |
| - <Th w="30%">Name</Th> |
102 |
| - <Th w="30%">Email</Th> |
103 |
| - <Th w="0" textAlign="right" >Deactivate</Th> |
104 |
| - {checkedAccountIds.length > 0 && |
105 |
| - <Th w="20%" textAlign="right"> |
106 |
| - <Button isDisabled={checkedAccountIds.length === 0} |
107 |
| - onClick={() => { handleDeleteClick(checkedAccountIds) }} |
108 |
| - size="xs" |
109 |
| - variant="outline" |
110 |
| - borderRadius="4px" |
111 |
| - borderWidth="1px" |
112 |
| - padding="0" |
113 |
| - borderColor={checkedAccountIds.length != 0 ? 'red' : 'gray.500'}> |
114 |
| - <CloseIcon w="10px" h="10px" color={checkedAccountIds.length != 0 ? 'red' : 'gray'}/> |
115 |
| - </Button> |
116 |
| - </Th> |
117 |
| - } |
118 |
| - </Tr> |
119 |
| - </Thead> |
120 |
| - <Tbody> |
121 |
| - { |
122 |
| - approvedAccounts.map((account, i) => ( |
123 |
| - <Tr key={i}> |
124 |
| - <Td> |
125 |
| - <Checkbox |
126 |
| - isChecked={individualChecked[i]} |
127 |
| - onChange={(e) => { updateIndividualCheckedAccountIds(e, account.id, i)}}> |
128 |
| - </Checkbox> |
129 |
| - </Td> |
130 |
| - <Td>{account.firstName} {account.lastName}</Td> |
131 |
| - <Td>{account.email}</Td> |
132 |
| - {checkedAccountIds.length > 0 && |
133 |
| - <Td></Td> |
134 |
| - } |
135 |
| - <Td textAlign="right"> |
136 |
| - <Button |
137 |
| - onClick={() => { handleDeleteClick([account.id]) }} |
138 |
| - size="xs" |
139 |
| - variant="outline" |
140 |
| - borderColor="gray.500" |
141 |
| - borderRadius="4px" |
142 |
| - borderWidth="1px" |
143 |
| - padding="0" |
144 |
| - > |
145 |
| - <CloseIcon w="10px" h="10px" color="gray.500"/> |
146 |
| - </Button> |
147 |
| - </Td> |
148 |
| - </Tr> |
149 |
| - )) |
150 |
| - } |
151 |
| - </Tbody> |
152 |
| - </Table> |
153 |
| - <PaginationFooter |
154 |
| - pagesCount={pagesCount} |
155 |
| - totalRowCount={totalRowCount} |
156 |
| - setPageSize={setPageSize} |
157 |
| - currentPage={currentPage} |
158 |
| - setCurrentPage={setCurrentPage} |
159 |
| - rangeString={`${offset + 1} - ${offset + approvedAccounts.length}`} |
160 |
| - /> |
161 |
| - </TableContainer> |
162 |
| - <DeleteAccountModal |
163 |
| - isOpen={isDeleteOpen} |
164 |
| - onClose={onDeleteClose} |
165 |
| - deleteItemId={deleteItemId} |
166 |
| - setDataShouldRevalidate={setDataShouldRevalidate} |
167 |
| - /> |
168 |
| - </Box> |
169 |
| - ) |
170 |
| -} |
| 119 | + return ( |
| 120 | + <Box> |
| 121 | + <TableContainer border="1px solid #ededed" borderRadius="10px"> |
| 122 | + <Table variant="simple"> |
| 123 | + <Thead> |
| 124 | + <Tr> |
| 125 | + <Th w="5%" h="50px"> |
| 126 | + <Checkbox |
| 127 | + isChecked={isSelectAll} |
| 128 | + onChange={e => { |
| 129 | + updateAllCheckedAccountIds(e); |
| 130 | + }} |
| 131 | + /> |
| 132 | + </Th> |
| 133 | + <Th w="30%">Name</Th> |
| 134 | + <Th w="30%">Email</Th> |
| 135 | + <Th w="0" textAlign="right"> |
| 136 | + Deactivate |
| 137 | + </Th> |
| 138 | + {checkedAccountIds.length > 0 && ( |
| 139 | + <Th w="20%" textAlign="right"> |
| 140 | + <Button |
| 141 | + isDisabled={checkedAccountIds.length === 0} |
| 142 | + onClick={() => { |
| 143 | + handleDeleteClick(checkedAccountIds); |
| 144 | + }} |
| 145 | + size="xs" |
| 146 | + variant="outline" |
| 147 | + borderRadius="4px" |
| 148 | + borderWidth="1px" |
| 149 | + padding="0" |
| 150 | + borderColor={checkedAccountIds.length != 0 ? 'red' : 'gray.500'} |
| 151 | + > |
| 152 | + <CloseIcon |
| 153 | + w="10px" |
| 154 | + h="10px" |
| 155 | + color={checkedAccountIds.length != 0 ? 'red' : 'gray'} |
| 156 | + /> |
| 157 | + </Button> |
| 158 | + </Th> |
| 159 | + )} |
| 160 | + </Tr> |
| 161 | + </Thead> |
| 162 | + <Tbody> |
| 163 | + {approvedAccounts.map((account, i) => ( |
| 164 | + <Tr key={i}> |
| 165 | + <Td> |
| 166 | + <Checkbox |
| 167 | + isDisabled={account.id === currentUser.id} |
| 168 | + isChecked={individualChecked[i]} |
| 169 | + onChange={e => { |
| 170 | + updateIndividualCheckedAccountIds(e, account.id, i); |
| 171 | + }} |
| 172 | + ></Checkbox> |
| 173 | + </Td> |
| 174 | + <Td color={account.id === currentUser.id ? 'gray' : 'black'}> |
| 175 | + {account.firstName} {account.lastName} |
| 176 | + </Td> |
| 177 | + <Td color={account.id === currentUser.id ? 'gray' : 'black'}>{account.email}</Td> |
| 178 | + {checkedAccountIds.length > 0 && <Td></Td>} |
| 179 | + <Td textAlign="right"> |
| 180 | + <Button |
| 181 | + onClick={() => { |
| 182 | + handleDeleteClick([account.id]); |
| 183 | + }} |
| 184 | + size="xs" |
| 185 | + variant="outline" |
| 186 | + borderColor="gray.500" |
| 187 | + borderRadius="4px" |
| 188 | + borderWidth="1px" |
| 189 | + padding="0" |
| 190 | + isDisabled={account.id === currentUser.id} |
| 191 | + > |
| 192 | + <CloseIcon w="10px" h="10px" color="gray.500" /> |
| 193 | + </Button> |
| 194 | + </Td> |
| 195 | + </Tr> |
| 196 | + ))} |
| 197 | + </Tbody> |
| 198 | + </Table> |
| 199 | + <PaginationFooter |
| 200 | + pagesCount={pagesCount} |
| 201 | + totalRowCount={totalRowCount} |
| 202 | + setPageSize={setPageSize} |
| 203 | + currentPage={currentPage} |
| 204 | + setCurrentPage={setCurrentPage} |
| 205 | + rangeString={`${offset + 1} - ${offset + approvedAccounts.length}`} |
| 206 | + /> |
| 207 | + </TableContainer> |
| 208 | + <DeleteAccountModal |
| 209 | + isOpen={isDeleteOpen} |
| 210 | + onClose={onDeleteClose} |
| 211 | + deleteItemId={deleteItemId} |
| 212 | + setDataShouldRevalidate={setDataShouldRevalidate} |
| 213 | + /> |
| 214 | + </Box> |
| 215 | + ); |
| 216 | +}; |
171 | 217 |
|
172 | 218 | ApprovedAccounts.propTypes = {
|
173 |
| - accountType: PropTypes.string.isRequired, |
174 |
| - searchQuery: PropTypes.string |
| 219 | + accountType: PropTypes.string.isRequired, |
| 220 | + searchQuery: PropTypes.string, |
175 | 221 | };
|
176 | 222 |
|
177 | 223 | export default ApprovedAccounts;
|
0 commit comments