Added vote in frontend
This commit is contained in:
@@ -1,24 +1,42 @@
|
|||||||
// VotingPage.js
|
// VotingPage.js
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { Bar } from "react-chartjs-2";
|
import { Bar } from "react-chartjs-2";
|
||||||
import { Chart as ChartJS, BarElement, CategoryScale, LinearScale } from "chart.js";
|
import { Chart as ChartJS, BarElement, CategoryScale, LinearScale } from "chart.js";
|
||||||
import { useQuery } from "react-query";
|
import { useMutation, useQuery } from "react-query";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import getPollData from "../services/getPollData";
|
import getPollData from "../services/getPollData";
|
||||||
import ErrorFallback from "../components/Errors/ErrorFallback";
|
import ErrorFallback from "../components/Errors/ErrorFallback";
|
||||||
|
import createVoteService from "../services/createVoteService";
|
||||||
|
import { FaBookmark } from "react-icons/fa";
|
||||||
|
import {toast} from "react-toastify";
|
||||||
|
|
||||||
ChartJS.register(BarElement, CategoryScale, LinearScale);
|
ChartJS.register(BarElement, CategoryScale, LinearScale);
|
||||||
|
|
||||||
function VotingPage() {
|
function VotingPage() {
|
||||||
|
|
||||||
const { pollId } = useParams();
|
const { pollId } = useParams();
|
||||||
|
const [seletedOption, setSeletedOption] = useState(null);
|
||||||
|
|
||||||
const { data: poll, isLoading, isError, refetch } = useQuery(["poll", pollId], () => getPollData(pollId), {
|
const { data: poll, isLoading, isError, refetch } = useQuery(["poll", pollId], () => getPollData(pollId), {
|
||||||
cacheTime : 10*100*60, // 10 minutes
|
cacheTime : 10*100*60, // 10 minutes
|
||||||
staleTime : 20*100*60, // 20 minutes
|
staleTime : 20*100*60, // 20 minutes
|
||||||
});
|
});
|
||||||
|
|
||||||
// Dummy chart data for visualization
|
const mutation = useMutation(createVoteService, {
|
||||||
|
onSuccess: (data) => {
|
||||||
|
toast.success("Vote given successfully");
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.log(error);
|
||||||
|
toast.error(error?.response?.data?.message || "An unexpected error occurred");
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleOptionSelect = (id) => {
|
||||||
|
mutation.mutate({ pollId, optionId: id });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const chartData = {
|
const chartData = {
|
||||||
labels: poll?.data?.pollData?.options.map(option => option.name),
|
labels: poll?.data?.pollData?.options.map(option => option.name),
|
||||||
datasets: [
|
datasets: [
|
||||||
@@ -43,6 +61,7 @@ function VotingPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-base-200 min-h-screen p-6 text-white flex flex-col items-center">
|
<div className="bg-base-200 min-h-screen p-6 text-white flex flex-col items-center">
|
||||||
|
<div className="w-full flex justify-between max-w-lg">
|
||||||
{/* Poll Creator Info */}
|
{/* Poll Creator Info */}
|
||||||
<div className="flex items-center justify-center gap-4 mb-6">
|
<div className="flex items-center justify-center gap-4 mb-6">
|
||||||
<img
|
<img
|
||||||
@@ -53,15 +72,24 @@ function VotingPage() {
|
|||||||
<h2 className="text-lg md:text-xl font-semibold">{poll?.data?.creatorData?.username || "Unknown"}</h2>
|
<h2 className="text-lg md:text-xl font-semibold">{poll?.data?.creatorData?.username || "Unknown"}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* BookMark Button */}
|
||||||
|
<button className="btn btn-circle btn-neutral"><FaBookmark /></button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Poll Title */}
|
{/* Poll Title */}
|
||||||
<h1 className="text-xl md:text-3xl font-bold mb-4 text-center">{poll?.data?.pollData?.title || "Loading.."}</h1>
|
<h1 className="text-xl md:text-3xl font-bold text-center">{poll?.data?.pollData?.title || "Loading.."}</h1>
|
||||||
|
|
||||||
|
{/* Poll Description */}
|
||||||
|
<p className="text-sm font-light md:text-base mb-6 text-center">{poll?.data?.pollData?.description || "Loading.."}</p>
|
||||||
|
|
||||||
{/* Voting Options */}
|
{/* Voting Options */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 w-full max-w-lg mb-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 w-full max-w-lg mb-6">
|
||||||
{poll?.data?.pollData?.options.map(option => (
|
{poll?.data?.pollData?.options.map(option => (
|
||||||
<div
|
<div
|
||||||
|
onClick={() => handleOptionSelect(option._id)}
|
||||||
key={option._id}
|
key={option._id}
|
||||||
className="md:p-4 p-2 bg-base-100 rounded-lg shadow-md flex items-center justify-center cursor-pointer hover:bg-base-300 transition"
|
className= {`md:p-4 p-2 ${seletedOption == option._id ? "bg-blue-500" : "bg-base-100"} rounded-lg shadow-md flex items-center justify-center cursor-pointer ${seletedOption == option._id ? "outline" :"hover:bg-base-300"} transition`}
|
||||||
>
|
>
|
||||||
<span className="text-lg">{option.name}</span>
|
<span className="text-lg">{option.name}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
8
frontend/src/services/createVoteService.js
Normal file
8
frontend/src/services/createVoteService.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import axiosInstance from "../helper/axiosInstance";
|
||||||
|
|
||||||
|
async function createVoteService(data) {
|
||||||
|
const response = await axiosInstance.post("/poll/vote", data);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createVoteService
|
||||||
8
frontend/src/utils/util.js
Normal file
8
frontend/src/utils/util.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export const saveSelectedOption = (pollId, seletedOptionId) => {
|
||||||
|
localStorage.setItem(pollId, seletedOptionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getSelectedOption = (pollId) => {
|
||||||
|
const selecetedId = localStorage.getItem(pollId);
|
||||||
|
return selecetedId;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user