CIA/e-voting-system/frontend/FRONTEND_NEXTJS_GUIDE.md

12 KiB

E-Voting Frontend - Next.js + ShadCN/UI Guide

Overview

The E-Voting frontend has been completely rebuilt using Next.js 15 and shadcn/ui components. This provides a modern, type-safe, and fully responsive user interface for the e-voting platform.

Key Technologies

  • Framework: Next.js 15 with App Router
  • UI Components: shadcn/ui (Radix UI + Tailwind CSS)
  • Styling: Tailwind CSS with custom dark theme
  • Language: TypeScript with strict type checking
  • Icons: Lucide React
  • Forms: React Hook Form (ready for integration)

Project Structure

frontend/
├── app/                          # Next.js App Router pages
│   ├── layout.tsx               # Root layout with metadata
│   ├── page.tsx                 # Home page (landing)
│   ├── globals.css              # Global styles and CSS variables
│   ├── auth/
│   │   ├── login/page.tsx       # Login page
│   │   └── register/page.tsx    # Registration page
│   └── dashboard/
│       ├── layout.tsx           # Dashboard layout with sidebar
│       ├── page.tsx             # Dashboard home
│       ├── profile/page.tsx     # User profile management
│       └── votes/
│           ├── active/page.tsx       # Active votes
│           ├── upcoming/page.tsx     # Upcoming votes
│           ├── history/page.tsx      # Vote history
│           └── archives/page.tsx     # Archived votes
├── components/
│   └── ui/                       # Reusable UI components
│       ├── button.tsx           # Button component with variants
│       ├── card.tsx             # Card component with subcomponents
│       ├── input.tsx            # Input field component
│       ├── label.tsx            # Label component
│       └── index.ts             # Component exports
├── lib/
│   └── utils.ts                 # Utility functions (cn helper)
├── public/                       # Static assets
├── styles/                       # Additional stylesheets
├── package.json                 # Dependencies and scripts
├── tsconfig.json               # TypeScript configuration
├── tailwind.config.ts          # Tailwind CSS configuration
├── next.config.js              # Next.js configuration
└── postcss.config.js           # PostCSS configuration

Running the Project

Development

cd frontend
npm install
npm run dev

The application will be available at http://localhost:3000.

Production Build

npm run build
npm start

Linting

npm run lint

Pages Overview

Public Pages

1. Home Page (/)

  • Hero section with call-to-action
  • Stats section (1000+ voters, 50+ elections, 99.9% security)
  • Features section highlighting key benefits
  • Navigation to login/register
  • Responsive design for mobile

2. Login Page (/auth/login)

  • Email and password input fields
  • Error display with icons
  • Loading state during submission
  • Link to registration page
  • Feature highlights illustration

3. Register Page (/auth/register)

  • First name, last name, email, password fields
  • Password confirmation validation
  • Success/error state handling
  • Feature highlights on form side

Protected Pages (Dashboard)

4. Dashboard Home (/dashboard)

  • Welcome section with user name
  • Stats cards (active votes, upcoming, past, archives)
  • Active votes carousel
  • Quick action buttons
  • Responsive grid layout

5. Active Votes (/dashboard/votes/active)

  • List of ongoing elections
  • Progress bars showing participation
  • Vote count and candidate information
  • Filter by category (National, Local, Regional)
  • "Participate" button for each vote

6. Upcoming Votes (/dashboard/votes/upcoming)

  • Timeline view of future elections
  • Importance indicators (color-coded)
  • Start date and time for each vote
  • "Notify me" button for reminders
  • Category and importance filtering

7. Vote History (/dashboard/votes/history)

  • Past elections with results
  • Participation indicator (checkmark if voted)
  • Stats: total voted, participation rate
  • Results preview (winner and participation %)
  • Filterable by participation status

8. Archives (/dashboard/votes/archives)

  • Historical elections organized by year
  • Document count per election
  • Download and consult options
  • Year filtering
  • Grid layout for browsing

9. Profile Page (/dashboard/profile)

  • Personal information form
  • Address and contact details
  • Password change section
  • Two-factor authentication status
  • Session management
  • Account deletion option

Design System

Color Palette

The custom dark theme uses CSS variables defined in app/globals.css:

--background: 23 23 23 (rgb(23, 23, 23))
--foreground: 224 224 224 (rgb(224, 224, 224))
--primary: 232 112 75 (rgb(232, 112, 75)) [Accent]
--secondary: 163 163 163
--muted: 115 115 115
--border: 82 82 82
--input: 82 82 82
--card: 39 39 39

Component Patterns

Button Component

import { Button } from "@/components/ui/button"

// Default variant
<Button>Submit</Button>

// Outline variant
<Button variant="outline">Cancel</Button>

// Destructive variant
<Button variant="destructive">Delete</Button>

// Ghost variant (no background)
<Button variant="ghost">Link</Button>

// Sizes
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>

Card Component

import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card"

<Card>
  <CardHeader>
    <CardTitle>Title</CardTitle>
    <CardDescription>Description</CardDescription>
  </CardHeader>
  <CardContent>
    {/* Content */}
  </CardContent>
</Card>

Input Component

import { Input } from "@/components/ui/input"

<Input
  type="email"
  placeholder="Enter email"
  value={value}
  onChange={handleChange}
/>

Label Component

import { Label } from "@/components/ui/label"

<Label htmlFor="email">Email Address</Label>
<Input id="email" type="email" />

State Management

Currently, all state is managed with React hooks (useState). For more complex state management, consider:

  • Context API for global state (authentication, user preferences)
  • TanStack Query for server state (API calls, caching)
  • Zustand for client state (if scaling up)

Styling Guide

Using Tailwind Classes

All styling uses Tailwind CSS utility classes. Custom CSS is avoided.

<div className="flex items-center justify-between p-4 rounded-lg bg-card border border-border hover:border-accent transition-colors">
  <span className="text-sm font-medium text-foreground">Label</span>
  <button className="text-accent hover:text-accent/80 transition-colors">Action</button>
</div>

Responsive Design

Use Tailwind's responsive prefixes:

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
  {/* Responsive grid */}
</div>

Adding New Pages

Create a new page

  1. Create a new file in app/[section]/[page]/page.tsx
  2. Make it a "use client" component if it needs interactivity
  3. Use existing components from components/ui/
  4. Follow the naming conventions and styling patterns

Example:

"use client"

import { Button } from "@/components/ui/button"
import { Card, CardHeader, CardTitle } from "@/components/ui/card"

export default function NewPage() {
  return (
    <div className="space-y-8">
      <h1 className="text-3xl font-bold">New Page Title</h1>

      <Card>
        <CardHeader>
          <CardTitle>Card Title</CardTitle>
        </CardHeader>
      </Card>

      <Button>Action</Button>
    </div>
  )
}

Adding New Components

Create a new UI component

  1. Create components/ui/component-name.tsx
  2. Export from components/ui/index.ts
  3. Use Radix UI primitives as base if available
  4. Style with Tailwind CSS
  5. Include proper TypeScript types

Example:

import React from "react"

export interface CustomButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: "default" | "outline"
  size?: "sm" | "md" | "lg"
}

export const CustomButton = React.forwardRef<HTMLButtonElement, CustomButtonProps>(
  ({ className, variant = "default", size = "md", ...props }, ref) => {
    return (
      <button
        ref={ref}
        className={`px-4 py-2 rounded-lg font-medium transition-colors ${
          variant === "outline" ? "border border-border hover:bg-muted" : "bg-accent text-white hover:bg-accent/90"
        }`}
        {...props}
      />
    )
  }
)

CustomButton.displayName = "CustomButton"

Integration with Backend

The frontend is ready to integrate with the E-Voting backend API. Currently, API calls are commented out or return mock data.

API Endpoints to Connect

Authentication

  • POST /api/auth/register - User registration
  • POST /api/auth/login - User login
  • POST /api/auth/logout - User logout
  • POST /api/auth/refresh - Refresh authentication token

Votes

  • GET /api/votes/active - Get active votes
  • GET /api/votes/upcoming - Get upcoming votes
  • GET /api/votes/:id - Get vote details
  • POST /api/votes/:id/participate - Submit vote
  • GET /api/votes/history - Get vote history
  • GET /api/votes/archives - Get archived votes

User

  • GET /api/user/profile - Get user profile
  • PUT /api/user/profile - Update profile
  • PUT /api/user/password - Change password
  • GET /api/user/sessions - Get active sessions

Example API Integration

const [data, setData] = useState(null)
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)

useEffect(() => {
  const fetchData = async () => {
    setLoading(true)
    try {
      const response = await fetch("/api/votes/active")
      const result = await response.json()
      setData(result)
    } catch (err) {
      setError(err)
    } finally {
      setLoading(false)
    }
  }

  fetchData()
}, [])

Accessibility (a11y)

All components follow WCAG 2.1 guidelines:

  • Proper heading hierarchy
  • ARIA labels on form inputs
  • Keyboard navigation support
  • Color contrast ratios > 4.5:1
  • Focus indicators visible

Performance Optimization

  • Code Splitting: Next.js automatically splits code at route boundaries
  • Image Optimization: Use next/image for optimized images
  • Font Optimization: System fonts used by default (fast loading)
  • CSS-in-JS: Tailwind generates minimal CSS bundle

Current build size: ~117 kB First Load JS (shared by all pages)

Troubleshooting

Common Issues

Build fails with TypeScript errors:

npm run build -- --no-lint

Dependencies conflict:

npm install --legacy-peer-deps

Cache issues:

rm -rf .next node_modules
npm install
npm run build

Next Steps

  1. API Integration: Connect authentication and vote endpoints
  2. State Management: Implement user session management with Context
  3. Error Handling: Add error boundaries and error pages
  4. Loading States: Show skeleton screens during data fetching
  5. Validation: Implement form validation with Zod + React Hook Form
  6. Testing: Add unit tests with Jest and E2E tests with Cypress
  7. Analytics: Integrate analytics tracking
  8. PWA: Add PWA capabilities for offline support

Resources

Support

For questions or issues related to the frontend, refer to:

  • Commit history: git log --oneline
  • Recent changes: git diff main..UI
  • Build output: Check terminal after npm run build