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 and Top Polls Feature #40

Merged
merged 5 commits into from
May 16, 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
14 changes: 7 additions & 7 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 34 additions & 32 deletions frontend/src/components/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { useSelector, useDispatch } from 'react-redux';
import { Link as RouterLink } from 'react-router-dom';
import { fetchPolls } from '../features/pollSlice';
import PollList from './PollList';
import PollPagination from './PollPagination';
import { AppDispatch, RootState } from '../app/store';
import {
Container,
Typography,
Button,
Box,
Grid,
CircularProgress,
} from '@mui/material';

Expand Down Expand Up @@ -42,7 +42,11 @@ const Home = () => {
);

if (!user) {
// When there is no user logged in, simply display all polls without filtering
// When there is no user logged in, only display 5 most voted on polls
const topPolls = Object.values(polls)
.sort((a, b) => b.votes.length - a.votes.length)
.slice(0, 3);

return (
<Container>
<div
Expand Down Expand Up @@ -82,10 +86,10 @@ const Home = () => {
</div>
</div>
<Typography variant="h4" sx={{ my: 4 }}>
All Polls
Featured Polls
</Typography>
{Object.keys(polls).length ? (
<PollList polls={Object.values(polls)} />
{topPolls.length ? (
<PollList polls={topPolls} />
) : (
<Typography>No polls available.</Typography>
)}
Expand All @@ -95,9 +99,23 @@ const Home = () => {

return (
<Container>
<Typography variant="h4" sx={{ my: 4 }}>
Welcome, {user.name}!
</Typography>
<div
style={{
padding: '20px',
background: '#f0f0f0',
borderRadius: '8px',
marginTop: '20px',
}}
>
<Typography variant="h5" gutterBottom>
Welcome, {user.name}!
</Typography>
<Typography variant="body1" gutterBottom>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In in velit
mattis, faucibus sapien id, tristique turpis. Etiam pulvinar ante
magna, a finibus nibh lacinia sit amet.
</Typography>
</div>
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}>
<Button
variant="contained"
Expand All @@ -106,31 +124,15 @@ const Home = () => {
>
Show {showAnswered ? 'Unanswered' : 'Answered'} Polls
</Button>
<Button
component={RouterLink}
to="/create"
variant="outlined"
color="primary"
>
Create New Poll
</Button>
<Button
component={RouterLink}
to="/leaderboard"
variant="outlined"
color="primary"
>
Go to Leaderboard
</Button>
</Box>
<Grid container spacing={2}>
{pollStatus === 'succeeded' &&
(showAnswered ? answeredPolls.length : unansweredPolls.length) ? (
<PollList polls={showAnswered ? answeredPolls : unansweredPolls} />
) : (
<Typography>No polls available.</Typography>
)}
</Grid>
{pollStatus === 'succeeded' &&
(showAnswered ? answeredPolls.length : unansweredPolls.length) ? (
<PollPagination
polls={showAnswered ? answeredPolls : unansweredPolls}
/>
) : (
<Typography>No polls available.</Typography>
)}
</Container>
);
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/PollList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Poll as PollType } from '../features/pollSlice'; // Importing the Poll
import List from '@mui/material/List'; // Material-UI List component for consistent styling

// Defining the props expected by the PollList component using TypeScript interface
interface PollListProps {
export interface PollListProps {
polls: PollType[]; // Array of polls of type PollType
}

Expand Down
57 changes: 57 additions & 0 deletions frontend/src/components/PollPagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { useState } from 'react';
import type { PollListProps } from './PollList';
import PollList from './PollList';
import {
Box,
Select,
MenuItem,
Pagination,
SelectChangeEvent,
} from '@mui/material';

const PollPagination: React.FC<PollListProps> = ({ polls }) => {
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(5);

const handlePageChange = (
event: React.ChangeEvent<unknown>,
page: number,
) => {
setCurrentPage(page);
};

const handleItemsPerPageChange = (event: SelectChangeEvent<number>) => {
setItemsPerPage(event.target.value as number);
setCurrentPage(1); // Reset to the first page whenever items per page changes
};

const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const currentPolls = polls.slice(startIndex, endIndex);
const pageCount = Math.ceil(polls.length / itemsPerPage);

return (
<Box>
<PollList polls={currentPolls} />
<Box
sx={{ display: 'flex', justifyContent: 'space-between', mt: 3, mb: 3 }}
>
<Select value={itemsPerPage} onChange={handleItemsPerPageChange}>
{[5, 10, 15, 20].map(option => (
<MenuItem key={option} value={option}>
{option} per page
</MenuItem>
))}
</Select>
<Pagination
count={pageCount}
page={currentPage}
onChange={handlePageChange}
color="primary"
/>
</Box>
</Box>
);
};

export default PollPagination;