From b84a031770a810658243ee7939c0a36b683eca57 Mon Sep 17 00:00:00 2001 From: Manik Maity Date: Fri, 8 Nov 2024 22:12:16 +0530 Subject: [PATCH] =?UTF-8?q?Added=20create=20poll=20in=20frontend=20?= =?UTF-8?q?=E2=9C=94=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/helper/axiosInstance.js | 4 + frontend/src/pages/CreatePollForm.jsx | 189 ++++++++++++++++----- frontend/src/pages/Dashboard.jsx | 12 +- frontend/src/services/createPollService.js | 8 + package-lock.json | 91 ++++++++++ package.json | 5 + 6 files changed, 255 insertions(+), 54 deletions(-) create mode 100644 frontend/src/services/createPollService.js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/frontend/src/helper/axiosInstance.js b/frontend/src/helper/axiosInstance.js index 836e270..ce7db93 100644 --- a/frontend/src/helper/axiosInstance.js +++ b/frontend/src/helper/axiosInstance.js @@ -2,6 +2,10 @@ import axios from "axios"; const axiosInstance = axios.create({ baseURL: "http://localhost:3000/api/v1", + withCredentials: true, + headers: { + "Content-Type": "application/json", + }, }); export default axiosInstance; diff --git a/frontend/src/pages/CreatePollForm.jsx b/frontend/src/pages/CreatePollForm.jsx index 1370061..9858423 100644 --- a/frontend/src/pages/CreatePollForm.jsx +++ b/frontend/src/pages/CreatePollForm.jsx @@ -1,64 +1,161 @@ // CreatePollForm.js import React, { useState } from "react"; import { FaPlus, FaTrashAlt } from "react-icons/fa"; +import { useMutation } from "react-query"; +import createPollService from "../services/createPollService"; +import { toast } from "react-toastify"; function CreatePollForm() { - const [options, setOptions] = useState(["Option 1", "Option 2"]); + const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + const [options, setOptions] = useState([]); + const [optionInput, setOptionInput] = useState(""); + + const handleAddOption = () => { + if (optionInput.trim() == "") { + return; + } + setOptions((prev) => [...prev, optionInput]); + setOptionInput(""); + }; + + const handleClearPoll = () => { + setTitle(""); + setDescription(""); + setOptions([]); + setOptionInput(""); + }; + + const mutation = useMutation(createPollService, { + onSuccess: (data) => { + const message = data?.message || "Poll created successfully"; + toast.success(message); + handleClearPoll(); + }, + onError: (error) => { + console.log(error); + const errorMessage = + error.response?.data?.errors?.[0]?.message || + "An unexpected error occurred"; + toast.error(errorMessage); + }, + }); + + const handlePollSubmit = (e) => { + e.preventDefault(); + if (title.trim() == "" || description.trim() == "" || options.length == 0) { + toast.error("All fields are required"); + return; + } + mutation.mutate({ title, description, options }); + }; return ( -
-
+
+

Create New Poll

- - {/* Poll Title */} -
- - -
- - {/* Poll Description */} -
- - -
- - {/* Poll Options */} -
- - {options.map((option, index) => ( -
+
+
+ {/* Poll Title */} +
+ setTitle(e.target.value)} + placeholder="Enter poll title" className="input input-bordered w-full" - readOnly /> - {options.length > 2 && ( - - )}
- ))} - + + {/* Poll Description */} +
+ + +
+
+ +
+ {/* Poll Options */} +
+ + + {options.map((option, index) => ( +
+ + {options.length > 2 && ( + + )} +
+ ))} + + {/* Options input field */} +
+ setOptionInput(e.target.value)} + placeholder="Enter new option" + className="input input-bordered w-full" + /> +
+ +
+
- {/* Submit Button */} - +
+ + {/* Submit Button */} + +
); diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx index 0b54c80..55ca7c5 100644 --- a/frontend/src/pages/Dashboard.jsx +++ b/frontend/src/pages/Dashboard.jsx @@ -2,10 +2,12 @@ import React, { useState } from "react"; import { FaPlus } from "react-icons/fa"; import PollTableRow from "../components/PollTableRow/PollTableRow"; +import { useNavigate } from "react-router-dom"; function Dashboard() { - const [showPollAddForm, setShowPollAddForm] = useState(false); + const navigator = useNavigate(); + const pollData = [ { _id: "1", title: "Poll 1", description: "Description of Poll 1", totalVotes: 120, published: true }, { _id: "2", title: "Poll 2", description: "Description of Poll 2", totalVotes: 45, published: false }, @@ -14,12 +16,6 @@ function Dashboard() { return (
- {showPollAddForm && ( -
- {/* Poll Add Form Component would go here */} -
- )} - {/* User Profile Sidebar */}
diff --git a/frontend/src/services/createPollService.js b/frontend/src/services/createPollService.js new file mode 100644 index 0000000..6eeb342 --- /dev/null +++ b/frontend/src/services/createPollService.js @@ -0,0 +1,8 @@ +import axiosInstance from "../helper/axiosInstance"; + +async function createPollService(data) { + const response = await axiosInstance.post("/poll/create", data); + return response.data; +} + +export default createPollService diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a662278 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,91 @@ +{ + "name": "LivePoll", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "react-toastify": "^10.0.6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT", + "peer": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-toastify": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.6.tgz", + "integrity": "sha512-yYjp+omCDf9lhZcrZHKbSq7YMuK0zcYkDFTzfRFgTXkTFHZ1ToxwAonzA4JI5CxA91JpjFLmwEsZEgfYfOqI1A==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..aa01aab --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "react-toastify": "^10.0.6" + } +}