diff --git a/frontend/src/hooks/useBookmark.js b/frontend/src/hooks/useBookmark.js new file mode 100644 index 0000000..5a29b9d --- /dev/null +++ b/frontend/src/hooks/useBookmark.js @@ -0,0 +1,28 @@ +import React from 'react' +import { useMutation } from 'react-query'; +import { toast } from 'react-toastify'; +import { addToBookmarkService } from '../services/addToBookmarkService'; + +function useBookmark() { + + const BookmarkMutation = useMutation(addToBookmarkService, { + onSuccess: (data) => { + toast.success(data?.message); + }, + onError: (error) => { + console.log(error); + toast.error( + error?.response?.data?.message || "An unexpected error occurred" + ); + }, + }) + + const handleBookmark = (pollId) => { + BookmarkMutation.mutate(pollId); + } + + + return {handleBookmark, BookmarkMutation}; +} + +export default useBookmark diff --git a/frontend/src/pages/Bookmark.jsx b/frontend/src/pages/Bookmark.jsx index fda0099..029ad77 100644 --- a/frontend/src/pages/Bookmark.jsx +++ b/frontend/src/pages/Bookmark.jsx @@ -22,7 +22,7 @@ const dummyBookmarks = [ function Bookmark() { return (
-

Bookmarked Polls

+

Bookmarked Polls

@@ -37,12 +37,12 @@ function Bookmark() { {dummyBookmarks.map((bookmark, index) => ( - - + diff --git a/frontend/src/pages/VotingPage.jsx b/frontend/src/pages/VotingPage.jsx index cbe506a..b9f3381 100644 --- a/frontend/src/pages/VotingPage.jsx +++ b/frontend/src/pages/VotingPage.jsx @@ -1,25 +1,36 @@ -// VotingPage.js import React, { useState } from "react"; 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 { useMutation, useQuery } from "react-query"; import { useParams } from "react-router-dom"; import getPollData from "../services/getPollData"; import ErrorFallback from "../components/Errors/ErrorFallback"; import createVoteService from "../services/createVoteService"; import { FaBookmark } from "react-icons/fa"; -import {toast} from "react-toastify"; +import { toast } from "react-toastify"; +import { makeChartDataObjFromPollData } from "../utils/util"; +import useBookmark from "../hooks/useBookmark"; ChartJS.register(BarElement, CategoryScale, LinearScale); function VotingPage() { - const { pollId } = useParams(); const [seletedOption, setSeletedOption] = useState(null); + const {handleBookmark} = useBookmark() - const { data: poll, isLoading, isError, refetch } = useQuery(["poll", pollId], () => getPollData(pollId), { - cacheTime : 10*100*60, // 10 minutes - staleTime : 20*100*60, // 20 minutes + const { + data: poll, + isLoading, + isError, + refetch, + } = useQuery(["poll", pollId], () => getPollData(pollId), { + cacheTime: 10 * 100 * 60, // 10 minutes + staleTime: 20 * 100 * 60, // 20 minutes }); const mutation = useMutation(createVoteService, { @@ -27,69 +38,71 @@ function VotingPage() { toast.success("Vote given successfully"); }, onError: (error) => { - console.log(error); - toast.error(error?.response?.data?.message || "An unexpected error occurred"); + console.log(error); + toast.error( + error?.response?.data?.message || "An unexpected error occurred" + ); }, - }) + }); const handleOptionSelect = (id) => { mutation.mutate({ pollId, optionId: id }); - } - - - const chartData = { - labels: poll?.data?.pollData?.options.map(option => option.name), - datasets: [ - { - label: "Votes", - data: poll?.data?.pollData?.options.map(option => option.voteCount), - backgroundColor: ["#3B82F6", "#EF4444", "#10B981", "#F59E0B"], - borderWidth: 1, - }, - ], }; if (isLoading) { return
; } - if (isError){ - return
- -
+ if (isError) { + return ( +
+ +
+ ); } return (
- {/* Poll Creator Info */} -
- {poll?.data?.creatorData?.username} -

{poll?.data?.creatorData?.username || "Unknown"}

-
+ {/* Poll Creator Info */} +
+ {poll?.data?.creatorData?.username} +

+ {poll?.data?.creatorData?.username || "Unknown"} +

+
- {/* BookMark Button */} - - + {/* BookMark Button */} +
{/* Poll Title */} -

{poll?.data?.pollData?.title || "Loading.."}

+

+ {poll?.data?.pollData?.title || "Loading.."} +

{/* Poll Description */} -

{poll?.data?.pollData?.description || "Loading.."}

+

+ {poll?.data?.pollData?.description || "Loading.."} +

{/* Voting Options */}
- {poll?.data?.pollData?.options.map(option => ( + {poll?.data?.pollData?.options.map((option) => (
handleOptionSelect(option._id)} key={option._id} - 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`} + 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`} > {option.name}
@@ -98,7 +111,10 @@ function VotingPage() { {/* Chart Visualization */}
- +
); diff --git a/frontend/src/services/addToBookmarkService.js b/frontend/src/services/addToBookmarkService.js new file mode 100644 index 0000000..7a12623 --- /dev/null +++ b/frontend/src/services/addToBookmarkService.js @@ -0,0 +1,6 @@ +import axiosInstance from "../helper/axiosInstance"; + +export async function addToBookmarkService(pollId) { + const response = await axiosInstance.get(`/poll/bookmark/${pollId}`); + return response.data; +} \ No newline at end of file diff --git a/frontend/src/utils/util.js b/frontend/src/utils/util.js index d6acb8b..846412b 100644 --- a/frontend/src/utils/util.js +++ b/frontend/src/utils/util.js @@ -5,4 +5,18 @@ export const saveSelectedOption = (pollId, seletedOptionId) => { export const getSelectedOption = (pollId) => { const selecetedId = localStorage.getItem(pollId); return selecetedId; +} + +export const makeChartDataObjFromPollData = (poll) => { + return { + labels: poll?.data?.pollData?.options.map(option => option.name), + datasets: [ + { + label: "Votes", + data: poll?.data?.pollData?.options.map(option => option.voteCount), + backgroundColor: ["#3B82F6", "#EF4444", "#10B981", "#F59E0B"], + borderWidth: 1, + }, + ], + }; } \ No newline at end of file
{index + 1}{bookmark.title} + {bookmark.title} {bookmark.description} -