diff --git a/client/package-lock.json b/client/package-lock.json index b75f148..372136a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -27,6 +27,7 @@ "react-scripts": "5.0.1", "react-scroll": "^1.8.9", "react-toastify": "^9.1.3", + "reselect": "^4.1.8", "web-vitals": "^2.1.4", "web3": "^4.1.1" }, diff --git a/client/package.json b/client/package.json index 384a63c..7ca4d95 100644 --- a/client/package.json +++ b/client/package.json @@ -23,6 +23,7 @@ "react-scripts": "5.0.1", "react-scroll": "^1.8.9", "react-toastify": "^9.1.3", + "reselect": "^4.1.8", "web-vitals": "^2.1.4", "web3": "^4.1.1" }, diff --git a/client/src/App.js b/client/src/App.js index e8a2fc9..40cab80 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -27,7 +27,7 @@ const App = () => { } /> } /> } /> - + {/* } /> */} {/* user protected routes */} }> } /> @@ -35,7 +35,7 @@ const App = () => { } /> } /> } /> - } /> + } /> @@ -44,7 +44,7 @@ const App = () => { } /> } /> } /> - } /> + {/* } /> */} } /> {/* } /> */} {/* } /> */} diff --git a/client/src/Contract/Normalvote.sol b/client/src/Contract/Normalvote.sol index 80461c9..1a931ce 100644 --- a/client/src/Contract/Normalvote.sol +++ b/client/src/Contract/Normalvote.sol @@ -1,111 +1,188 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.18; -contract SimpleVoting { - // Structs - struct Candidate { - string name; - uint votes; - } - struct Booth { - string zoneName; - Candidate [] candidates; - uint votingStart; - uint duration; - address admin; - uint candidatescnt; +contract voting{ + ///////////// + ///Structs/// + ///////////// + + struct Candidate{ + string name; + uint128 votes; + string zone; } - struct Voter { + struct Voter{ address voterAddress; - bool isVoted; + bool voted; } - // Events - event BoothCreated(string zoneName, Candidate[] candidates, uint votingStart,address superadmin, uint duration); - event Voted(string zoneName, uint candidateIndex); - event adminadded(address admin_,string zoneName_); - event candidateAdded(string candidateName_,string zoneName_,address admin_); + struct Admin{ + string zone; + } - // State Variables - uint public zones = 0; + //State Variables//// + ///////////////////// + address public superAdmin; + uint votingStart; + uint votingEnd; + string public zone; + Candidate[] public candidates; - // Mappings - mapping(string => Booth) private booths; - mapping(address => bool) public voters; - mapping(address => bool) public isAdmin; + ///MAPPINGS/// + ////////////// + mapping(address voteradr => bool isvoted) public voters; + mapping(address adminadr => bool isadmin) public admins; + mapping(address => string) public adminZones; + mapping(string name=>uint Index)public candidateno; - // Modifiers - modifier onlyAdmin(string memory zoneName_,address admin_) { - require(isAdmin[admin_], "Only Admins"); - Booth storage booth = booths[zoneName_]; - require(booth.admin==admin_,"Not an admin"); - _; + constructor(string memory _zone){ + superAdmin=msg.sender; + zone=_zone; } - modifier onlysuperAdmin() { - require(superAdmin==msg.sender, "Only Admins"); + + ////////////// + //Modifiers// + ////////////// + modifier onlyadmin(address admin_){ + require(admins[admin_],"Only Admins"); _; } + modifier onlysuperAdmin{ + require(superAdmin==msg.sender,"Only Superadmin "); + _; + } + + ////Main Functions/// + ///////////////////// + function addAdmin(address _admin) public payable onlysuperAdmin { + adminZones[_admin] = zone; + admins[_admin]=true; + } - // Main functions - function createBooth( - string memory zoneName_, - string [] memory candidateNames_, - uint votingStart_, - uint durationinDays_ - ) external payable { - uint duration = votingStart_ + (durationinDays_ * 1 days); - Booth storage booth = booths[zoneName_]; - booth.zoneName = zoneName_; - booth.votingStart = votingStart_; - booth.duration = duration; - booth.candidatescnt = 0; - superAdmin=msg.sender; - for (uint i = 0; i < candidateNames_.length; i++) { - booth.candidates.push(Candidate(candidateNames_[i], 0)); - booth.candidatescnt++; + function addCandidate(string memory partyName,address admin) public onlyadmin(admin_) { + require(!getVotingStatus(),"Voting is going on Can't add now !"); + candidates.push(Candidate({ + name: _partyName, + votes: 0, + zone: adminZones[msg.sender] + })); + candidateno[_partyName]=candidates.length+1; + } + + ///Working functions/// + /////////////////////// + function initiateVoting(string[] memory _candidateNames, uint256 _durationInminutes) external{ + require(_candidateNames.length>=2,"Atleast two Candidates should be there in Election "); + for (uint128 i = 0; i < _candidateNames.length; i++) { + candidates.push(Candidate({ + name: _candidateNames[i], + votes: 0, + zone:adminZones[msg.sender] + })); + candidateno[_candidateNames[i]]=i; } - // emit BoothCreated(zoneName_, booth.candidates, votingStart_,msg.sender, duration); - zones++; + votingStart = block.timestamp; + votingEnd = block.timestamp + (_durationInminutes * 1 minutes); } - function addAdmin(address admin_,string memory zoneName_) external onlysuperAdmin { - require(isAdmin[admin_] ==false,"Already an admin "); - Booth storage booth = booths[zoneName_]; - booth.admin=admin_; - isAdmin[admin_]=true; - emit adminadded(admin_,zoneName_); + function vote(uint _candidateIndex,address voter) public { + require(block.timestamp>votingStart,"Voting hasn't started !"); + require(block.timestamp= votingStart && block.timestamp < votingEnd); + } } - function vote(string memory zoneName_, uint candidateIndex_) public { - require(!voters[msg.sender], "You have already voted."); - Booth storage booth = booths[zoneName_]; - require(candidateIndex_ < booth.candidates.length, "Invalid candidate index."); - booth.candidates[candidateIndex_].votes++; - voters[msg.sender] = true; - emit Voted(zoneName_, candidateIndex_); +contract VotingFactory{ + + address public owner; + address[] public deployedContracts; + voting newContract; + + struct Candidate{ + string name; + uint128 votes; + string zone; + } + ////////////// + ///mappings/// + ////////////// + mapping(address => string) public contractZones; + mapping(string =>address)public zonesContract; + mapping(address superadminadr => bool issuperadmin) public superadmins; + + + constructor(){ + owner=msg.sender; } - function GetResults(string memory zoneName_) external view onlysuperAdmin returns (Candidate[] memory) { - Booth storage booth = booths[zoneName_]; - return booth.candidates; + ////////////////// + //////Modifier//// + ////////////////// + modifier onlysuperadmin { + require(superadmins[msg.sender],"Only Super Admins"); + _; + } + modifier onlyOwner { + require(msg.sender==owner,"Only Owner"); + _; + } + + ///Main Functions/// + ////////////////////// + + function createVotingContract(string memory _zone) public payable { + newContract = new voting(_zone); + deployedContracts.push(address(newContract)); + contractZones[address(newContract)] = _zone; + zonesContract[_zone]=address(newContract); + } + + function AddSuperAdminVF(address superAdmin) public payable{ + require(!superadmins[msg.sender],"Already a superAdmin"); + superadmins[superAdmin]=true; + } + + function AddCandidateVF(string memory _partyname) public{ + newContract.addCandidate(_partyname,msg.sender); } - function getBoothByZoneName(string memory zoneName_) external view returns (Booth memory) { - return booths[zoneName_]; + function addadminVF(address _admin) public { + newContract.addAdmin(_admin); + } + + + function initiateVotingVF(string[] memory _candidateNames, uint256 _durationInDays) public { + newContract.initiateVoting(_candidateNames,_durationInDays); + } + + function voteVF(uint _candidateIndex,address voter) public { + newContract.vote(_candidateIndex,voter); + } + + function getStatus() public view returns(bool){ + return newContract.getVotingStatus(); + } + + function showResultsVF() public view returns (voting.Candidate[] memory) { + return newContract.showResults(); } } -// ["Amaan","Meghna"] -// 0x0DbbFd3deF00C5aAd59A6427e339F0194D00f428 \ No newline at end of file + +//0xfbDaBD3eb616dd601264F7983DCA1Ed935DDcD44 \ No newline at end of file diff --git a/client/src/component/WalletConnectButton.js b/client/src/component/WalletConnectButton.js index eabae7d..6981ab1 100644 --- a/client/src/component/WalletConnectButton.js +++ b/client/src/component/WalletConnectButton.js @@ -1,32 +1,32 @@ import React from "react"; import { useDispatch, useSelector } from "react-redux"; -import { connectWallet, setConnected, setError } from "../redux/walletSlice.js"; +import { connectWallet, setError } from "../redux/walletSlice.js"; -const WalletConnectButton = () => { +const WalletConnectButton = ({changeWallet}) => { const dispatch = useDispatch(); - const connected = useSelector(setConnected); + const error = useSelector(setError); - +console.log(error) const handleConnectWallet = async () => { - if (!connected) { + try { - await dispatch(connectWallet()); + dispatch(connectWallet()); + changeWallet(); } catch (err) { console.log(err); } - } + }; return (
- {connected ? ( -

Your wallet is connected.

- ) : ( +
- {error &&

{error}

} + + {/* {error &&

{error}

} */}
- )} +
); }; diff --git a/client/src/page/Login.jsx b/client/src/page/Login.jsx index 430e93b..e872cbc 100644 --- a/client/src/page/Login.jsx +++ b/client/src/page/Login.jsx @@ -10,6 +10,7 @@ import { } from "@mui/material"; import { toast } from "react-toastify"; import { login, reset } from "../redux/authSlice"; +// import { initWallet, setInitialized} from "../redux/walletSlice.js"; import { useSelector, useDispatch } from "react-redux"; import Layout from "../component/Layout/Layout"; import Spinner from "../component/Spinner"; @@ -22,6 +23,18 @@ const LoginPageComponent = () => { const navigate = useNavigate(); const dispatch = useDispatch(); + //const initialized = useSelector(setInitialized); + + + // const handleInitWallet = async () => { + // if (!initialized) { + // try { + // await dispatch(initWallet()); + // } catch (err) { + // console.log(err); + // } + // } + // }; const { user, isLoading, isError, isSuccess, message } = useSelector( (state) => state.auth ); @@ -47,7 +60,10 @@ const LoginPageComponent = () => { if (isError) toast.error(message); if (isSuccess || (user && !user.isAdmin)) navigate("/"); else if (isSuccess || (user && user.isAdmin)) navigate("/admin"); - else if (isSuccess || (user && user.isSuperAdmin)) navigate("/super-admin"); + else if (isSuccess || (user && user.isSuperAdmin)) { + navigate("/super-admin"); + // handleInitWallet(); + } dispatch(reset()); }, [user, isError, message, isSuccess, dispatch, navigate]); diff --git a/client/src/page/Profile.jsx b/client/src/page/Profile.jsx index 257cef5..2cf033f 100644 --- a/client/src/page/Profile.jsx +++ b/client/src/page/Profile.jsx @@ -168,7 +168,7 @@ const Profile = () => {
Full name
- {`${user.firstName} ${user.lastName}`} + {`${user.fullName}`}
diff --git a/client/src/page/Register.jsx b/client/src/page/Register.jsx index 84de9d7..2b1c907 100644 --- a/client/src/page/Register.jsx +++ b/client/src/page/Register.jsx @@ -45,13 +45,8 @@ const Register = () => { } else { setError(null); } - const nameParts = userData?.fullname.split(" "); - - if (nameParts.length >= 2) { - const [firstName, lastName] = nameParts; - delete userData.fullname; delete userData.confirmPassword; - const formData = { ...userData, firstName, lastName }; + const formData = { ...userData}; try { dispatch(register(formData)); @@ -59,7 +54,7 @@ const Register = () => { console.log(err); toast.error(err.message || "An error occurred. Please try again."); } - } + }; return ( diff --git a/client/src/page/SuperAdmin.jsx b/client/src/page/SuperAdmin.jsx index b77e1cb..3792c58 100644 --- a/client/src/page/SuperAdmin.jsx +++ b/client/src/page/SuperAdmin.jsx @@ -1,43 +1,62 @@ import React, { useState, useEffect } from "react"; import Layout from "../component/Layout/Layout"; import Grid from "@mui/material/Grid"; -// import Web3 from "web3"; +import Web3 from "web3"; // Import Web3 + import ABI from "./voting.json"; import { toast } from "react-toastify"; -import { useDispatch, useSelector } from "react-redux"; -import { - initWallet, - setConnected, - setError, -} from "../redux/walletSlice.js"; +import { useSelector } from "react-redux"; import WalletConnectButton from "../component/WalletConnectButton"; - +import { selectError } from "../redux/walletSlice"; const SuperAdmin = () => { const [selectedZone, setSelectedZone] = useState(""); const [currentPage, setCurrentPage] = useState(1); const itemsPerPage = 9; - const dispatch = useDispatch(); - const connected = useSelector(setConnected); - const error = useSelector(setError); + const [connected, setConnected] = useState(false); + useEffect(() => { + const sessionStorageConnected = JSON.parse( + sessionStorage.getItem("connected") + ); + if (sessionStorageConnected) { + setConnected(sessionStorageConnected); + } + }, []); + const address = JSON.parse(sessionStorage.getItem("address")) || ""; + + const error = useSelector(selectError); + const [fetched, setFetched] = useState(false); + let contract1; + const initContract = async () => { + try { + const provider = window.ethereum; + if (typeof provider === "undefined") { + toast.error( + "MetaMask is not installed. Please install it to use this application." + ); + return; + } - const contract = useSelector((state) => state.wallet.contract); + const web3 = new Web3(provider); + await provider.request({ method: "eth_requestAccounts" }); + + contract1 = new web3.eth.Contract( + ABI, + "0x0c8Bc9A045b36ba45798bCFCf7ca55ab8eeb88C6" + ); + setFetched(true); + } catch (err) { + console.error(err); + toast.error("An error occurred. Please try again."); + } + }; useEffect(() => { - - const initWalletWithCatch = async () => { - try { - await dispatch(initWallet()); - } catch (err) { - console.log(err); - } - }; + initContract(); + }, [fetched]); - initWalletWithCatch(); - }, [dispatch]); useEffect(() => { if (error) toast.error(error); - - }, [error, dispatch]); + }, [error]); const zoneDB = [ { @@ -102,39 +121,83 @@ const SuperAdmin = () => { }, ]; - // const contract = useSelector(selectContract); - + // const contract1 = useSelector(selectContract); +/* const CreateVotingBooth = async () => { try { - - const candidateNames = ["Amaan", "Satyam", "Sahil"]; - const durationInDays = 1; - const votingStart=new Date.now(); - const superAdmin = "0x0DbbFd3deF00C5aAd59A6427e339F0194D00f428"; - const zoneName="Ruby"; - contract.methods - .createBooth(zoneName, candidateNames, votingStart, durationInDays) - .send({ from: superAdmin }) - .on("transactionHash", (hash) => { - // Transaction sent; you can track it using the transaction hash - console.log("Transaction hash:", hash); + if (fetched) { + const candidateNames = ["AAP", "TMC", "BJP", "CPIM"]; + const durationInDays = 5; + const votingStart = Date.now(); + const superAdmin = address; + const zoneName = "Ruby"; + console.log("here"); + console.log(contract1); + await contract1.methods + .AddSuperAdminVF(superAdmin) + .send({ + from: superAdmin, + gas:30000000 }) - .on("confirmation", (confirmationNumber, receipt) => { - // Transaction confirmed; you can handle the receipt here - console.log("Confirmation number:", confirmationNumber); - console.log("Receipt:", receipt); - }) - .on("error", (error) => { - // Handle errors here - console.error("Error:", error); - }); - //console.log(contract); + .on("transactionHash", (hash) => { + // Transaction sent; you can track it using the transaction hash + console.log("Transaction hash:", hash); + }) + .on("confirmation", (confirmationNumber, receipt) => { + // Transaction confirmed; you can handle the receipt here + console.log("Confirmation number:", confirmationNumber); + console.log("Receipt:", receipt); + }) + .on("error", (error) => { + // Handle errors here + console.error("Error:", error); + }); + + // await contract1.methods + // .createVotingContract(zoneName) + // .send({ from: superAdmin ,gas:30000000}) + // .on("transactionHash", (hash) => { + // // Transaction sent; you can track it using the transaction hash + // console.log("Transaction hash:", hash); + // }) + // .on("confirmation", (confirmationNumber, receipt) => { + // // Transaction confirmed; you can handle the receipt here + // console.log("Confirmation number:", confirmationNumber); + // console.log("Receipt:", receipt); + // }) + // .on("error", (error) => { + // // Handle errors here + // console.error("Error:", error); + // }); + + // await contract1.methods + // .initiateVotingVF(candidateNames, durationInDays) + // .send({ from: superAdmin ,gas:30000000}) + // .on("transactionHash", (hash) => { + // // Transaction sent; you can track it using the transaction hash + // console.log("Transaction hash:", hash); + // }) + // .on("confirmation", (confirmationNumber, receipt) => { + // // Transaction confirmed; you can handle the receipt here + // console.log("Confirmation number:", confirmationNumber); + // console.log("Receipt:", receipt); + // }) + // .on("error", (error) => { + // // Handle errors here + // console.error("Error:", error); + // }); + } + + //console.log(contract1); } catch (error) { console.log(error); alert("Please Install Metamask"); } }; - + const changeWallet = () => { + setConnected(true); + console.log(connected); + }; const handleZoneChange = (event) => { setSelectedZone(event.target.value); setCurrentPage(1); @@ -154,7 +217,7 @@ const SuperAdmin = () => { const handlePageChange = (newPage) => { setCurrentPage(newPage); }; - +*/ return (
@@ -163,12 +226,21 @@ const SuperAdmin = () => { End Vote
- {!connected && } + {!connected ? ( + + ) : ( + + )}
{/* Dropdown filter by zone */} -
+ {/*
-
+
*/} - {currentData.map((zone, index) => ( + {zoneDB.map((zone, index) => (

Zone : {zone.zoneId}

@@ -199,7 +270,7 @@ const SuperAdmin = () => { {/* Pagination */} -
+ {/*
{Array.from({ length: totalPages }, (_, index) => ( ))} -
+
*/}
diff --git a/client/src/page/Vote.jsx b/client/src/page/Vote.jsx index 39705be..ad19d78 100644 --- a/client/src/page/Vote.jsx +++ b/client/src/page/Vote.jsx @@ -15,12 +15,12 @@ import web3 from 'web3' // import { useWeb3 } from './Web3Context'; // import contractInstance from "./contractInstance"; - const Vote = () => { - const contract = useSelector((state) => state.wallet.contract); + const [hasVoted,setHasVoted]=useState(false); const [loading,setLoading]=useState(false); const [state,setState]=useState(false); - const [data,setData]=useState(false); + // const [data,setData]=useState(false); + const contract = useSelector((state) => state.wallet.contract); const error = useSelector(setError); const candidatesDB = [ @@ -105,6 +105,7 @@ const candidatesDB = [ image_url: "https://example.com/olivia_turner.jpg", }, ]; + //Fetch both the data from database const userData = { fullName: "Mickael Poulaz", @@ -118,47 +119,26 @@ const userData = { voted: false, }; - const connectWallet=async()=>{ - try { - setLoading(true); - - if (window.ethereum) { - await window.ethereum.send('eth_requestAccounts'); - const accounts = await window.ethereum.request({ method: 'eth_accounts' }); - - if (accounts && accounts.length > 0) { - web3.setAccount(accounts[0]); - } - } - } catch (error) { - console.error('MetaMask connection error:', error); - } finally { - setLoading(false); - } - } - useEffect(() => { - WalletConnectButton(); - }, []); + const handleVoteClick = async (zoneName,index) => { try { const transaction = await contract.vote(zoneName,index); await transaction.wait(); - // alert(`Voted Successfully from ${signerAddress}`); + // alert(Voted Successfully from ${signerAddress}); setState({ ...state, contract }); } catch (error) { console.log(error); } - const updatedUserData = { ...data, voted: true }; - setData(updatedUserData); + }; return (

Vote

- {data.voted ? ( + {hasVoted ? ( ) : ( diff --git a/client/src/page/voting.json b/client/src/page/voting.json index 7ac080e..f0c7182 100644 --- a/client/src/page/voting.json +++ b/client/src/page/voting.json @@ -1,42 +1,44 @@ [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, { "inputs": [ { "internalType": "string", - "name": "_zone", + "name": "_partyname", "type": "string" } ], + "name": "AddCandidateVF", + "outputs": [], "stateMutability": "nonpayable", - "type": "constructor" + "type": "function" }, { "inputs": [ { "internalType": "address", - "name": "_admin", + "name": "superAdmin", "type": "address" } ], - "name": "addAdmin", + "name": "AddSuperAdminVF", "outputs": [], "stateMutability": "payable", "type": "function" }, { "inputs": [ - { - "internalType": "string", - "name": "_partyName", - "type": "string" - }, { "internalType": "address", "name": "_admin", "type": "address" } ], - "name": "addCandidate", + "name": "addadminVF", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -45,57 +47,32 @@ "inputs": [ { "internalType": "address", - "name": "adminadr", + "name": "", "type": "address" } ], - "name": "adminZones", + "name": "contractZones", "outputs": [ { "internalType": "string", - "name": "zones", + "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "adminadr", - "type": "address" - } - ], - "name": "admins", - "outputs": [ - { - "internalType": "bool", - "name": "isadmin", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { "internalType": "string", - "name": "name", + "name": "_zone", "type": "string" } ], - "name": "candidateno", - "outputs": [ - { - "internalType": "uint256", - "name": "Index", - "type": "uint256" - } - ], - "stateMutability": "view", + "name": "createVotingContract", + "outputs": [], + "stateMutability": "payable", "type": "function" }, { @@ -106,22 +83,12 @@ "type": "uint256" } ], - "name": "candidates", + "name": "deployedContracts", "outputs": [ { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "uint128", - "name": "votes", - "type": "uint128" - }, - { - "internalType": "string", - "name": "zone", - "type": "string" + "internalType": "address", + "name": "", + "type": "address" } ], "stateMutability": "view", @@ -129,7 +96,7 @@ }, { "inputs": [], - "name": "getVotingStatus", + "name": "getStatus", "outputs": [ { "internalType": "bool", @@ -151,21 +118,29 @@ "internalType": "uint256", "name": "_durationInDays", "type": "uint256" - }, + } + ], + "name": "initiateVotingVF", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ { "internalType": "address", - "name": "_admin", + "name": "", "type": "address" } ], - "name": "initiateVoting", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "showResults", + "name": "showResultsVF", "outputs": [ { "components": [ @@ -193,32 +168,19 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_candidateIndex", - "type": "uint256" - } - ], - "name": "vote", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { "internalType": "address", - "name": "voteradr", + "name": "superadminadr", "type": "address" } ], - "name": "voters", + "name": "superadmins", "outputs": [ { "internalType": "bool", - "name": "isvoted", + "name": "issuperadmin", "type": "bool" } ], @@ -226,15 +188,39 @@ "type": "function" }, { - "inputs": [], - "name": "zone", - "outputs": [ + "inputs": [ + { + "internalType": "uint256", + "name": "_candidateIndex", + "type": "uint256" + }, + { + "internalType": "address", + "name": "voter", + "type": "address" + } + ], + "name": "voteVF", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "string", "name": "", "type": "string" } ], + "name": "zonesContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], "stateMutability": "view", "type": "function" } diff --git a/client/src/redux/authSlice.js b/client/src/redux/authSlice.js index 47239e7..44b5318 100644 --- a/client/src/redux/authSlice.js +++ b/client/src/redux/authSlice.js @@ -39,7 +39,8 @@ export const logout = createAsyncThunk("auth/logout", async () => { await axios.get("/api/logout"); sessionStorage.removeItem("user"); - + sessionStorage.removeItem("connected"); + sessionStorage.removeItem("address"); return null; }); export const login = createAsyncThunk("auth/login", async (user, thunkAPI) => { diff --git a/client/src/redux/walletSlice.js b/client/src/redux/walletSlice.js index 1ced831..0d484d9 100644 --- a/client/src/redux/walletSlice.js +++ b/client/src/redux/walletSlice.js @@ -5,32 +5,51 @@ import Web3 from 'web3'; import ABI from '../page/voting.json'; const initialState = { - web3: null, - contract: null, + web3Data: null, + contractAddress: null, // Store the contract address as a string connected: false, error: null, + initialized: false, + accountAddress: null, }; const walletSlice = createSlice({ name: 'wallet', initialState, reducers: { - setWeb3: (state, action) => { - state.web3 = action.payload; + setWeb3Data: (state, action) => { + // Store only the relevant properties from Web3 + state.web3Data = { + currentProvider: action.payload.currentProvider, // Store the provider URL + // Add other properties as needed + }; }, - setContract: (state, action) => { - state.contract = action.payload; + setAccountAddress: (state, action) => { + state.accountAddress = action.payload; + }, + setContractAddress: (state, action) => { + state.contractAddress = action.payload; // Store the contract address as a string }, setConnected: (state, action) => { state.connected = action.payload; }, + setInitialized: (state, action) => { + state.initialized = action.payload; + }, setError: (state, action) => { state.error = action.payload; }, }, }); -export const { setWeb3, setContract, setConnected, setError } = walletSlice.actions; +export const { + setWeb3Data, + setContractAddress, + setConnected, + setInitialized, + setAccountAddress, + setError, +} = walletSlice.actions; export const initWallet = () => async (dispatch) => { try { @@ -47,10 +66,19 @@ export const initWallet = () => async (dispatch) => { ABI, '0x0c8Bc9A045b36ba45798bCFCf7ca55ab8eeb88C6' ); - - dispatch(setWeb3(web3)); - dispatch(setContract(contract)); - dispatch(setConnected(true)); + sessionStorage.setItem("contract", JSON.stringify(contract)); + const web3Data = { + // Store the provider URL + currentProvider: web3.currentProvider.host, + // Add other properties as needed + }; + + dispatch(setWeb3Data(web3Data)); + // Store the contract address as a string + + dispatch(setContractAddress('0x0c8Bc9A045b36ba45798bCFCf7ca55ab8eeb88C6')); + + dispatch(setInitialized(true)); } catch (error) { console.error(error); dispatch(setError('An error occurred. Please try again.')); @@ -59,20 +87,23 @@ export const initWallet = () => async (dispatch) => { export const connectWallet = () => async (dispatch, getState) => { try { - if (window.ethereum !==undefined) { + if (window.ethereum !== undefined) { await window.ethereum.send('eth_requestAccounts'); const accounts = await window.ethereum.request({ method: 'eth_accounts' }); - const state = getState(); if (accounts && accounts.length > 0) { + const accountAddress = accounts[0]; dispatch(setConnected(true)); dispatch(setError(null)); - state.wallet.web3.setAccount(accounts[0]); + dispatch(setAccountAddress(accountAddress)); + sessionStorage.setItem("address", JSON.stringify(accountAddress)); + sessionStorage.setItem("connected",true) + console.log(accountAddress) } } else { dispatch(setError('MetaMask is not installed or unavailable.')); - } + } catch (error) { console.error('MetaMask connection error:', error); dispatch(setError('An error occurred while connecting to MetaMask.')); @@ -81,6 +112,5 @@ export const connectWallet = () => async (dispatch, getState) => { export const selectConnected = (state) => state.wallet.connected; export const selectError = (state) => state.wallet.error; - - +export const selectAccount = (state) => state.wallet.accountAddress; export default walletSlice.reducer; diff --git a/server/controllers/userController.js b/server/controllers/userController.js index 683fdfa..343d5c9 100644 --- a/server/controllers/userController.js +++ b/server/controllers/userController.js @@ -9,8 +9,7 @@ export const getUsers = async (req, res, next) => { if (searchQuery) { query = { $or: [ - { firstName: { $regex: new RegExp(searchQuery, "i") } }, - { lastName: { $regex: new RegExp(searchQuery, "i") } }, + { fullName: { $regex: new RegExp(searchQuery, "i") } }, { email: { $regex: new RegExp(searchQuery, "i") } }, ], }; @@ -57,8 +56,8 @@ export const makeAdmin = async (req, res, next) => { export const registerUser = async (req, res, next) => { try { - const { firstName, lastName, email, password, phoneNumber } = req.body; - if (!firstName || !lastName || !email || !password || !phoneNumber) + const { fullName, email, password, phoneNumber } = req.body; + if (!fullName || !email || !password || !phoneNumber) return res.status(400).send("All input fields are required"); const hashedPassword = hashPassword(password); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; @@ -72,8 +71,7 @@ export const registerUser = async (req, res, next) => { res.status(400).json({ error: "User already exists!" }); } else { const user = await User.create({ - firstName, - lastName, + fullName, email: email.toLowerCase(), password: hashedPassword, phoneNumber, @@ -83,8 +81,7 @@ export const registerUser = async (req, res, next) => { "access_token", generateAuthToken( user._id, - user.firstName, - user.lastName, + user.fullName, user.email, user.isAdmin, user.isSuperAdmin @@ -98,8 +95,7 @@ export const registerUser = async (req, res, next) => { .status(201) .json({ _id: user._id, - firstName: user.firstName, - lastName: user.lastName, + fullName: user.fullName, email: user.email, isAdmin: user.isAdmin, isSuperAdmin: user.isSuperAdmin, @@ -158,8 +154,7 @@ export const loginUser = async (req, res, next) => { "access_token", generateAuthToken( user._id, - user.firstName, - user.lastName, + user.fullName, user.email, user.isAdmin, user.isSuperAdmin @@ -169,8 +164,7 @@ export const loginUser = async (req, res, next) => { .status(200) .json({ _id: user._id, - firstName: user.firstName, - lastName: user.lastName, + fullName: user.fullName, email: user.email, isAdmin: user.isAdmin, isSuperAdmin: user.isSuperAdmin, diff --git a/server/models/UserModel.js b/server/models/UserModel.js index bed5311..e9c37ab 100644 --- a/server/models/UserModel.js +++ b/server/models/UserModel.js @@ -2,11 +2,7 @@ import mongoose from "mongoose"; const userSchema = new mongoose.Schema( { - firstName: { - type: String, - required: true, - }, - lastName: { + fullName: { type: String, required: true, }, diff --git a/server/utils/generateAuthToken.js b/server/utils/generateAuthToken.js index 612d624..93c68d9 100644 --- a/server/utils/generateAuthToken.js +++ b/server/utils/generateAuthToken.js @@ -1,8 +1,8 @@ import jwt from "jsonwebtoken"; -const generateAuthToken = (_id, firstName, lastName, email, isAdmin,isSuperAdmin) => { +const generateAuthToken = (_id, fullName, email, isAdmin,isSuperAdmin) => { return jwt.sign( - { _id, firstName, lastName, email, isAdmin,isSuperAdmin }, + { _id, fullName, email, isAdmin,isSuperAdmin }, process.env.JWT_SECRET_KEY, { expiresIn: "1d" } );