Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"dev": "vite --host",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview",
Expand Down
14 changes: 8 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Route, Routes } from 'react-router';
import LoginPage from './pages/LoginPage';
import LoginPage from '@/pages/LoginPage';
import React from 'react';
import AuthContext from './context/AuthContext';
import connectToBlockchain from './config';
import AuthContext from '@/context/AuthContext';
import connectToBlockchain from '@/config';
import Layout from '@/pages/layout';
import CandidatePage from './pages/AddCandidatePage';
import CreateElection from './pages/CreateElection';
import CandidatePage from '@/pages/AddCandidatePage';
import CreateElection from '@/pages/CreateElection';
import HomePage from '@/pages/Home';

function App() {
const auth = React.useContext(AuthContext);
Expand All @@ -27,6 +28,7 @@ function App() {
let is_voter = true;

try {
console.log('admin', account);
is_admin = await contractInstance.isAdmin(account);
} catch (error) {
console.error('Error while fetching user data:', error);
Expand Down Expand Up @@ -60,7 +62,7 @@ function App() {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<div>home</div>} />
<Route path="/" element={<HomePage />} />
<Route path="/voter/add" element={<LoginPage />} />
<Route path="/elections/">
<Route path=":id" element={<div>election</div>} />
Expand Down
118 changes: 118 additions & 0 deletions src/components/shared/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { Link } from 'react-router';
import { Vote } from 'lucide-react';

export default function Footer() {
return (
<footer className="border-t bg-background">
<div className="container px-4 py-12 md:px-6">
<div className="grid gap-8 sm:grid-cols-2 md:grid-cols-4 lg:grid-cols-5">
<div className="sm:col-span-2 lg:col-span-2">
<Link to="/" className="mb-6 flex items-center gap-2">
<Vote className="h-6 w-6 text-primary" />
<span className="text-xl font-bold text-primary">VoteChain</span>
</Link>
<p className="mb-4 max-w-xs text-muted-foreground">
Secure, transparent, and tamper-proof voting powered by blockchain technology.
</p>
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Platform</h3>
<ul className="space-y-3 text-sm">
<li>
<Link to="/how-it-works" className="text-muted-foreground hover:text-foreground">
How It Works
</Link>
</li>
<li>
<Link
to="/active-elections"
className="text-muted-foreground hover:text-foreground"
>
Active Elections
</Link>
</li>
<li>
<Link
to="/upcoming-elections"
className="text-muted-foreground hover:text-foreground"
>
Upcoming Elections
</Link>
</li>
<li>
<Link to="/create-election" className="text-muted-foreground hover:text-foreground">
Create Election
</Link>
</li>
</ul>
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Resources</h3>
<ul className="space-y-3 text-sm">
<li>
<Link to="/docs" className="text-muted-foreground hover:text-foreground">
Documentation
</Link>
</li>
<li>
<Link to="/faq" className="text-muted-foreground hover:text-foreground">
FAQ
</Link>
</li>
<li>
<Link to="/security" className="text-muted-foreground hover:text-foreground">
Security
</Link>
</li>
<li>
<Link to="/blog" className="text-muted-foreground hover:text-foreground">
Blog
</Link>
</li>
</ul>
</div>
<div>
<h3 className="mb-4 text-sm font-medium">Company</h3>
<ul className="space-y-3 text-sm">
<li>
<Link to="/about" className="text-muted-foreground hover:text-foreground">
About
</Link>
</li>
<li>
<Link to="/contact" className="text-muted-foreground hover:text-foreground">
Contact
</Link>
</li>
<li>
<Link to="/privacy" className="text-muted-foreground hover:text-foreground">
Privacy Policy
</Link>
</li>
<li>
<Link to="/terms" className="text-muted-foreground hover:text-foreground">
Terms of Service
</Link>
</li>
</ul>
</div>
</div>
<div className="mt-12 border-t pt-8">
<div className="flex flex-col items-center justify-between gap-4 sm:flex-row">
<p className="text-sm text-muted-foreground">
© {new Date().getFullYear()} VoteChain. All rights reserved.
</p>
<div className="flex items-center space-x-4">
<Link
to="https://github.com/E-VoteChain/VoteChain"
className="text-muted-foreground hover:text-foreground"
>
GitHub
</Link>
</div>
</div>
</div>
</div>
</footer>
);
}
2 changes: 2 additions & 0 deletions src/components/shared/election/create-election.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export function CreateElectionForm() {

if (state.instance !== null) {
const totalElections = await state.instance.methods.noOfElections().call();
console.log('instance', state.instance);
console.log('TotalElections', totalElections);
for (let i = 1; i <= totalElections; i++) {
const electionData = await state.instance.methods
.getElection(i)
Expand Down
75 changes: 75 additions & 0 deletions src/components/shared/how-it-works.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
export function HowItWorks() {
return (
<section className="py-16 md:py-20">
<div className="container px-4 md:px-6">
<div className="mx-auto mb-12 max-w-[800px] text-center">
<h2 className="mb-4 text-3xl font-bold tracking-tight sm:text-4xl">
How VoteChain Works
</h2>
<p className="text-lg text-muted-foreground">
Our blockchain voting platform ensures security, transparency, and ease of use at every
step.
</p>
</div>

<div className="relative mx-auto max-w-5xl">
<div className="absolute left-1/2 top-0 h-full w-1 -translate-x-1/2 bg-border md:block"></div>

<div className="space-y-12 md:space-y-24">
<div className="relative grid gap-8 md:grid-cols-2">
<div className="flex md:justify-end">
<div className="relative max-w-md md:text-right">
<h3 className="mb-2 text-xl font-bold">Create an Election</h3>
<p className="text-muted-foreground">
Set up your election with candidates, voting rules, and duration. Customize
authentication methods to ensure only eligible voters participate.
</p>
</div>
</div>
<div className="md:pt-16"></div>
</div>

<div className="relative grid gap-8 md:grid-cols-2">
<div className="md:pt-16"></div>
<div className="flex">
<div className="relative max-w-md">
<h3 className="mb-2 text-xl font-bold">Secure Voter Authentication</h3>
<p className="text-muted-foreground">
Voters verify their identity through secure methods like email verification,
wallet connection, or custom authentication systems.
</p>
</div>
</div>
</div>

<div className="relative grid gap-8 md:grid-cols-2">
<div className="flex md:justify-end">
<div className="relative max-w-md md:text-right">
<h3 className="mb-2 text-xl font-bold">Cast Secure Votes</h3>
<p className="text-muted-foreground">
Voters make their selections through an intuitive interface. Each vote is
encrypted and securely recorded on the blockchain.
</p>
</div>
</div>
<div className="md:pt-16"></div>
</div>

<div className="relative grid gap-8 md:grid-cols-2">
<div className="md:pt-16"></div>
<div className="flex">
<div className="relative max-w-md">
<h3 className="mb-2 text-xl font-bold">Transparent Results</h3>
<p className="text-muted-foreground">
Results are tallied automatically and can be independently verified through the
blockchain, ensuring complete transparency while maintaining voter privacy.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
127 changes: 127 additions & 0 deletions src/components/shared/recent-elections.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { Link } from 'react-router';
import { ArrowRight, Calendar, Vote } from 'lucide-react';

import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';

const recentElections = [
{
id: 1,
title: 'Community Board Election',
description: 'Vote for the new community board members',
status: 'active',
votes: 156,
candidates: 5,
endDate: '2023-12-15',
category: 'Community',
},
{
id: 2,
title: 'Student Council President',
description: 'Annual election for the student council president',
status: 'upcoming',
votes: 0,
candidates: 3,
endDate: '2023-12-10',
category: 'Education',
},
{
id: 3,
title: 'Tech Startup Board of Directors',
description: 'Elect the new board of directors',
status: 'active',
votes: 87,
candidates: 7,
endDate: '2024-01-05',
category: 'Corporate',
},
];

export function RecentElections() {
return (
<section className="py-16 md:py-20">
<div className="container px-4 md:px-6">
<div className="mb-10 flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
<div>
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl">Recent Elections</h2>
<p className="mt-2 text-muted-foreground">
Browse through active and upcoming elections on our platform.
</p>
</div>
<Button variant="outline" asChild>
<Link to="/active-elections">
View All Elections <ArrowRight className="ml-2 h-4 w-4" />
</Link>
</Button>
</div>

<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{recentElections.map((election) => (
<Card key={election.id} className="flex flex-col">
<CardHeader className="pb-4">
<div className="mb-2">
<Badge
variant="outline"
className={
election.status === 'active'
? 'bg-green-500/10 text-green-500'
: 'bg-primary/10 text-primary'
}
>
{election.status === 'active' ? 'Active' : 'Upcoming'}
</Badge>
<Badge variant="outline" className="ml-2 bg-secondary/10 text-secondary">
{election.category}
</Badge>
</div>
<CardTitle className="line-clamp-1">{election.title}</CardTitle>
<CardDescription className="line-clamp-2">{election.description}</CardDescription>
</CardHeader>
<CardContent className="flex-1">
<div className="grid grid-cols-2 gap-4 text-sm">
<div className="flex flex-col">
<span className="text-muted-foreground">Candidates</span>
<span className="font-medium">{election.candidates}</span>
</div>
<div className="flex flex-col">
<span className="text-muted-foreground">Votes Cast</span>
<span className="font-medium">{election.votes}</span>
</div>
<div className="col-span-2 flex flex-col">
<span className="text-muted-foreground">End Date</span>
<span className="font-medium">
{new Date(election.endDate).toLocaleDateString()}
</span>
</div>
</div>
</CardContent>
<CardFooter className="pt-4">
<Button className="w-full" asChild>
<Link to={`/elections/${election.id}`}>
{election.status === 'active' ? (
<>
<Vote className="mr-2 h-4 w-4" /> Cast Vote
</>
) : (
<>
<Calendar className="mr-2 h-4 w-4" /> View Details
</>
)}
</Link>
</Button>
</CardFooter>
</Card>
))}
</div>
</div>
</section>
);
}
Loading
Loading