Skip to content

Commit af9d17a

Browse files
authored
Merge pull request #2 from BuidlGuidl/landingPage
Landing page
2 parents ea59a6d + 310257c commit af9d17a

File tree

6 files changed

+262
-110
lines changed

6 files changed

+262
-110
lines changed

packages/nextjs/app/_components/VotingOverview.tsx

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import ListVotings from "./ListVotings";
55
import OwnedVotings from "./OwnedVotings";
66
import ParticipatedVotings from "./ParticipatedVotings";
77

8-
const VotingOverview = () => {
8+
interface VotingOverviewProps {
9+
onCreateClick: () => void;
10+
}
11+
12+
const VotingOverview = ({ onCreateClick }: VotingOverviewProps) => {
913
const [activeTab, setActiveTab] = useState<"all" | "owned" | "participated">("owned");
1014

1115
const tabs = [
@@ -18,17 +22,34 @@ const VotingOverview = () => {
1822

1923
return (
2024
<div className="w-full space-y-6">
21-
<div className="tabs tabs-boxed w-fit">
22-
{tabs.map(tab => (
23-
<button
24-
key={tab.id}
25-
className={`tab text-xl font-medium ${activeTab === tab.id ? "tab-active" : ""}`}
26-
onClick={() => setActiveTab(tab.id)}
27-
style={{ fontSize: "2rem" }}
25+
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
26+
<div className="tabs tabs-boxed w-fit">
27+
{tabs.map(tab => (
28+
<button
29+
key={tab.id}
30+
className={`tab text-2xl font-medium ${activeTab === tab.id ? "tab-active" : ""}`}
31+
onClick={() => setActiveTab(tab.id)}
32+
>
33+
{tab.label}
34+
</button>
35+
))}
36+
</div>
37+
38+
<button
39+
className="btn btn-primary gap-2 shadow-lg hover:scale-105 transition-transform"
40+
onClick={onCreateClick}
41+
>
42+
<svg
43+
className="w-6 h-6"
44+
fill="none"
45+
stroke="currentColor"
46+
viewBox="0 0 24 24"
47+
xmlns="http://www.w3.org/2000/svg"
2848
>
29-
{tab.label}
30-
</button>
31-
))}
49+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
50+
</svg>
51+
Create Voting
52+
</button>
3253
</div>
3354

3455
<div className="w-full max-h-[calc(3*280px+2*1rem)] overflow-y-auto pr-2">

packages/nextjs/app/page.tsx

Lines changed: 192 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,220 @@
11
"use client";
22

3-
import { useState } from "react";
4-
import CreateVotingModal from "./_components/CreateVotingModal";
5-
import VotingOverview from "./_components/VotingOverview";
3+
import Link from "next/link";
64
import { NextPage } from "next";
75

8-
const Home: NextPage = () => {
9-
const [isModalOpen, setIsModalOpen] = useState(false);
10-
6+
const LandingPage: NextPage = () => {
117
return (
128
<div className="min-h-screen">
139
{/* Hero Section */}
14-
<div className="bg-base-200">
15-
<div className="max-w-6xl mx-auto px-8 py-12">
16-
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
17-
<div className="flex-1 space-y-4">
18-
<h1 className="text-5xl font-bold bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent mb-4 leading-tight pb-2">
10+
<div className="relative overflow-hidden bg-gradient-to-br from-base-100 via-base-200 to-base-300">
11+
<div className="absolute inset-0 bg-grid-pattern opacity-5"></div>
12+
<div className="relative max-w-6xl mx-auto px-8 py-20 md:py-32">
13+
<div className="text-center space-y-8">
14+
{/* Main Heading */}
15+
<h1 className="text-6xl md:text-7xl lg:text-8xl font-bold leading-tight">
16+
<span className="bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">
1917
Hidden Vote
20-
</h1>
21-
<p className="text-xl opacity-70 max-w-2xl">
22-
Host private voting sessions. Votes stay secret, results stay transparent.
18+
</span>
19+
</h1>
20+
21+
{/* Subtitle */}
22+
<p className="text-2xl md:text-3xl opacity-80 max-w-3xl mx-auto font-light">
23+
Private voting powered by Zero-Knowledge Proofs
24+
</p>
25+
26+
{/* Description */}
27+
<p className="text-lg md:text-xl opacity-70 max-w-2xl mx-auto">
28+
Create secure voting sessions where individual votes remain completely private while results stay
29+
verifiable and transparent on the blockchain.
30+
</p>
31+
32+
{/* CTA Button */}
33+
<div className="pt-8">
34+
<Link
35+
href="/votings"
36+
className="btn btn-primary btn-lg gap-2 shadow-2xl hover:scale-105 transition-transform"
37+
>
38+
<svg
39+
className="w-6 h-6"
40+
fill="none"
41+
stroke="currentColor"
42+
viewBox="0 0 24 24"
43+
xmlns="http://www.w3.org/2000/svg"
44+
>
45+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
46+
</svg>
47+
Launch App
48+
</Link>
49+
</div>
50+
</div>
51+
</div>
52+
</div>
53+
54+
{/* Features Section */}
55+
<div className="max-w-6xl mx-auto px-8 py-20">
56+
<h2 className="text-4xl md:text-5xl font-bold text-center mb-16">Why Hidden Vote?</h2>
57+
58+
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
59+
{/* Feature 1 */}
60+
<div className="card bg-base-200 shadow-xl hover:shadow-2xl transition-shadow">
61+
<div className="card-body items-center text-center space-y-4">
62+
<div className="w-16 h-16 rounded-full bg-blue-400/30 flex items-center justify-center">
63+
<svg
64+
className="w-8 h-8 text-blue-400"
65+
fill="none"
66+
stroke="currentColor"
67+
strokeWidth={2.5}
68+
viewBox="0 0 24 24"
69+
xmlns="http://www.w3.org/2000/svg"
70+
>
71+
<path
72+
strokeLinecap="round"
73+
strokeLinejoin="round"
74+
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
75+
/>
76+
</svg>
77+
</div>
78+
<h3 className="card-title text-2xl">Complete Privacy</h3>
79+
<p className="opacity-70">
80+
Your vote remains encrypted and anonymous. Zero-knowledge proofs ensure nobody can see how you voted.
2381
</p>
2482
</div>
25-
<div className="flex-shrink-0">
26-
<button className="btn btn-primary btn-lg gap-2 shadow-lg" onClick={() => setIsModalOpen(true)}>
83+
</div>
84+
85+
{/* Feature 2 */}
86+
<div className="card bg-base-200 shadow-xl hover:shadow-2xl transition-shadow">
87+
<div className="card-body items-center text-center space-y-4">
88+
<div className="w-16 h-16 rounded-full bg-purple-400/30 flex items-center justify-center">
2789
<svg
28-
className="w-6 h-6"
90+
className="w-8 h-8 text-purple-400"
2991
fill="none"
3092
stroke="currentColor"
93+
strokeWidth={2.5}
3194
viewBox="0 0 24 24"
3295
xmlns="http://www.w3.org/2000/svg"
3396
>
34-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
97+
<path
98+
strokeLinecap="round"
99+
strokeLinejoin="round"
100+
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
101+
/>
35102
</svg>
36-
Create Voting
37-
</button>
103+
</div>
104+
<h3 className="card-title text-2xl">Blockchain Verified</h3>
105+
<p className="opacity-70">
106+
All votes and results are cryptographically secured and permanently recorded on the blockchain.
107+
</p>
108+
</div>
109+
</div>
110+
111+
{/* Feature 3 */}
112+
<div className="card bg-base-200 shadow-xl hover:shadow-2xl transition-shadow">
113+
<div className="card-body items-center text-center space-y-4">
114+
<div className="w-16 h-16 rounded-full bg-pink-400/30 flex items-center justify-center">
115+
<svg
116+
className="w-8 h-8 text-pink-400"
117+
fill="none"
118+
stroke="currentColor"
119+
strokeWidth={2.5}
120+
viewBox="0 0 24 24"
121+
xmlns="http://www.w3.org/2000/svg"
122+
>
123+
<path strokeLinecap="round" strokeLinejoin="round" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" />
124+
</svg>
125+
</div>
126+
<h3 className="card-title text-2xl">Transparent Results</h3>
127+
<p className="opacity-70">
128+
Vote counts are publicly verifiable while maintaining individual voter anonymity.
129+
</p>
38130
</div>
39131
</div>
40132
</div>
41133
</div>
42134

43-
{/* Main Content */}
44-
<div className="max-w-6xl mx-auto px-8 py-12">
45-
<VotingOverview />
135+
{/* How It Works Section */}
136+
<div className="bg-base-200 py-20">
137+
<div className="max-w-6xl mx-auto px-8">
138+
<h2 className="text-4xl md:text-5xl font-bold text-center mb-16">How It Works</h2>
139+
140+
<div className="space-y-8">
141+
{/* Step 1 */}
142+
<div className="flex flex-col md:flex-row gap-6 items-center">
143+
<div className="flex-shrink-0 w-16 h-16 rounded-full bg-blue-400 text-white flex items-center justify-center text-2xl font-bold">
144+
1
145+
</div>
146+
<div className="flex-1">
147+
<h3 className="text-2xl font-bold mb-2">Create a Voting Session</h3>
148+
<p className="text-lg opacity-70">
149+
Set up your question with up to 16 choices, and configure registration and voting periods.
150+
</p>
151+
</div>
152+
</div>
153+
154+
{/* Step 2 */}
155+
<div className="flex flex-col md:flex-row gap-6 items-center">
156+
<div className="flex-shrink-0 w-16 h-16 rounded-full bg-purple-400 text-white flex items-center justify-center text-2xl font-bold">
157+
2
158+
</div>
159+
<div className="flex-1">
160+
<h3 className="text-2xl font-bold mb-2">Register to Vote</h3>
161+
<p className="text-lg opacity-70">
162+
During the registration period, eligible voters register to join the voting session. This builds the
163+
anonymity set that protects voter privacy when voting begins.
164+
</p>
165+
</div>
166+
</div>
167+
168+
{/* Step 3 */}
169+
<div className="flex flex-col md:flex-row gap-6 items-center">
170+
<div className="flex-shrink-0 w-16 h-16 rounded-full bg-pink-400 text-white flex items-center justify-center text-2xl font-bold">
171+
3
172+
</div>
173+
<div className="flex-1">
174+
<h3 className="text-2xl font-bold mb-2">Cast Your Vote</h3>
175+
<p className="text-lg opacity-70">
176+
Submit your encrypted vote during the voting period using zero-knowledge proofs to maintain privacy.
177+
</p>
178+
</div>
179+
</div>
180+
181+
{/* Step 4 */}
182+
<div className="flex flex-col md:flex-row gap-6 items-center">
183+
<div className="flex-shrink-0 w-16 h-16 rounded-full bg-purple-500 text-white flex items-center justify-center text-2xl font-bold">
184+
4
185+
</div>
186+
<div className="flex-1">
187+
<h3 className="text-2xl font-bold mb-2">View Results</h3>
188+
<p className="text-lg opacity-70">
189+
Once voting ends, results are tallied and publicly displayed while individual votes remain private.
190+
</p>
191+
</div>
192+
</div>
193+
</div>
194+
</div>
46195
</div>
47196

48-
<CreateVotingModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
197+
{/* CTA Section */}
198+
<div className="max-w-6xl mx-auto px-8 py-20 text-center">
199+
<h2 className="text-4xl md:text-5xl font-bold mb-8">Ready to Get Started?</h2>
200+
<p className="text-xl opacity-70 mb-12 max-w-2xl mx-auto">
201+
Experience the future of private, secure, and transparent voting on the blockchain.
202+
</p>
203+
<Link href="/votings" className="btn btn-primary btn-lg gap-2 shadow-2xl hover:scale-105 transition-transform">
204+
<svg
205+
className="w-6 h-6"
206+
fill="none"
207+
stroke="currentColor"
208+
viewBox="0 0 24 24"
209+
xmlns="http://www.w3.org/2000/svg"
210+
>
211+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
212+
</svg>
213+
Launch App
214+
</Link>
215+
</div>
49216
</div>
50217
);
51218
};
52219

53-
export default Home;
220+
export default LandingPage;

packages/nextjs/app/voting/[address]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export default function VotingByAddressPage() {
141141
return (
142142
<div className="flex items-center justify-center flex-col grow pt-6 w-full">
143143
<div className="px-4 sm:px-5 w-full max-w-7xl mx-auto">
144-
<Link href="/" className="btn btn-sm btn-ghost gap-2 mb-4">
144+
<Link href="/votings" className="btn btn-sm btn-ghost gap-2 mb-4">
145145
<svg
146146
xmlns="http://www.w3.org/2000/svg"
147147
fill="none"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import CreateVotingModal from "../_components/CreateVotingModal";
5+
import VotingOverview from "../_components/VotingOverview";
6+
import { NextPage } from "next";
7+
8+
const VotingsPage: NextPage = () => {
9+
const [isModalOpen, setIsModalOpen] = useState(false);
10+
11+
return (
12+
<div className="min-h-screen">
13+
{/* Main Content */}
14+
<div className="max-w-6xl mx-auto px-8 py-12">
15+
<VotingOverview onCreateClick={() => setIsModalOpen(true)} />
16+
</div>
17+
18+
<CreateVotingModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
19+
</div>
20+
);
21+
};
22+
23+
export default VotingsPage;

0 commit comments

Comments
 (0)