Skip to content

Admin dashboard — ballot creation, voter upload, token issuance, and tally controls in one UI #35

Description

@Just-Bamford

Summary

Admins currently must make separate API calls to create a ballot,
upload the voter list, issue tokens, monitor voting, and trigger the
tally — there is no single interface for this workflow. An admin
managing multiple ballots has to switch between CLI, raw API calls,
or scattered frontend pages to complete a single election cycle. A
dedicated admin dashboard consolidates all ballot lifecycle operations
into one place, reducing friction and error-prone manual steps.

Background

The backend has all the necessary endpoints (POST /api/ballots,
POST /api/eligibility, POST /api/tokens, POST /api/ballots/:id/tally)
but the frontend only shows individual ballot views. There is no
dashboard that orchestrates the full workflow in sequence. Admins
cannot see at a glance how many ballots are active, which ones are
pending tally, or what token issuance status each ballot has.

Scope

Frontend

  • Create a new route /admin/dashboard that displays:
    • Active ballots table with columns: ballot title, voter count,
      tokens issued, votes received, deadline, status (open/closed)
    • Ability to click any ballot to open an inline panel showing:
      • Voter list upload interface (CSV file picker)
      • Token issuance button and progress indicator
      • Vote submission count (real-time or polling)
      • Tally button (only enabled if deadline passed)
      • Results link (only visible after tally)
  • Add a "Create Ballot" button that opens a modal with form fields:
    • Title, description, options (comma-separated or add/remove UI)
    • Deadline picker (datetime)
    • Initial voter list upload (optional)
  • After ballot creation, auto-focus the newly created ballot in the table
  • Add role-based access control — only admins can access /admin/dashboard
  • Display error messages if upload, token issuance, or tally fails

Backend

  • No new endpoints needed — use existing API
  • Consider adding a GET /api/admin/ballots endpoint that returns all
    ballots with aggregated status (tokens issued, votes received, tally status)
    to avoid multiple API calls for the dashboard

Tests

  • Dashboard loads and displays active ballots
  • Create ballot flow works end-to-end
  • Voter upload displays file picker and uploads correctly
  • Token issuance button shows progress
  • Vote count updates in real-time or on poll
  • Tally button only enabled after deadline
  • Non-admin users cannot access /admin/dashboard

Relevant Files

  • frontend/src/pages/AdminDashboard.tsx (new)
  • frontend/src/components/BallotCard.tsx (new)
  • frontend/src/components/VoterUploadPanel.tsx (new)
  • frontend/src/api/admin.ts (new or updated)
  • frontend/src/routes.ts
  • frontend/src/middleware/auth.ts (role check)

Acceptance Criteria

  • Admin dashboard displays all ballots with status columns
  • Ballot creation form works end-to-end
  • Voter upload, token issuance, and tally all accessible from dashboard
  • Real-time or polling vote count updates show progress
  • Tally button only enabled after deadline
  • Role-based access control prevents non-admins from accessing
  • No TypeScript warnings when npm run build completes
  • All tests pass

Out of Scope

  • Real-time WebSocket updates — polling only for now
  • Batch ballot creation — one at a time
  • Advanced analytics or charts — simple counts only

Note for Contributors

This is the main surface for admin users. Make it clear, fast, and
mistake-proof. The workflow should be: Create → Upload → Issue Tokens
→ Monitor Votes → Tally → View Results. Do not make admins navigate
away from this page to complete any step. Keep the inline panels
focused and responsive.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26enhancementNew feature or requestfrontendFrontend-related issuesuser-facingLabel: user-facing

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions