diff --git a/client/app/components/Cards/BallotCards/ScoreBallot.tsx b/client/app/components/Cards/BallotCards/ScoreBallot.tsx index dbb3930d..d563afbb 100644 --- a/client/app/components/Cards/BallotCards/ScoreBallot.tsx +++ b/client/app/components/Cards/BallotCards/ScoreBallot.tsx @@ -41,9 +41,7 @@ const ScoreBallot = ({ const newSum = sumWithoutCurrent + credits; if (newSum > 100) { - toast.error("Credit Limit Exceeded !!"); - console.log("Error credits"); - return; + toast.error("Credit Limit Exceeded !!"); return; } newCreditScores[id] = credits; const sum = SumOfArray(newCreditScores); diff --git a/client/app/components/ChatBot/ChatBot.tsx b/client/app/components/ChatBot/ChatBot.tsx index 32bda8f6..414bc86a 100644 --- a/client/app/components/ChatBot/ChatBot.tsx +++ b/client/app/components/ChatBot/ChatBot.tsx @@ -4,6 +4,7 @@ import React, { useState, useRef, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { ArrowUpIcon, ChatBubbleLeftRightIcon } from "@heroicons/react/24/solid"; import { XMarkIcon } from "@heroicons/react/24/outline"; // Corrected the import for XMarkIcon +import toast from "react-hot-toast"; interface Message { content: string; @@ -49,7 +50,7 @@ const ChatBot: React.FC = () => { const reply: Message = { content: data.message, role: "assistant" }; setMessages((prevMessages) => [...prevMessages, reply]); } catch (error) { - console.error("Error:", error); + toast.error("Failed to get response. Please try again."); } }; diff --git a/client/app/components/Helper/CrossChain.tsx b/client/app/components/Helper/CrossChain.tsx index a73bdb9a..94f4765a 100644 --- a/client/app/components/Helper/CrossChain.tsx +++ b/client/app/components/Helper/CrossChain.tsx @@ -4,6 +4,9 @@ import React, { useEffect, useState } from "react"; import { erc20Abi } from "viem"; import { avalancheFuji } from "viem/chains"; import { useAccount, useSwitchChain, useWriteContract } from "wagmi"; +import logger from "@/app/helpers/logger"; +import toast from "react-hot-toast"; + const CrossChain = ({ electionAddress, isEnded, @@ -34,8 +37,9 @@ const CrossChain = ({ }); setbuttonValue(true); } catch (error) { - console.log("Error : ", error); - } + logger.error("CrossChain: failed to add election", error); + toast.error("Failed to enable cross-chain support. Please try again."); + } }; useEffect(() => { setbuttonValue(isCrossChainEnabled); diff --git a/client/app/components/Modal/AddCandidate.tsx b/client/app/components/Modal/AddCandidate.tsx index aa782fd0..46e0b981 100644 --- a/client/app/components/Modal/AddCandidate.tsx +++ b/client/app/components/Modal/AddCandidate.tsx @@ -14,6 +14,7 @@ import { ErrorMessage } from "../../helpers/ErrorMessage"; import { sepolia } from "viem/chains"; import { useElectionData } from "@/app/hooks/ElectionInfo"; import { pinJSONFile } from "@/app/helpers/pinToIPFS"; +import logger from "@/app/helpers/logger"; const AddCandidate = ({ openModal, @@ -51,8 +52,8 @@ const AddCandidate = ({ }); toast.success(`${name} Added to Election`); } catch (error) { - console.log("Error ", error); - toast.error(ErrorMessage(error)); + logger.error("AddCandidate: failed to add candidate", error); + toast.error(ErrorMessage(error)); } setopenModal(false); }; diff --git a/client/app/components/Modal/Vote.tsx b/client/app/components/Modal/Vote.tsx index feef369e..6c4c5c00 100644 --- a/client/app/components/Modal/Vote.tsx +++ b/client/app/components/Modal/Vote.tsx @@ -6,6 +6,7 @@ import { useElectionModal } from "@/app/hooks/ElectionModal"; import React, { useEffect } from "react"; import toast from "react-hot-toast"; import { useAccount, useWriteContract } from "wagmi"; +import logger from "@/app/helpers/logger"; const Vote = ({ disabled, @@ -20,7 +21,6 @@ const Vote = ({ const { writeContractAsync } = useWriteContract(); const { chain } = useAccount(); const vote = async () => { - console.log("Vote array", voteArray); try { if (chain?.id === 43113) { await writeContractAsync({ @@ -40,7 +40,7 @@ const Vote = ({ toast.success(`Voted Casted `); setelectionModal(false); } catch (error) { - console.log("Error", error); + logger.error("Vote: failed to cast vote", error); toast.error(ErrorMessage(error)); } }; diff --git a/client/app/create/page.tsx b/client/app/create/page.tsx index d8f62dad..9205e01b 100644 --- a/client/app/create/page.tsx +++ b/client/app/create/page.tsx @@ -13,6 +13,7 @@ import { sepolia } from "viem/chains"; import { ArrowPathIcon , PlusIcon, TrashIcon} from "@heroicons/react/24/solid"; import { useRouter } from "next/navigation"; import ElectionInfoPopup from "../components/Modal/ElectionInfoPopup"; +import logger from "@/app/helpers/logger"; const CreatePage: React.FC = () => { const router = useRouter(); @@ -93,7 +94,7 @@ const CreatePage: React.FC = () => { toast.success("Election created successfully!"); router.push("/"); } catch (error) { - console.error("Error creating election:", error); + logger.error("CreateElection: failed to create election", error); toast.error(ErrorMessage(error)); } }; diff --git a/client/app/helpers/ErrorMessage.ts b/client/app/helpers/ErrorMessage.ts index fd8131a1..328c5cfd 100644 --- a/client/app/helpers/ErrorMessage.ts +++ b/client/app/helpers/ErrorMessage.ts @@ -1,3 +1,5 @@ +import logger from "@/app/helpers/logger"; + const errorMessages = { ElectionInactive: "Election is Not Active", OwnerPermissioned: "Must be Owner of Election", @@ -13,7 +15,7 @@ const errorMessages = { }; export const ErrorMessage = (error: any) => { - console.log("Error : ", error); + logger.error("ErrorMessage helper received error", error); for (const [key, message] of Object.entries(errorMessages)) { if (error.message.includes(key)) { return message; diff --git a/client/app/helpers/fetchFileFromIPFS.ts b/client/app/helpers/fetchFileFromIPFS.ts index f0080a0b..5aa43981 100644 --- a/client/app/helpers/fetchFileFromIPFS.ts +++ b/client/app/helpers/fetchFileFromIPFS.ts @@ -1,3 +1,5 @@ +import logger from "@/app/helpers/logger"; + const GATEWAY = "orange-confused-boar-516.mypinata.cloud"; const JWT = process.env.NEXT_PUBLIC_PINATA_JWT; @@ -8,6 +10,6 @@ export async function fetchFileFromIPFS(CID: String) { const response = await request.json(); return response; } catch (error) { - console.log(error); + logger.error("fetchFileFromIPFS: failed to fetch file from IPFS", error); } } diff --git a/client/app/helpers/logger.ts b/client/app/helpers/logger.ts new file mode 100644 index 00000000..86d6b0d2 --- /dev/null +++ b/client/app/helpers/logger.ts @@ -0,0 +1,9 @@ +import log from "loglevel"; + +if (process.env.NODE_ENV === "production") { + log.setLevel("warn"); +} else { + log.setLevel("debug"); +} + +export default log; \ No newline at end of file diff --git a/client/app/helpers/pinToIPFS.ts b/client/app/helpers/pinToIPFS.ts index d1e48ffa..f0a4c8f4 100644 --- a/client/app/helpers/pinToIPFS.ts +++ b/client/app/helpers/pinToIPFS.ts @@ -1,3 +1,4 @@ +import logger from "@/app/helpers/logger"; const JWT = process.env.NEXT_PUBLIC_PINATA_JWT; export const pinJSONFile = async (body: any) => { @@ -16,10 +17,9 @@ export const pinJSONFile = async (body: any) => { options ); const data = await response.json(); - console.log(data); return data; } catch (err) { - console.error(err); + logger.error("pinJSONFile: failed to pin JSON to IPFS", err); throw err; // rethrow the error to be handled by the caller } }; @@ -33,7 +33,7 @@ export const unpinJSONFile = async (CID: String) => { try { await fetch(`https://api.pinata.cloud/pinning/unpin/${CID}`, options); } catch (err) { - console.error(err); + logger.error("unpinJSONFile: failed to unpin JSON from IPFS", err); throw err; // rethrow the error to be handled by the caller } }; diff --git a/client/package.json b/client/package.json index a3d924b1..0c53c0c6 100644 --- a/client/package.json +++ b/client/package.json @@ -20,6 +20,7 @@ "@vanilla-extract/sprinkles": "^1.6.3", "daisyui": "^4.12.10", "framer-motion": "^11.2.12", + "loglevel": "^1.9.2", "next": "14.2.4", "react": "^18", "react-dom": "^18",