Skip to content

Commit b947e84

Browse files
cherhchenCheryl Chen
and
Cheryl Chen
authored
Account page fixes (#96)
* 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]>
1 parent 2366a1a commit b947e84

File tree

3 files changed

+574
-406
lines changed

3 files changed

+574
-406
lines changed
+199-153
Original file line numberDiff line numberDiff line change
@@ -1,177 +1,223 @@
11
import { NPOBackend } from '../../utils/auth_utils.js';
22
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';
517
import DeleteAccountModal from './DeleteAccountModal.jsx';
618
import PropTypes from 'prop-types';
7-
import PaginationFooter from "../../components/Catalog/PaginationFooter/PaginationFooter";
19+
import PaginationFooter from '../../components/Catalog/PaginationFooter/PaginationFooter';
820
import { usePagination } from '@ajna/pagination';
21+
import { useAuthContext } from '../../common/AuthContext.jsx';
922

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);
2239

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]);
3856

39-
useEffect(() => {
40-
fetchTableData();
41-
}, [fetchTableData]);
57+
useEffect(() => {
58+
fetchTableData();
59+
}, [fetchTableData]);
4260

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]);
5169

52-
useEffect(() => {
53-
setCurrentPage(1);
54-
}, [searchQuery, setCurrentPage, pageSize]);
70+
useEffect(() => {
71+
setCurrentPage(1);
72+
}, [searchQuery, setCurrentPage, pageSize]);
5573

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]);
6079

61-
const handleDeleteClick = id => {
62-
setDeleteItemId(id);
63-
onDeleteOpen();
64-
}
80+
const handleDeleteClick = id => {
81+
setDeleteItemId(id);
82+
onDeleteOpen();
83+
};
6584

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);
7492
} else {
75-
setCheckedAccountIds([]);
93+
newIndividualChecked[i] = false;
7694
}
95+
}
96+
setCheckedAccountIds(allIds);
97+
} else {
98+
setCheckedAccountIds([]);
7799
}
100+
setIndividualChecked(newIndividualChecked);
101+
setIsSelectAll(e.target.checked);
102+
};
78103

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);
92116
}
117+
};
93118

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+
};
171217

172218
ApprovedAccounts.propTypes = {
173-
accountType: PropTypes.string.isRequired,
174-
searchQuery: PropTypes.string
219+
accountType: PropTypes.string.isRequired,
220+
searchQuery: PropTypes.string,
175221
};
176222

177223
export default ApprovedAccounts;

0 commit comments

Comments
 (0)