Added Polls Page

This commit is contained in:
Manik Maity
2024-11-13 15:05:07 +05:30
parent e007f18bb5
commit b3525c16dc
6 changed files with 109 additions and 19 deletions

View File

@@ -13,6 +13,7 @@ import { QueryClient, QueryClientProvider } from "react-query";
import PrivateRoute from "./components/PrivateRoute/PrivateRoute"; import PrivateRoute from "./components/PrivateRoute/PrivateRoute";
import { ToastContainer } from "react-toastify"; import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css"; import "react-toastify/dist/ReactToastify.css";
import Polls from "./pages/Polls";
function App() { function App() {
const queryClient = new QueryClient(); const queryClient = new QueryClient();
@@ -25,6 +26,7 @@ function App() {
<Route path="/" element={<Home />} /> <Route path="/" element={<Home />} />
<Route path="/login" element={<LoginPage />} /> <Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<Register />} /> <Route path="/register" element={<Register />} />
<Route path="/poll" element={<Polls />} />
<Route element={<PrivateRoute />}> <Route element={<PrivateRoute />}>
<Route path="dashboard" element={<Dashboard />} /> <Route path="dashboard" element={<Dashboard />} />
<Route path="bookmark" element={<Bookmark />} /> <Route path="bookmark" element={<Bookmark />} />

View File

@@ -1,26 +1,37 @@
import React from 'react' import React from "react";
import { Link } from 'react-router-dom' import { Link } from "react-router-dom";
import useUserStore from '../../store/useStore' import useUserStore from "../../store/useStore";
import ProfileImage from './ProfileImage'; import ProfileImage from "./ProfileImage";
function Header() { function Header() {
const { user } = useUserStore(); const { user } = useUserStore();
return ( return (
<div className="navbar bg-base-100"> <div className="navbar bg-base-100">
<div className="flex-1"> <div className="flex-1">
<Link to={"/"} className="btn btn-ghost text-xl">LivePoll</Link> <Link to={"/"} className="btn btn-ghost text-xl">
LivePoll
</Link>
</div> </div>
<div className="flex-none"> <div className="flex-none">
<ul className="menu menu-horizontal px-1"> <ul className="menu menu-horizontal px-1 gap-1">
{user.username ? <li><Link to={"/dashboard"}>Dashboard</Link></li> : <li><Link to={"/login"}>Login</Link></li>} {user.username ? (
<li><Link to={'/bookmark'}>Bookmarks</Link></li> <li>
<Link to={"/dashboard"}>Dashboard</Link>
</li>
) : (
<li>
<Link to={"/login"}>Login</Link>
</li>
)}
<li>
<Link to={"/poll"}>Polls</Link>
</li>
</ul> </ul>
</div> </div>
{user.username && <ProfileImage userData={user} />} {user.username && <ProfileImage userData={user} />}
</div> </div>
) );
} }
export default Header export default Header;

View File

@@ -29,6 +29,9 @@ function ProfileImage({userData}) {
Profile Profile
<span className="badge">New</span> <span className="badge">New</span>
</Link> </Link>
<Link to={"/bookmark"} className="justify-between" >
Bookmarks
</Link>
</li> </li>
<li><a onClick={handleLogout}>Logout</a></li> <li><a onClick={handleLogout}>Logout</a></li>
</ul> </ul>

View File

@@ -0,0 +1,28 @@
import React from "react";
import { useNavigate } from "react-router-dom";
function PollCard({ poll }) {
const navigator = useNavigate();
const handleViewOnClick = () => {
navigator(`/view/${poll._id}`);
};
return (
<div className="card bg-base-300 shadow-xl text-white w-full md:w-80">
<div className="card-body">
<h2 className="card-title text-xl font-bold">{poll.title}</h2>
<p className="text-sm text-base-content">{poll.description}</p>
<div className="flex items-center justify-between mt-4">
<div className="text-xs text-gray-400">
Created by <span className="text-yellow-400">{poll.creatorData.username}</span> on {new Date(poll?.createdAt).toLocaleDateString()}
</div>
<button onClick={handleViewOnClick} className="btn btn-primary btn-sm text-base-content">View</button>
</div>
</div>
</div>
);
}
export default PollCard;

View File

@@ -0,0 +1,38 @@
import React, { useState } from 'react'
import { useQuery } from 'react-query'
import getPollsService from '../services/getPollsService'
import PollCard from '../components/PollCard/PollCard'
import ErrorFallback from '../components/Errors/ErrorFallback'
function Polls() {
const [page, setPage] = useState(1);
const [limit, setLimit] = useState(6);
const {data, isLoading, isError, isSuccess, refetch} = useQuery(["polls", page, limit], () => getPollsService(page, limit), {
cacheTime: 1000 * 60 * 5, // 5 minutes
staleTime: 1000 * 60 * 10, // 10 minutes
})
return (
<div className="container mx-auto p-4 bg-base-200">
<h1 className="text-2xl font-bold text-center mb-6">Polls</h1>
{isSuccess && <div className="flex flex-wrap justify-center gap-6">
{data?.data?.polls?.map((poll) => (
<PollCard key={poll._id} poll={poll} />
))}
</div>}
{isLoading && <div className='flex flex-wrap justify-center gap-6 skeleton min-h-40'></div>}
{isError && <div className='flex justify-center gap-6'>
<ErrorFallback onRetry={() => refetch()} />
</div>}
<div className='flex justify-center gap-6 mt-6'>
<button className='btn btn-primary btn-circle' disabled={page <= 1} onClick={() => setPage(page - 1)}>Prev</button>
<button className='btn btn-primary btn-circle' disabled={data?.data?.totalPages === page} onClick={() => setPage(page + 1)}>Next</button>
</div>
</div>
)
}
export default Polls

View File

@@ -0,0 +1,8 @@
import axiosInstance from "../helper/axiosInstance";
async function getPollsService(page = 1, limit = 10) {
const response = await axiosInstance.get(`poll/all?page=${page}&limit=${limit}`);
return response.data;
}
export default getPollsService;