From d4cd9399a66ffe7801ffd5d5f0547f2a855d2525 Mon Sep 17 00:00:00 2001 From: ctc-devops <90984711+ctc-devops@users.noreply.github.com> Date: Fri, 12 Apr 2024 10:36:15 -0700 Subject: [PATCH 1/9] Create a pull trequest for branch 69-account-page-pagination-approve-decline-multiple From c8429b0261be3a66b5cf9c6b7bcb2857a20c6794 Mon Sep 17 00:00:00 2001 From: Cheryl Chen Date: Mon, 15 Apr 2024 23:31:14 -0700 Subject: [PATCH 2/9] added search to approved accounts --- src/components/Accounts/ApprovedAccounts.jsx | 17 +++++++++++++---- src/pages/Accounts/Accounts.jsx | 19 ++++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/components/Accounts/ApprovedAccounts.jsx b/src/components/Accounts/ApprovedAccounts.jsx index 927c1b4..f560169 100644 --- a/src/components/Accounts/ApprovedAccounts.jsx +++ b/src/components/Accounts/ApprovedAccounts.jsx @@ -5,18 +5,26 @@ import { CloseIcon } from '@chakra-ui/icons' import DeleteAccountModal from './DeleteAccountModal.jsx'; import PropTypes from 'prop-types'; -const ApprovedAccounts = ( {accountType} ) => { +const ApprovedAccounts = ( {accountType, searchQuery} ) => { const [approvedAccounts, setApprovedAccounts] = useState([]); const { isOpen: isDeleteOpen, onOpen: onDeleteOpen, onClose: onDeleteClose } = useDisclosure(); const [deleteItemId, setDeleteItemId] = useState(""); useEffect(() => { const renderTable = async () => { - const { data } = await NPOBackend.get('/users/approved-accounts'); - setApprovedAccounts(data); + if (searchQuery) { + const { data } = await NPOBackend.get(`/users/approved-accounts`, { + params: {keyword: searchQuery} + }); + setApprovedAccounts(data); + } + else { + const { data } = await NPOBackend.get('/users/approved-accounts'); + setApprovedAccounts(data); + } }; renderTable(); - }, [approvedAccounts]) + }, [searchQuery]) const handleDeleteClick = id => { setDeleteItemId(id); @@ -62,6 +70,7 @@ const ApprovedAccounts = ( {accountType} ) => { ApprovedAccounts.propTypes = { accountType: PropTypes.string.isRequired, + searchQuery: PropTypes.string }; export default ApprovedAccounts; \ No newline at end of file diff --git a/src/pages/Accounts/Accounts.jsx b/src/pages/Accounts/Accounts.jsx index 6b65ef8..61ac383 100644 --- a/src/pages/Accounts/Accounts.jsx +++ b/src/pages/Accounts/Accounts.jsx @@ -1,8 +1,11 @@ import PendingAccounts from "../../components/Accounts/PendingAccounts"; import ApprovedAccounts from "../../components/Accounts/ApprovedAccounts"; -import { Box, Heading, Tabs, TabList, TabPanels, Tab, TabPanel} from '@chakra-ui/react' +import { Box, Heading, Tabs, TabList, TabPanels, Tab, TabPanel, Input, InputGroup, InputLeftElement, HStack } from '@chakra-ui/react' +import { SearchIcon } from '@chakra-ui/icons'; +import { useState } from 'react'; const Accounts = () => { + const [keyword, setKeyword] = useState(""); return ( @@ -15,8 +18,18 @@ const Accounts = () => { Pending Accounts - Accounts - + + Accounts + + + + + + setKeyword(e.target.value)}/> + + + + Pending Accounts From 5d33f8efc1967311d8c7833e5dec079b514ee9fc Mon Sep 17 00:00:00 2001 From: Cheryl Chen Date: Tue, 16 Apr 2024 23:41:01 -0700 Subject: [PATCH 3/9] added pagination (still need to refresh table when data changes) and fixed sign up account type bug --- src/components/Accounts/ApprovedAccounts.jsx | 54 ++++++++++++-------- src/components/Authentication/SignUp.jsx | 8 +-- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/components/Accounts/ApprovedAccounts.jsx b/src/components/Accounts/ApprovedAccounts.jsx index f560169..8ab0da1 100644 --- a/src/components/Accounts/ApprovedAccounts.jsx +++ b/src/components/Accounts/ApprovedAccounts.jsx @@ -4,27 +4,37 @@ import { Box, Table, Thead, Tbody, Tr, Th, Td, TableContainer, Button, Checkbox, 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, 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), + }); useEffect(() => { const renderTable = async () => { - if (searchQuery) { + try { const { data } = await NPOBackend.get(`/users/approved-accounts`, { - params: {keyword: searchQuery} + params: { + keyword: (searchQuery && searchQuery.length) && searchQuery, + page: currentPage, + limit: pageSize, + accountType: accountType} }); - setApprovedAccounts(data); - } - else { - const { data } = await NPOBackend.get('/users/approved-accounts'); - setApprovedAccounts(data); + setApprovedAccounts(data.accounts); + setTotalRowCount(Number(data.count[0].count)); + } catch (error) { + console.error('Error fetching data:', error); } }; renderTable(); - }, [searchQuery]) + }, [searchQuery, totalRowCount, currentPage, pageSize, accountType]) const handleDeleteClick = id => { setDeleteItemId(id); @@ -46,24 +56,28 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { { approvedAccounts.map((account, i) => ( - accountType === account.type ? ( - - - {account.firstName} {account.lastName} - {account.email} - - - - - ) : ( - <> - ) + + + {account.firstName} {account.lastName} + {account.email} + + + + )) } + ) } diff --git a/src/components/Authentication/SignUp.jsx b/src/components/Authentication/SignUp.jsx index 5d68d11..7cc56a4 100644 --- a/src/components/Authentication/SignUp.jsx +++ b/src/components/Authentication/SignUp.jsx @@ -6,7 +6,7 @@ import emailtemplate from '../EmailTemplates/emailtemplate'; import { Box, Heading, Text, FormControl, Button, Center, Link, Input, Alert, AlertDescription } from '@chakra-ui/react'; import AUTH_ROLES from '../../utils/auth_config'; -const { USER_ROLE } = AUTH_ROLES.AUTH_ROLES; +const { ADMIN_ROLE, USER_ROLE } = AUTH_ROLES.AUTH_ROLES; const SignUp = () => { const [firstName, setFirstName] = useState(); @@ -45,7 +45,7 @@ const SignUp = () => { } // register email and password - await registerWithEmailAndPassword(email, password, USER_ROLE, navigate, '/awaitConfirmation', firstName, lastName); + await registerWithEmailAndPassword(email, password, userType, navigate, '/awaitConfirmation', firstName, lastName); // send email to Debbie const subject = "placeholder"; @@ -86,7 +86,7 @@ const SignUp = () => { }} > - + @@ -43,6 +43,7 @@ DeleteAccountModal.propTypes = { isOpen: PropTypes.bool.isRequired, onClose: PropTypes.func.isRequired, deleteItemId: PropTypes.string.isRequired, + setDataShouldRevalidate: PropTypes.func.isRequired }; export default DeleteAccountModal; diff --git a/src/components/Accounts/PendingAccounts.jsx b/src/components/Accounts/PendingAccounts.jsx index c3944ee..20acdb4 100644 --- a/src/components/Accounts/PendingAccounts.jsx +++ b/src/components/Accounts/PendingAccounts.jsx @@ -1,31 +1,41 @@ import { NPOBackend } from '../../utils/auth_utils.js'; import { useEffect, useState } from 'react'; -import { Table, Thead, Tbody, Tr, Th, Td, TableContainer, Button, HStack } from '@chakra-ui/react' +import { Table, Thead, Tbody, Tr, Th, Td, TableContainer, Button } from '@chakra-ui/react' import { Checkbox } from '@chakra-ui/react' import PropTypes from 'prop-types'; -const PendingAccounts = ( {accountType, searchQuery} ) => { +const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { const [pendingAccounts, setPendingAccounts] = useState([]); const [individualChecked, setIndividualChecked] = useState(new Array(pendingAccounts.length).fill(false)); const [checkedAccountIds, setCheckedAccountIds] = useState([]); + const [accountStatus, setAccountStatus] = useState({}); + useEffect(() => { const renderTable = async () => { - const { data } = await NPOBackend.get('/users/pending-accounts', { - params : { - keyword: searchQuery - } - }); + const { data } = await NPOBackend.get('/users/pending-accounts', {params: {accountType: accountType}}); setPendingAccounts(data); + console.log("ELNGLKNKJ: " + data); + setHasPendingAccounts(data.length !== 0); }; renderTable(); + }, []) + + useEffect(() => { + const newAccountStatus = {} + for (let i = 0; i < pendingAccounts.length; i++) { + newAccountStatus[pendingAccounts[i]["id"]] = "pending"; + } + setAccountStatus(newAccountStatus); }, [pendingAccounts]) const handleApproveUser = async (ids) => { try { for (let i = 0; i < ids.length; i++) { + console.log("approved: " + ids[i]); await NPOBackend.put(`/users/approve/${ids[i]}`); } + setIndividualChecked(new Array(pendingAccounts.length).fill(false)); } catch (error) { console.log(error); } @@ -34,8 +44,10 @@ const PendingAccounts = ( {accountType, searchQuery} ) => { const handleDeleteUser = async (ids) => { try { for (let i = 0; i < ids.length; i++) { + console.log("deleted: " + ids[i]); await NPOBackend.delete(`/users/${ids[i]}`); } + setIndividualChecked(new Array(pendingAccounts.length).fill(false)); } catch (error) { console.log(error); } @@ -66,8 +78,28 @@ const PendingAccounts = ( {accountType, searchQuery} ) => { console.log(newCheckedAccountIds); } + useEffect(() => console.log("accountStatus: " + JSON.stringify(accountStatus)), [accountStatus]); + + const acceptAllClick = () => { + handleApproveUser(checkedAccountIds); + const newAccountStatus = {... accountStatus}; + for (let i = 0; i < checkedAccountIds.length; i++) { + newAccountStatus[checkedAccountIds[i]] = "approved"; + } + setAccountStatus(newAccountStatus); + } + + const deleteAllClick = () => { + handleDeleteUser(checkedAccountIds); + const newAccountStatus = {... accountStatus}; + for (let i = 0; i < checkedAccountIds.length; i++) { + newAccountStatus[checkedAccountIds[i]] = "declined"; + } + setAccountStatus(newAccountStatus); + } + return ( - + @@ -76,34 +108,45 @@ const PendingAccounts = ( {accountType, searchQuery} ) => { - - - - - + + { pendingAccounts.map((account, i) => ( - accountType === account.type ? ( - - - - + + + + + + { + accountStatus[account.id] === "pending" ? ( - - ) : ( - <> - ) + ) : accountStatus[account.id] === "approved" ? ( + + ) : ( + + ) + } + ) ) } @@ -115,7 +158,7 @@ const PendingAccounts = ( {accountType, searchQuery} ) => { PendingAccounts.propTypes = { accountType: PropTypes.string.isRequired, - searchQuery: PropTypes.string + setHasPendingAccounts: PropTypes.func.isRequired }; export default PendingAccounts; \ No newline at end of file diff --git a/src/pages/Accounts/Accounts.jsx b/src/pages/Accounts/Accounts.jsx index 411a18b..7eec7ed 100644 --- a/src/pages/Accounts/Accounts.jsx +++ b/src/pages/Accounts/Accounts.jsx @@ -1,14 +1,17 @@ import PendingAccounts from "../../components/Accounts/PendingAccounts"; import ApprovedAccounts from "../../components/Accounts/ApprovedAccounts"; -import { Box, Heading, Tabs, TabList, TabPanels, Tab, TabPanel, Input, InputGroup, InputLeftElement, HStack } from '@chakra-ui/react' +import { Box, Heading, Tabs, TabList, TabPanels, Tab, TabPanel, Input, InputGroup, InputLeftElement, HStack, Center } from '@chakra-ui/react' import { SearchIcon } from '@chakra-ui/icons'; import { useState } from 'react'; const Accounts = () => { - const [pendingKeyword, setPendingKeyword] = useState(""); const [approvedKeyword, setApprovedKeyword] = useState(""); + const [hasAdminPendingAccounts, setHasAdminPendingAccounts] = useState(true); + const [hasStudentPendingAccounts, setHasStudentPendingAccounts] = useState(true); + return ( - + +
Admins @@ -17,20 +20,36 @@ const Accounts = () => { - - Pending Accounts + { hasAdminPendingAccounts ? ( + <> + Pending Accounts + + + ) : <> + } + + Accounts - setPendingKeyword(e.target.value)}/> + setApprovedKeyword(e.target.value)}/> - - - Accounts + + + + { hasStudentPendingAccounts ? ( + <> + Pending Accounts + + + ): <> + } + + Accounts @@ -40,16 +59,11 @@ const Accounts = () => { - - - - Pending Accounts - - Accounts - + +
); } From 34e3c4aa8bdb3a7069aa7446d56e738c799da43f Mon Sep 17 00:00:00 2001 From: Cheryl Chen Date: Mon, 22 Apr 2024 14:03:02 -0700 Subject: [PATCH 7/9] refresh pagination on delete, fixed multiselect bugs, fixed catalog pagination next to empty page bug --- src/components/Accounts/ApprovedAccounts.jsx | 65 +++++-------- .../Accounts/DeleteAccountModal.jsx | 5 +- src/components/Accounts/PendingAccounts.jsx | 95 +++++++++---------- src/pages/Accounts/Accounts.jsx | 21 ++-- src/pages/Catalog/Catalog.jsx | 4 +- 5 files changed, 85 insertions(+), 105 deletions(-) diff --git a/src/components/Accounts/ApprovedAccounts.jsx b/src/components/Accounts/ApprovedAccounts.jsx index e395241..f30132e 100644 --- a/src/components/Accounts/ApprovedAccounts.jsx +++ b/src/components/Accounts/ApprovedAccounts.jsx @@ -10,34 +10,15 @@ import { usePagination } from '@ajna/pagination'; 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({ + const { currentPage, setCurrentPage, pagesCount, offset, pageSize, setPageSize} = usePagination({ initialState: { currentPage: 1, pageSize: 10 }, - pagesCount: Math.ceil(totalRowCount / 10), + total: totalRowCount, }); 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 [dataShouldRevalidate, setDataShouldRevalidate] = useState(false); const fetchTableData = useCallback(async () => { try { @@ -53,7 +34,7 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { } catch (error) { console.error('Error fetching data:', error); } - }, [searchQuery, totalRowCount, currentPage, pageSize, accountType]); + }, [searchQuery, currentPage, pageSize, accountType]); useEffect(() => { fetchTableData(); @@ -61,15 +42,21 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { useEffect(() => { if (dataShouldRevalidate) { - console.log(dataShouldRevalidate); fetchTableData(); setDataShouldRevalidate(false); + setIndividualChecked(new Array(totalRowCount).fill(false)); + setCheckedAccountIds([]); } - }, [dataShouldRevalidate, fetchTableData]); + }, [dataShouldRevalidate, fetchTableData, totalRowCount]); useEffect(() => { setCurrentPage(1); - }, [searchQuery, setCurrentPage]); + }, [searchQuery, setCurrentPage, pageSize]); + + useEffect(() => { + setIndividualChecked(new Array(totalRowCount).fill(false)); + setCheckedAccountIds([]); + }, [searchQuery, currentPage, totalRowCount]); const handleDeleteClick = id => { setDeleteItemId(id); @@ -77,6 +64,7 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { } 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++) { @@ -88,7 +76,10 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { } } - const updateIndividualCheckedAccountIds = (e, id) => { + 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); @@ -98,7 +89,6 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { newCheckedAccountIds.splice(index, 1); setCheckedAccountIds(newCheckedAccountIds); } - console.log(newCheckedAccountIds); } return ( @@ -107,13 +97,11 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => {
Name EmailActionAction + + +
{const newIndividualChecked = [...individualChecked]; - newIndividualChecked[i] = e.target.checked; - setIndividualChecked(newIndividualChecked); - updateIndividualCheckedAccountIds(e, account.id)}}> - - {account.firstName} {account.lastName}{account.email}
{const newIndividualChecked = [...individualChecked]; + newIndividualChecked[i] = e.target.checked; + setIndividualChecked(newIndividualChecked); + updateIndividualCheckedAccountIds(e, account.id);}}> + + {account.firstName} {account.lastName}{account.email} - - + +
ApprovedDeclined
- - - + + + - @@ -154,7 +139,7 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { setPageSize={setPageSize} currentPage={currentPage} setCurrentPage={setCurrentPage} - rangeString={`${offset + 1} - ${offset + Number(pageSize)}`} + rangeString={`${offset + 1} - ${offset + approvedAccounts.length}`} /> Are you sure? You cannot undo this action afterwards. - + @@ -42,7 +43,7 @@ const DeleteAccountModal = ({ isOpen, onClose, deleteItemId, setDataShouldRevali DeleteAccountModal.propTypes = { isOpen: PropTypes.bool.isRequired, onClose: PropTypes.func.isRequired, - deleteItemId: PropTypes.string.isRequired, + deleteItemId: PropTypes.array.isRequired, setDataShouldRevalidate: PropTypes.func.isRequired }; diff --git a/src/components/Accounts/PendingAccounts.jsx b/src/components/Accounts/PendingAccounts.jsx index 20acdb4..8c7390c 100644 --- a/src/components/Accounts/PendingAccounts.jsx +++ b/src/components/Accounts/PendingAccounts.jsx @@ -15,11 +15,10 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { const renderTable = async () => { const { data } = await NPOBackend.get('/users/pending-accounts', {params: {accountType: accountType}}); setPendingAccounts(data); - console.log("ELNGLKNKJ: " + data); setHasPendingAccounts(data.length !== 0); }; renderTable(); - }, []) + }, [accountType, setHasPendingAccounts]) useEffect(() => { const newAccountStatus = {} @@ -29,11 +28,21 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { setAccountStatus(newAccountStatus); }, [pendingAccounts]) - const handleApproveUser = async (ids) => { + const changeStatus = ((accountid, status) => { + let newAccountStatus = {...accountStatus}; + newAccountStatus[accountid] = status; + setAccountStatus(newAccountStatus); + }); + + const handleApproveDeclineUser = async (ids, option) => { try { for (let i = 0; i < ids.length; i++) { - console.log("approved: " + ids[i]); - await NPOBackend.put(`/users/approve/${ids[i]}`); + if (option === "approve-option") { + await NPOBackend.put(`/users/approve/${ids[i]}`); + } + else if (option === "decline-option") { + await NPOBackend.delete(`/users/${ids[i]}`); + } } setIndividualChecked(new Array(pendingAccounts.length).fill(false)); } catch (error) { @@ -41,23 +50,26 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { } } - const handleDeleteUser = async (ids) => { - try { - for (let i = 0; i < ids.length; i++) { - console.log("deleted: " + ids[i]); - await NPOBackend.delete(`/users/${ids[i]}`); + const updateAllIndividualChecked = (e) => { + let newIndividualChecked = []; + for (let i = 0; i < pendingAccounts.length; i++) { + if (accountStatus[pendingAccounts[i].id] === "pending") { + newIndividualChecked.push(e.target.checked); + } + else { + newIndividualChecked.push(false); } - setIndividualChecked(new Array(pendingAccounts.length).fill(false)); - } catch (error) { - console.log(error); } + setIndividualChecked(newIndividualChecked); } const updateAllCheckedAccountIds = (e) => { if (e.target.checked) { let allIds = []; for (let i = 0; i < pendingAccounts.length; i++) { - allIds.push(pendingAccounts[i].id) + if (accountStatus[pendingAccounts[i].id] === "pending") { + allIds.push(pendingAccounts[i].id); + } } setCheckedAccountIds(allIds); } else { @@ -65,7 +77,10 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { } } - const updateIndividualCheckedAccountIds = (e, id) => { + 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); @@ -75,27 +90,16 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { newCheckedAccountIds.splice(index, 1); setCheckedAccountIds(newCheckedAccountIds); } - console.log(newCheckedAccountIds); - } - - useEffect(() => console.log("accountStatus: " + JSON.stringify(accountStatus)), [accountStatus]); - - const acceptAllClick = () => { - handleApproveUser(checkedAccountIds); - const newAccountStatus = {... accountStatus}; - for (let i = 0; i < checkedAccountIds.length; i++) { - newAccountStatus[checkedAccountIds[i]] = "approved"; - } - setAccountStatus(newAccountStatus); } - const deleteAllClick = () => { - handleDeleteUser(checkedAccountIds); + const acceptDeclineAllClick = (option) => { + handleApproveDeclineUser(checkedAccountIds, option); const newAccountStatus = {... accountStatus}; for (let i = 0; i < checkedAccountIds.length; i++) { - newAccountStatus[checkedAccountIds[i]] = "declined"; + newAccountStatus[checkedAccountIds[i]] = option === "approve-option" ? "approved" : "declined"; } setAccountStatus(newAccountStatus); + setCheckedAccountIds([]); } return ( @@ -103,15 +107,13 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => {
{setIndividualChecked(new Array(approvedAccounts.length).fill(e.target.checked)); - updateAllCheckedAccountIds(e)}}/> - NameEmail { updateAllCheckedAccountIds(e) }}/>NameEmail Deactivate + {const newIndividualChecked = [...individualChecked]; - newIndividualChecked[i] = e.target.checked; - setIndividualChecked(newIndividualChecked); - updateIndividualCheckedAccountIds(e, account.id)}}> + onChange={(e) => { updateIndividualCheckedAccountIds(e, account.id, i)}}> {account.firstName} {account.lastName}
- - - - - + + + + @@ -119,10 +121,7 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { { pendingAccounts.map((account, i) => ( - @@ -131,14 +130,8 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { { accountStatus[account.id] === "pending" ? ( ) : accountStatus[account.id] === "approved" ? ( diff --git a/src/pages/Accounts/Accounts.jsx b/src/pages/Accounts/Accounts.jsx index 7eec7ed..8e907b0 100644 --- a/src/pages/Accounts/Accounts.jsx +++ b/src/pages/Accounts/Accounts.jsx @@ -5,12 +5,13 @@ import { SearchIcon } from '@chakra-ui/icons'; import { useState } from 'react'; const Accounts = () => { - const [approvedKeyword, setApprovedKeyword] = useState(""); + const [approvedAdminKeyword, setApprovedAdminKeyword] = useState(""); + const [approvedStudentKeyword, setApprovedStudentKeyword] = useState(""); const [hasAdminPendingAccounts, setHasAdminPendingAccounts] = useState(true); const [hasStudentPendingAccounts, setHasStudentPendingAccounts] = useState(true); return ( - +
@@ -23,43 +24,43 @@ const Accounts = () => { { hasAdminPendingAccounts ? ( <> Pending Accounts - + ) : <> } - + Accounts - setApprovedKeyword(e.target.value)}/> + setApprovedAdminKeyword(e.target.value)}/> - + { hasStudentPendingAccounts ? ( <> Pending Accounts - + ): <> } - + Accounts - setApprovedKeyword(e.target.value)}/> + setApprovedStudentKeyword(e.target.value)}/> - + diff --git a/src/pages/Catalog/Catalog.jsx b/src/pages/Catalog/Catalog.jsx index 3a4517b..859155c 100644 --- a/src/pages/Catalog/Catalog.jsx +++ b/src/pages/Catalog/Catalog.jsx @@ -54,7 +54,7 @@ export default function Catalog({ onDayPlanner, addExistingEventFunc, setCurrEve const { currentPage, setCurrentPage, pagesCount, offset, pageSize, setPageSize } = usePagination({ initialState: { currentPage: 1, pageSize: 10 }, - pagesCount: Math.ceil(totalRowCount / 10), + total: totalRowCount }); // const handleEditForm = data => { @@ -116,7 +116,7 @@ export default function Catalog({ onDayPlanner, addExistingEventFunc, setCurrEve // Reset pagination on filter change useEffect(() => { setCurrentPage(1); - }, [filterValues, setCurrentPage]); + }, [filterValues, setCurrentPage, pageSize, searchTerm]); return ( From c1d5d3b0d8ae02704ad88669095bb6621e411e06 Mon Sep 17 00:00:00 2001 From: Cheryl Chen Date: Sat, 27 Apr 2024 22:58:31 -0700 Subject: [PATCH 8/9] fixed account page styling --- src/components/Accounts/ApprovedAccounts.jsx | 49 ++++++++++----- src/components/Accounts/PendingAccounts.jsx | 64 ++++++++++++++++---- src/pages/Accounts/Accounts.jsx | 50 +++++++++------ 3 files changed, 118 insertions(+), 45 deletions(-) diff --git a/src/components/Accounts/ApprovedAccounts.jsx b/src/components/Accounts/ApprovedAccounts.jsx index f30132e..0218369 100644 --- a/src/components/Accounts/ApprovedAccounts.jsx +++ b/src/components/Accounts/ApprovedAccounts.jsx @@ -97,19 +97,24 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => {
{setIndividualChecked(new Array(pendingAccounts.length).fill(e.target.checked)); - updateAllCheckedAccountIds(e)}}/> - NameEmailAction - - + {updateAllIndividualChecked(e); updateAllCheckedAccountIds(e);}}/>NameEmailAction + +
{const newIndividualChecked = [...individualChecked]; - newIndividualChecked[i] = e.target.checked; - setIndividualChecked(newIndividualChecked); - updateIndividualCheckedAccountIds(e, account.id);}}> + {updateIndividualCheckedAccountIds(e, account.id, i);}}> {account.firstName} {account.lastName} - - + + Approved
- - - - - + + + + + {checkedAccountIds.length > 0 && + + } @@ -124,9 +129,21 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { - - + } + )) diff --git a/src/components/Accounts/PendingAccounts.jsx b/src/components/Accounts/PendingAccounts.jsx index 8c7390c..bab0618 100644 --- a/src/components/Accounts/PendingAccounts.jsx +++ b/src/components/Accounts/PendingAccounts.jsx @@ -107,14 +107,34 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => {
{ updateAllCheckedAccountIds(e) }}/>NameEmailDeactivate - - { updateAllCheckedAccountIds(e) }}/>NameEmailDeactivate + +
{account.firstName} {account.lastName} {account.email} - + {checkedAccountIds.length > 0 && + +
- - - - - + + + + + {checkedAccountIds.length > 0 && + + } @@ -126,12 +146,32 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { - + {checkedAccountIds.length > 0 && + + } { accountStatus[account.id] === "pending" ? ( - ) : accountStatus[account.id] === "approved" ? ( diff --git a/src/pages/Accounts/Accounts.jsx b/src/pages/Accounts/Accounts.jsx index 8e907b0..fd87081 100644 --- a/src/pages/Accounts/Accounts.jsx +++ b/src/pages/Accounts/Accounts.jsx @@ -14,7 +14,7 @@ const Accounts = () => {
- + Admins Students @@ -23,19 +23,28 @@ const Accounts = () => { { hasAdminPendingAccounts ? ( <> - Pending Accounts - + + Pending + + ) : <> } - - Accounts + + Accounts - - - + + + - setApprovedAdminKeyword(e.target.value)}/> + setApprovedAdminKeyword(e.target.value)} + /> @@ -44,19 +53,26 @@ const Accounts = () => { { hasStudentPendingAccounts ? ( <> - Pending Accounts - + Pending + ): <> } - - Accounts + + Accounts - - - + + + - setApprovedStudentKeyword(e.target.value)}/> + setApprovedStudentKeyword(e.target.value)} + /> From b1471e38f149e60d09a7fb4dc746a963d27f4bf6 Mon Sep 17 00:00:00 2001 From: ThatMegamind Date: Sun, 28 Apr 2024 11:57:09 -0700 Subject: [PATCH 9/9] fixed indentation of some code, fixed spacing issues --- src/components/Accounts/ApprovedAccounts.jsx | 150 +++++++++---------- src/components/Accounts/PendingAccounts.jsx | 22 +-- src/pages/Accounts/Accounts.jsx | 12 +- 3 files changed, 92 insertions(+), 92 deletions(-) diff --git a/src/components/Accounts/ApprovedAccounts.jsx b/src/components/Accounts/ApprovedAccounts.jsx index 0218369..d2de376 100644 --- a/src/components/Accounts/ApprovedAccounts.jsx +++ b/src/components/Accounts/ApprovedAccounts.jsx @@ -18,15 +18,15 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { }); const [individualChecked, setIndividualChecked] = useState(new Array(approvedAccounts.length).fill(false)); const [checkedAccountIds, setCheckedAccountIds] = useState([]); - const [dataShouldRevalidate, setDataShouldRevalidate] = useState(false); + 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, + keyword: (searchQuery && searchQuery.length) && searchQuery, + page: currentPage, + limit: pageSize, accountType: accountType} }); setApprovedAccounts(data.accounts); @@ -93,78 +93,78 @@ const ApprovedAccounts = ( {accountType, searchQuery} ) => { return ( - -
{updateAllIndividualChecked(e); updateAllCheckedAccountIds(e);}}/>NameEmailAction - - - {updateAllIndividualChecked(e); updateAllCheckedAccountIds(e);}}/>NameEmailAction + + +
{account.firstName} {account.lastName} {account.email} - - + + + Approved
- - - - - - - {checkedAccountIds.length > 0 && - - } - - - - { - approvedAccounts.map((account, i) => ( - - - - - {checkedAccountIds.length > 0 && - - } - - - )) + +
{ updateAllCheckedAccountIds(e) }}/>NameEmailDeactivate - -
- { updateIndividualCheckedAccountIds(e, account.id, i)}}> - - {account.firstName} {account.lastName}{account.email} - -
+ + + + + + + {checkedAccountIds.length > 0 && + } - -
{ updateAllCheckedAccountIds(e) }}/>NameEmailDeactivate + +
- -
- + + + { + approvedAccounts.map((account, i) => ( + + + { updateIndividualCheckedAccountIds(e, account.id, i)}}> + + + {account.firstName} {account.lastName} + {account.email} + {checkedAccountIds.length > 0 && + + } + + + + + )) + } + + + +
+ ) } @@ -174,4 +174,4 @@ ApprovedAccounts.propTypes = { searchQuery: PropTypes.string }; -export default ApprovedAccounts; \ No newline at end of file +export default ApprovedAccounts; diff --git a/src/components/Accounts/PendingAccounts.jsx b/src/components/Accounts/PendingAccounts.jsx index bab0618..52e71c8 100644 --- a/src/components/Accounts/PendingAccounts.jsx +++ b/src/components/Accounts/PendingAccounts.jsx @@ -111,9 +111,9 @@ const PendingAccounts = ( {accountType, setHasPendingAccounts} ) => { Name Email Action - {checkedAccountIds.length > 0 && + {checkedAccountIds.length > 0 && - - - ) : accountStatus[account.id] === "approved" ? ( - Approved + Approved ) : ( - Declined + Declined ) } @@ -194,4 +194,4 @@ PendingAccounts.propTypes = { setHasPendingAccounts: PropTypes.func.isRequired }; -export default PendingAccounts; \ No newline at end of file +export default PendingAccounts; diff --git a/src/pages/Accounts/Accounts.jsx b/src/pages/Accounts/Accounts.jsx index fd87081..8d14e15 100644 --- a/src/pages/Accounts/Accounts.jsx +++ b/src/pages/Accounts/Accounts.jsx @@ -37,7 +37,7 @@ const Accounts = () => { - { { hasStudentPendingAccounts ? ( - <> + Pending - + ): <> } @@ -65,8 +65,8 @@ const Accounts = () => { - { ); } -export default Accounts; \ No newline at end of file +export default Accounts;