Skip to content

Conversation

@charuljain02
Copy link

@charuljain02 charuljain02 commented Dec 26, 2025

Description

This PR adds a new Explorer page and links it from the Navbar. It also sets up routing so users can navigate to the Explorer page from the main interface.

Fixes #176

Type of change

Please mark the options that are relevant.

  • Updated UI/UX
  • Improved the business logic of code
  • Added new feature
  • Other

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings

Summary by CodeRabbit

  • New Features

    • Added Explorer page (placeholder) accessible from the app menu.
    • Terms & Conditions acceptance required when adding candidates.
    • Loading indicator shown while creating a voting process.
  • Bug Fixes

    • Improved validation for voting process creation (requires ≥2 proposals).
    • Enhanced error handling and user feedback on submission failures.
  • UI/UX

    • Explorer link added to navigation menu; clearer loading states and disabled buttons.
  • Chores

    • Minor formatting (end-of-file newline) fixes.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 26, 2025

Warning

Rate limit exceeded

@charuljain02 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 56 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between b0d7a1f and 97e314a.

📒 Files selected for processing (3)
  • anonymousVoting/clientAnonymousVoting/src/components/CreateProcessPage.js
  • anonymousVoting/clientAnonymousVoting/src/components/Explorer.js
  • anonymousVoting/clientAnonymousVoting/src/components/Navbar.js
📝 Walkthrough

Walkthrough

Adds an Explorer page and navbar link, creates a new /explorer route, refactors CreateProcessPage form/async handling, adds a terms-acceptance flow to AddCandidateModal, and applies only end-of-file formatting in ConnectWallet.js.

Changes

Cohort / File(s) Summary
Explorer feature
anonymousVoting/clientAnonymousVoting/src/App.js, anonymousVoting/clientAnonymousVoting/src/components/Explorer.js, anonymousVoting/clientAnonymousVoting/src/components/Navbar.js
New Explorer component and /explorer route added; navbar updated to include an Explorer link/icon alongside settings and logout UI.
Process creation refactor
anonymousVoting/clientAnonymousVoting/src/components/CreateProcessPage.js
Removed unused web3 imports, changed createProcess to validate up-front and use try/catch/finally with pending state, updated isFormValid to require ≥2 comma-separated proposals, and added spinner/disabled state to submit button.
Candidate modal: terms flow
anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js
Added acceptedTerms state and checkbox; submission now requires acceptance, encodes candidate name as UTF‑8 bytes and awaits transaction; modal resets terms on close and disables Confirm until accepted.
Formatting only
anonymousVoting/clientAnonymousVoting/src/components/ConnectWallet.js
Only end-of-file newline/formatting change; no functional edits.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped a route to /explorer today,
A tiny page to show the way,
Forms now wait and spinners hum,
Candidates agree before they come,
I nibble code and bound away. ✨

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning PR implements basic Explorer routing and navbar link but does not fulfill core feature requirements like table/list display, search, filters, pagination, or on-chain links. Complete implementation of Explorer page with voting events list, search/filter controls, pagination, and on-chain links as specified in issue #176.
Out of Scope Changes check ⚠️ Warning PR includes out-of-scope changes: AddCandidateModal now requires terms acceptance, and CreateProcessPage was refactored with validation and error handling improvements unrelated to explorer feature. Move AddCandidateModal and CreateProcessPage changes to separate PRs focused on their respective features, keeping this PR focused solely on Explorer page and navbar integration.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Feature/add explorer navbar' is vague and generic, using branch-naming conventions rather than clear change description. Revise title to clearly describe the main change, e.g., 'Add Explorer page with navbar navigation' or 'Create Explorer component and add to navigation'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (4)
anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js (4)

4-4: Remove unused import.

The ElectionOrganiser import is not used anywhere in this file.

🔎 Proposed fix
-import ElectionOrganiser from "../../build/ElectionOrganizer.json";

33-35: Use consistent error handling utility.

The terms validation uses toast.error() directly while the rest of the component uses the dangertoast() utility. This creates inconsistency in error handling patterns.

🔎 Proposed fix
     // ✅ ADDED: enforce terms acceptance
     if (!acceptedTerms) {
-        toast.error("You must accept the Terms & Conditions");
+        dangertoast(null, "You must accept the Terms & Conditions");
         return;
     }

56-60: Reset all form state when closing modal.

Currently only acceptedTerms is reset when the modal closes, but candidateDetail retains its values. This means the form will show previously entered data when the modal is reopened.

🔎 Proposed fix
 const closeModal = e => {
     e.preventDefault();
     setIsOpen(false);
     setAcceptedTerms(false); // ✅ reset
+    setCandidateDetail({ name: '', description: '' });
 };

32-36: Consider on-chain enforcement of terms acceptance.

The terms acceptance validation is currently enforced only in the UI. Users could bypass this requirement by interacting directly with the smart contract. If terms acceptance is legally or operationally critical, consider whether it should also be enforced at the smart contract level.

Also applies to: 122-132, 142-142

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d3a4dd and 0edf12d.

⛔ Files ignored due to path filters (2)
  • anonymousVoting/clientAnonymousVoting/public/assets/explorer.png is excluded by !**/*.png
  • anonymousVoting/clientAnonymousVoting/public/assets/image.png is excluded by !**/*.png
📒 Files selected for processing (6)
  • anonymousVoting/clientAnonymousVoting/src/App.js
  • anonymousVoting/clientAnonymousVoting/src/components/ConnectWallet.js
  • anonymousVoting/clientAnonymousVoting/src/components/CreateProcessPage.js
  • anonymousVoting/clientAnonymousVoting/src/components/Explorer.js
  • anonymousVoting/clientAnonymousVoting/src/components/Navbar.js
  • anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js
🔇 Additional comments (4)
anonymousVoting/clientAnonymousVoting/src/App.js (1)

2-2: LGTM!

The Explorer component is correctly imported and routed at /explorer. The implementation aligns with the PR objectives to add a dedicated Explorer page accessible from the navbar.

Also applies to: 35-35

anonymousVoting/clientAnonymousVoting/src/components/CreateProcessPage.js (3)

8-9: LGTM!

Good cleanup of unused imports. Removing useRef and unused contract functions simplifies the code.


32-61: Excellent refactoring of error handling and state management.

The upfront validation and structured try/catch/finally block properly handle the deployment flow. The pending state is now correctly reset in all cases.

Verify that upstream error handling in deployVotingProcess is robust and that user-facing error messages are sufficiently informative.


114-131: LGTM!

The pending state implementation with spinner provides clear visual feedback during transaction processing. The button is correctly disabled while pending to prevent duplicate submissions.


const handleSubmitCandidate = async (e) => {
let id ;
let id;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix undefined variable usage in error handler.

The variable id is declared on line 29 but never assigned a value. It will be undefined when passed to dangertoast on line 51, which may cause incorrect toast behavior.

🔎 Proposed fix

Either remove the id variable entirely if dangertoast can handle it, or assign it properly:

 const handleSubmitCandidate = async (e) => {
-    let id;
     e.preventDefault();

And update the error handler:

     } catch (err) {
-        dangertoast(id, "Candidate Addition Failed");
+        dangertoast(null, "Candidate Addition Failed");
         console.log(err);
     }

Also applies to: 51-51

🤖 Prompt for AI Agents
In
anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js
around line 29 (and error use at line 51), the local variable `id` is declared
but never assigned so it will be undefined when passed to `dangertoast`; either
remove the unused `id` variable and call `dangertoast` with only the message (or
with a valid fallback), or assign `id` an appropriate value before the error
handler runs (for example a generated unique id or an existing candidate/form
id) and then pass that defined value into `dangertoast`; update the error
handler to not rely on an undefined `id` (use a fallback or omit the parameter)
so the toast behaves correctly.

Comment on lines 38 to +44
try {


let tx = await addProposal(electionId,ethers.utils.toUtf8Bytes(candidateDetail.name.trim()));

await tx.wait();
console.log(tx);
// successtoast(id, "Candidate Added Successfully")


} catch(err) {
dangertoast(id ,"Candidate Addition Failed")
let tx = await addProposal(
electionId,
ethers.utils.toUtf8Bytes(candidateDetail.name.trim())
);

await tx.wait();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Validate candidate name is not empty after trimming.

The code trims the candidate name but doesn't validate that it's non-empty before submission. Users could submit candidates with only whitespace characters, resulting in empty names.

🔎 Proposed fix
     // ✅ ADDED: enforce terms acceptance
     if (!acceptedTerms) {
         toast.error("You must accept the Terms & Conditions");
         return;
     }
+
+    // Validate candidate name is not empty
+    if (!candidateDetail.name.trim()) {
+        toast.error("Candidate name is required");
+        return;
+    }

     try {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
let tx = await addProposal(electionId,ethers.utils.toUtf8Bytes(candidateDetail.name.trim()));
await tx.wait();
console.log(tx);
// successtoast(id, "Candidate Added Successfully")
} catch(err) {
dangertoast(id ,"Candidate Addition Failed")
let tx = await addProposal(
electionId,
ethers.utils.toUtf8Bytes(candidateDetail.name.trim())
);
await tx.wait();
// ✅ ADDED: enforce terms acceptance
if (!acceptedTerms) {
toast.error("You must accept the Terms & Conditions");
return;
}
// Validate candidate name is not empty
if (!candidateDetail.name.trim()) {
toast.error("Candidate name is required");
return;
}
try {
let tx = await addProposal(
electionId,
ethers.utils.toUtf8Bytes(candidateDetail.name.trim())
);
await tx.wait();
🤖 Prompt for AI Agents
In
anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js
around lines 38 to 44, the code trims the candidate name but doesn't check that
the trimmed value is non-empty before calling addProposal; update the handler to
compute const name = candidateDetail.name?.trim() and if (!name) abort the
submission: show a user-facing validation error (set component state or call the
existing error/toast mechanism) and return early so addProposal is not called;
only pass the validated non-empty name to ethers.utils.toUtf8Bytes and proceed
with the transaction when valid.

Comment on lines +47 to +49
// successtoast(id, "Candidate Added Successfully")
setIsOpen(false);
setAcceptedTerms(false);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Restore success feedback and reset form state.

The success toast on line 47 is commented out, leaving users without confirmation that their candidate was added successfully. Additionally, candidateDetail state is not reset after successful submission, so the form will display previous values when reopened.

🔎 Proposed fix
     await tx.wait();
     console.log(tx);

-    // successtoast(id, "Candidate Added Successfully")
+    successtoast(null, "Candidate Added Successfully");
     setIsOpen(false);
     setAcceptedTerms(false);
+    setCandidateDetail({ name: '', description: '' });
 } catch (err) {
🤖 Prompt for AI Agents
In
anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js
around lines 47 to 49, restore the success feedback and clear form state after a
successful submission: re-enable the success toast call (successtoast or the
app's toast utility) so users receive confirmation, and reset the
candidateDetail state to its initial empty/default values (and any other form
fields) before closing the modal; keep setAcceptedTerms(false) as is and ensure
the toast is called before setIsOpen(false) so the message is visible.

<br />

<div>
<b>Canidate Name</b>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in user-facing labels.

"Canidate" is misspelled on lines 93 and 106. It should be "Candidate".

🔎 Proposed fix
-<b>Canidate Name</b>
+<b>Candidate Name</b>
-<b>Canidate Description</b>
+<b>Candidate Description</b>

Also applies to: 106-106

🤖 Prompt for AI Agents
In
anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js
around lines 93 and 106, there are misspelled user-facing labels ("Canidate") —
change both occurrences to "Candidate" in the rendered text (and any related
aria-labels or test IDs if they use the same string) so the UI displays the
correct spelling.

Comment on lines 109 to +117
<textarea
className="form-control"
className="form-control"
placeholder="Name of the candidate"
name="description"
rows={6}
value={candidateDetail.description}
onChange={handleCandidateDetailChange}
style={{marginTop: "15px"}}
/>
style={{ marginTop: "15px" }}
/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Correct placeholder text for description field.

The placeholder text on line 111 says "Name of the candidate" but this field is for the candidate's description.

🔎 Proposed fix
 <textarea
     className="form-control"
-    placeholder="Name of the candidate"
+    placeholder="Description of the candidate"
     name="description"
     rows={6}
     value={candidateDetail.description}
     onChange={handleCandidateDetailChange}
     style={{ marginTop: "15px" }}
 />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<textarea
className="form-control"
className="form-control"
placeholder="Name of the candidate"
name="description"
rows={6}
value={candidateDetail.description}
onChange={handleCandidateDetailChange}
style={{marginTop: "15px"}}
/>
style={{ marginTop: "15px" }}
/>
<textarea
className="form-control"
placeholder="Description of the candidate"
name="description"
rows={6}
value={candidateDetail.description}
onChange={handleCandidateDetailChange}
style={{ marginTop: "15px" }}
/>
🤖 Prompt for AI Agents
In
anonymousVoting/clientAnonymousVoting/src/components/modals/AddCandidateModal.js
around lines 109 to 117, the textarea's placeholder incorrectly reads "Name of
the candidate" but this field holds the candidate's description; update the
placeholder to something appropriate (e.g., "Description of the candidate" or
"Candidate description"), and keep the rest of the props unchanged so the value
and onChange continue to work as expected.

Comment on lines 16 to 37
<img
src="/assets/settings.png"
className="navbarMenuIcon navbarMenuLeft"
alt="settings"
/>

<Link to="/explorer">
<img
src="/assets/explorer.png"
className="navbarMenuIcon"
alt="explorer"
/>
</Link>

<Link to="/">
<img
src="/assets/logout.png"
className="navbarMenuIcon"
alt="logout"
/>
</Link>
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for explorer.png in common asset locations
fd -t f "explorer.png" anonymousVoting/clientAnonymousVoting/public anonymousVoting/clientAnonymousVoting/src

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 135


🏁 Script executed:

# Also check the directory structure of assets
ls -la anonymousVoting/clientAnonymousVoting/public/assets/ 2>/dev/null || echo "Assets directory structure not found, checking alternative locations"
find anonymousVoting/clientAnonymousVoting -type d -name "assets" -o -name "public" 2>/dev/null | head -20

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 1683


🏁 Script executed:

# Read the full Navbar.js file to understand logout behavior
cat -n anonymousVoting/clientAnonymousVoting/src/components/Navbar.js

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 1439


🏁 Script executed:

# Search for logout handlers and auth context
rg -i "logout|disconnectWallet|clearAuth" anonymousVoting/clientAnonymousVoting/src --type js --type jsx -B 2 -A 5

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 98


🏁 Script executed:

# Check for context providers and auth state management
fd -t f "\.js$|\.jsx$" anonymousVoting/clientAnonymousVoting/src | xargs grep -l "Context\|useContext\|provider" | head -10

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 721


🏁 Script executed:

# Check the settings icon - see if it has any handler in parent or if it's a separate component
rg "settings\.png" anonymousVoting/clientAnonymousVoting/src -B 5 -A 5

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 1005


🏁 Script executed:

# Search for logout logic without file type filter
rg -i "logout|disconnect.*wallet|clear.*auth|signOut" anonymousVoting/clientAnonymousVoting/src -B 2 -A 5

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 880


🏁 Script executed:

# Check how Navbar is used in parent components
rg "Navbar" anonymousVoting/clientAnonymousVoting/src -B 2 -A 2

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 3507


🏁 Script executed:

# Check the Dashboard or main App component for logout handling
cat -n anonymousVoting/clientAnonymousVoting/src/components/Dashboard.js | head -100

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 3659


🏁 Script executed:

# Check if there's any logout or disconnect logic in Dashboard
rg -i "navigate|useNavigate|history" anonymousVoting/clientAnonymousVoting/src/components/Dashboard.js

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 53


🏁 Script executed:

# Check App.js for routing and logout
cat -n anonymousVoting/clientAnonymousVookie/src/App.js | head -80

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 151


🏁 Script executed:

# Search for wallet provider/context to see if there's disconnect logic
rg -i "provider|context|wallet" anonymousVoting/clientAnonymousVoting/src --max-count 20

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 7321


🏁 Script executed:

# Check if there's a ConnectWallet component that might handle disconnection
cat -n anonymousVoting/clientAnonymousVoting/src/components/ConnectWallet.js

Repository: AOSSIE-Org/Agora-Blockchain

Length of output: 4981


Replace the empty explorer.png file with actual icon content.

The /assets/explorer.png file exists but is empty (0 bytes) and will not render. Additionally, the logout link navigates to "/" without performing any logout action such as clearing authentication state or disconnecting the wallet. If logout behavior is intended to be functional, add appropriate state cleanup and wallet disconnection logic; otherwise, the logout link is non-functional as currently implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: 🧭 Feature Request: Add Explorer Page to Navbar

1 participant