Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pagination for catalog #30

Merged
merged 3 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"prepare": "husky install"
},
"dependencies": {
"@ajna/pagination": "^1.4.19",
"@chakra-ui/icons": "^2.1.1",
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.11.1",
Expand Down
120 changes: 120 additions & 0 deletions src/components/PaginationFooter/PaginationFooter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { Select, Flex, Box, HStack, Text } from '@chakra-ui/react';
import {
Pagination,
usePagination,
PaginationNext,
PaginationPrevious,
PaginationContainer,
} from '@ajna/pagination';
import { useState, useEffect } from 'react';
import { PropTypes } from 'prop-types';
import { NPOBackend } from '../../utils/auth_utils';

const PaginationFooter = ({ setData, table, searchTerm, selectedFilters }) => {
const [rowsPerPage, setRowsPerPage] = useState(10);
const [rowRangeString, setRowRangeString] = useState('');
const [dataCount, setDataCount] = useState(0);

const { currentPage, setCurrentPage, pagesCount } = usePagination({
pagesCount: Math.ceil(dataCount / rowsPerPage),
initialState: { currentPage: 1 },
});

// when the number of rows or the next page is clicked, get the desired data from the backend
useEffect(() => {
const refreshData = async () => {
const params = {
title: searchTerm,
...selectedFilters,
limit: rowsPerPage,
page: currentPage
};
const { data } = await NPOBackend.get('/catalog', {
params: params
});
const { count, events: tableData } = data;

setData(tableData); // data on the page
setDataCount(count[0].count); // total number of data across all pages

const start = (currentPage - 1) * rowsPerPage + 1;
setRowRangeString(`${start} - ${start + tableData.length - 1}`); // range of data on the page
};
refreshData();
}, [currentPage, rowsPerPage, setData, table, searchTerm, selectedFilters]);

useEffect(() => {
setCurrentPage(1);
}, [setCurrentPage, rowsPerPage, table]);


return (
<Flex
direction="row"
justify="space-between"
border="solid"
borderWidth="1px"
borderColor="#E2E8F0"
mx={5}
p={3}
>
<HStack spacing={0}>
<Box fontSize="14px" width="100%" whitespace="nowrap">
Show rows per page&nbsp;
</Box>
<Select
onChange={e => setRowsPerPage(e.target.value)}
defaultValue={10}
size="sm"
width="50%"
>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
</Select>
</HStack>
<Flex align="center" gap={5}>
<Text fontSize="14px">
<Text as="b" fontSize="14px">
{rowRangeString}
</Text>
&nbsp;of {dataCount}
</Text>
<Pagination pagesCount={pagesCount} currentPage={currentPage} onPageChange={setCurrentPage}>
<PaginationContainer justify="right">
<PaginationPrevious variant="ghost">&lsaquo;</PaginationPrevious>
<PaginationNext variant="ghost">&rsaquo;</PaginationNext>
</PaginationContainer>
</Pagination>
</Flex>
</Flex>

);
}
PaginationFooter.propTypes = {
setData: PropTypes.func,
table: PropTypes.string.isRequired,
data: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string,
}),
),
searchTerm: PropTypes.string.isRequired,
selectedFilters: PropTypes.shape({
subject: PropTypes.string,
eventType: PropTypes.string,
season: PropTypes.string,
year: PropTypes.string,
}),
};

PaginationFooter.defaultProps = {
data: [],
table: '',
setData: () => {},
};

export default PaginationFooter;



45 changes: 8 additions & 37 deletions src/pages/Catalog/Catalog.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Table, Thead, Tbody, Tr, Th, Td, TableContainer, Badge, Input, Select, Flex, Box, Center, Button } from '@chakra-ui/react';
import { useState, useEffect } from 'react';
import { NPOBackend } from '../../utils/auth_utils';
import { Link } from 'react-router-dom';
import { Table, Thead, Tbody, Tr, Th, Td, TableContainer, Badge, Input, Select, Flex, Box, Center } from '@chakra-ui/react';
import { useState } from 'react';
import PaginationFooter from '../../components/PaginationFooter/PaginationFooter';

const subjectsOptions = ['life skills', 'science', 'technology', 'engineering', 'math', 'college readiness'];
const eventOptions = ['guest speaker', 'study-trip', 'workshop', 'other'];
const yearOptions = ['junior', 'senior', 'both'];
Expand All @@ -17,28 +17,6 @@ export default function Catalog() {
year: '',
});

useEffect(() => {
const fetchCatalogData = async () => {
const params = {
title: searchTerm,
...selectedFilters,
};
console.log('fetching catalog data with params', params);
const response = await NPOBackend.get('/catalog', {
params: params
});
console.log('response', response);
setTableData(response.data);
};

const delay = setTimeout(() => {
fetchCatalogData().catch(console.error);
}, 750); // this is in miliseconds so 750 is .75 seconds, Vy design choice delay

return () => clearTimeout(delay);

}, [searchTerm, selectedFilters]);

const handleSearch = (event) => {
console.log('searching for', event.target.value);
setSearchTerm(event.target.value);
Expand All @@ -53,15 +31,7 @@ export default function Catalog() {

return (
<div>
<Flex justify="space-between" align="center" mb="4" bgColor="gray.200" p="4">
<Link to="/publishedschedule">
<Button bgColor="gray.200">Schedule</Button>
</Link>
<Link to="/logout">
<Button bgColor="gray.200">Logout</Button>
</Link>
</Flex>


<Center>
<Box minW="950px" mt="8">
<h1 style={{ fontSize: 35}}>Event Catalog</h1>
Expand Down Expand Up @@ -98,7 +68,7 @@ export default function Catalog() {
</Select>
</Flex>
</Flex>

<TableContainer mt="8" mb = "8" borderRadius="md" overflowX="auto">
<Table variant="simple" className="space-table" borderWidth="3px" width="100%">
<Thead>
Expand Down Expand Up @@ -131,10 +101,11 @@ export default function Catalog() {
))}
</Tbody>
</Table>
<PaginationFooter table="catalog" setData={setTableData} searchTerm={searchTerm} selectedFilters={selectedFilters} />
</TableContainer>
</Box>
</Center>
</div>
);
}

1 change: 0 additions & 1 deletion src/utils/auth_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ const finishGoogleLoginRegistration = async (redirectPath, navigate) => {
* @returns A boolean indicating whether or not the log in was successful
*/
const logInWithEmailAndPassword = async (email, password, redirectPath, navigate, cookies) => {
console.log(auth.currentUser);
await signInWithEmailAndPassword(auth, email, password);
// Check if the user has verified their email.
if (!auth.currentUser.emailVerified) {
Expand Down
Loading