diff --git a/client/app/components/Header/Header.tsx b/client/app/components/Header/Header.tsx index ef15d94..589d42a 100644 --- a/client/app/components/Header/Header.tsx +++ b/client/app/components/Header/Header.tsx @@ -10,6 +10,7 @@ import { HomeIcon, XMarkIcon, Bars3Icon, + CodeBracketIcon, } from "@heroicons/react/24/outline"; import Web3Connect from "../Helper/Web3Connect"; import Image from "next/image"; @@ -17,6 +18,7 @@ import Image from "next/image"; const menuItems = [ { name: "Home", href: "/", icon: HomeIcon }, { name: "Create", href: "/create", icon: PlusCircleIcon }, + { name: "Developers", href: "/developers", icon: CodeBracketIcon }, { name: "Profile", href: "/profile", icon: UserIcon }, ]; diff --git a/client/app/developers/page.tsx b/client/app/developers/page.tsx new file mode 100644 index 0000000..c895af0 --- /dev/null +++ b/client/app/developers/page.tsx @@ -0,0 +1,624 @@ +"use client"; +import React, { useState } from "react"; +import { motion } from "framer-motion"; +import { + CodeBracketIcon, + BookOpenIcon, + RocketLaunchIcon, + CubeIcon, + CommandLineIcon, + DocumentTextIcon, + BeakerIcon, + ArrowTopRightOnSquareIcon, +} from "@heroicons/react/24/outline"; + +interface DocSection { + id: string; + title: string; + icon: React.ComponentType>; + content: string; +} + +const docSections: DocSection[] = [ + { + id: "quickstart", + title: "Quick Start", + icon: RocketLaunchIcon, + content: `Get started with Agora Blockchain in minutes. Follow our step-by-step guide to create your first decentralized election. + +## Installation + +\`\`\`bash +# Clone the repository +git clone https://github.com/AOSSIE-Org/Agora-Blockchain.git +cd Agora-Blockchain + +# Install dependencies +npm install + +# Start local blockchain +cd blockchain && npx hardhat node + +# Deploy contracts +npx hardhat run scripts/deploy.js --network localhost + +# Start the client +cd ../client && npm run dev +\`\`\` + +## Your First Election + +1. Connect your MetaMask wallet +2. Navigate to "Create Election" +3. Fill in election details and add candidates +4. Choose a voting algorithm (Borda, IRV, etc.) +5. Deploy and share your election!`, + }, + { + id: "smart-contracts", + title: "Smart Contracts", + icon: CubeIcon, + content: `## Core Contracts + +### Election.sol +The main contract for managing individual elections. + +\`\`\`solidity +contract Election { + struct Candidate { + uint256 id; + string name; + uint256 voteCount; + } + + mapping(address => bool) public hasVoted; + mapping(uint256 => Candidate) public candidates; + + function vote(uint256 candidateId) public { + require(!hasVoted[msg.sender], "Already voted"); + require(candidateId > 0 && candidateId <= candidatesCount); + + candidates[candidateId].voteCount++; + hasVoted[msg.sender] = true; + } +} +\`\`\` + +### ElectionFactory.sol +Factory contract for creating new elections. + +\`\`\`solidity +contract ElectionFactory { + address[] public elections; + + function createElection( + string memory _title, + string memory _description + ) public returns (address) { + Election newElection = new Election(_title, _description, msg.sender); + elections.push(address(newElection)); + return address(newElection); + } +} +\`\`\` + +## Voting Algorithms + +Agora supports multiple voting algorithms: +- **Borda Count**: Ranked-choice voting system +- **Instant Runoff Voting (IRV)**: Eliminates candidates with fewest votes +- **Moore's Method**: Condorcet-compliant voting +- **Oklahoma Method**: Modified Borda count`, + }, + { + id: "api-reference", + title: "API Reference", + icon: CodeBracketIcon, + content: `## Web3 Integration + +### Connecting Wallet + +\`\`\`typescript +import { ConnectButton } from '@rainbow-me/rainbowkit'; +import { useAccount } from 'wagmi'; + +function App() { + const { address, isConnected } = useAccount(); + + return ( + + ); +} +\`\`\` + +### Reading Election Data + +\`\`\`typescript +import { useContractRead } from 'wagmi'; +import ElectionABI from './abi/Election.json'; + +function ElectionDetails({ address }) { + const { data: title } = useContractRead({ + address: address, + abi: ElectionABI, + functionName: 'title', + }); + + const { data: candidateCount } = useContractRead({ + address: address, + abi: ElectionABI, + functionName: 'candidatesCount', + }); + + return ( +
+

{title}

+

{candidateCount} candidates

+
+ ); +} +\`\`\` + +### Casting a Vote + +\`\`\`typescript +import { useContractWrite } from 'wagmi'; +import ElectionABI from './abi/Election.json'; + +function VoteButton({ electionAddress, candidateId }) { + const { write: vote } = useContractWrite({ + address: electionAddress, + abi: ElectionABI, + functionName: 'vote', + args: [candidateId], + }); + + return ( + + ); +} +\`\`\` + +## Contract Events + +\`\`\`typescript +import { useContractEvent } from 'wagmi'; + +function ElectionMonitor({ address }) { + useContractEvent({ + address: address, + abi: ElectionABI, + eventName: 'VoteCast', + listener: (log) => { + console.log('Vote cast:', log); + }, + }); +} +\`\`\``, + }, + { + id: "integration", + title: "Integration Guide", + icon: BeakerIcon, + content: `## Integrating Agora into Your DApp + +### 1. Install Dependencies + +\`\`\`bash +npm install wagmi viem @rainbow-me/rainbowkit +\`\`\` + +### 2. Configure Wagmi + +\`\`\`typescript +import { createConfig, configureChains } from 'wagmi'; +import { sepolia, polygonAmoy } from 'wagmi/chains'; +import { publicProvider } from 'wagmi/providers/public'; + +const { chains, publicClient } = configureChains( + [sepolia, polygonAmoy], + [publicProvider()] +); + +const config = createConfig({ + autoConnect: true, + publicClient, +}); +\`\`\` + +### 3. Wrap Your App + +\`\`\`typescript +import { WagmiConfig } from 'wagmi'; +import { RainbowKitProvider } from '@rainbow-me/rainbowkit'; + +function App({ Component, pageProps }) { + return ( + + + + + + ); +} +\`\`\` + +### 4. Create an Election + +\`\`\`typescript +const { write: createElection } = useContractWrite({ + address: FACTORY_ADDRESS, + abi: ElectionFactoryABI, + functionName: 'createElection', + args: ['My Election', 'Description', ['Alice', 'Bob']], +}); +\`\`\` + +## Testing + +\`\`\`bash +# Run contract tests +cd blockchain +npx hardhat test + +# Run frontend tests +cd client +npm test +\`\`\``, + }, + { + id: "sdk", + title: "SDK & Tools", + icon: CommandLineIcon, + content: `## Available SDKs + +### JavaScript/TypeScript SDK + +\`\`\`bash +npm install @agora-blockchain/sdk +\`\`\` + +\`\`\`typescript +import { AgoraClient } from '@agora-blockchain/sdk'; + +const client = new AgoraClient({ + network: 'sepolia', + privateKey: process.env.PRIVATE_KEY, +}); + +// Create election +const election = await client.createElection({ + title: 'My Election', + candidates: ['Alice', 'Bob', 'Charlie'], + algorithm: 'borda', +}); + +// Cast vote +await election.vote(candidateId); + +// Get results +const results = await election.getResults(); +\`\`\` + +## Development Tools + +### Hardhat Configuration + +\`\`\`javascript +module.exports = { + solidity: "0.8.20", + networks: { + sepolia: { + url: process.env.SEPOLIA_RPC_URL, + accounts: [process.env.PRIVATE_KEY], + }, + }, +}; +\`\`\` + +### Useful Scripts + +\`\`\`json +{ + "scripts": { + "compile": "hardhat compile", + "test": "hardhat test", + "deploy": "hardhat run scripts/deploy.js", + "verify": "hardhat verify --network sepolia" + } +} +\`\`\` + +## Debugging + +\`\`\`bash +# Enable verbose logging +DEBUG=* npm run dev + +# Check contract deployment +npx hardhat verify --network sepolia +\`\`\``, + }, + { + id: "contributing", + title: "Contributing", + icon: DocumentTextIcon, + content: `## How to Contribute + +We welcome contributions from the community! Here's how you can help: + +### 1. Fork the Repository + +\`\`\`bash +git clone https://github.com/YOUR_USERNAME/Agora-Blockchain.git +cd Agora-Blockchain +git remote add upstream https://github.com/AOSSIE-Org/Agora-Blockchain.git +\`\`\` + +### 2. Create a Branch + +\`\`\`bash +git checkout -b feat/my-feature +# or +git checkout -b fix/bug-description +\`\`\` + +### 3. Make Your Changes + +- Write clean, documented code +- Follow existing code style +- Add tests for new features +- Update documentation + +### 4. Commit Standards + +\`\`\`bash +# Feature +git commit -m "feat: add new voting algorithm" + +# Bug fix +git commit -m "fix: resolve wallet connection issue" + +# Documentation +git commit -m "docs: update API reference" +\`\`\` + +### 5. Submit Pull Request + +1. Push to your fork +2. Open a PR against \`main\` branch +3. Describe your changes +4. Wait for review + +## Code Style + +- Use TypeScript for frontend +- Use Solidity 0.8.x for contracts +- Follow ESLint configuration +- Write meaningful commit messages + +## Testing Requirements + +- All smart contracts must have test coverage +- Frontend components should have unit tests +- Integration tests for critical flows + +## Need Help? + +- Join our Discord community +- Check existing issues and discussions +- Read the documentation thoroughly`, + }, +]; + +const resources = [ + { + title: "GitHub Repository", + description: "View source code and contribute", + icon: CodeBracketIcon, + link: "https://github.com/AOSSIE-Org/Agora-Blockchain", + }, + { + title: "Smart Contracts", + description: "Explore deployed contracts", + icon: CubeIcon, + link: "https://github.com/AOSSIE-Org/Agora-Blockchain/tree/main/blockchain/contracts", + }, + { + title: "API Documentation", + description: "Complete API reference", + icon: BookOpenIcon, + link: "https://github.com/AOSSIE-Org/Agora-Blockchain#readme", + }, + { + title: "Community Discord", + description: "Join developer discussions", + icon: CommandLineIcon, + link: "https://aossie.org", + }, +]; + +export default function DevelopersPage() { + const [activeSection, setActiveSection] = useState("quickstart"); + + const currentSection = docSections.find((s) => s.id === activeSection); + + return ( +
+
+ {/* Header */} + +

+ Developer Portal +

+

+ Build decentralized voting applications with Agora Blockchain. + Comprehensive guides, API docs, and tools for developers. +

+
+ +
+ {/* Sidebar Navigation */} + +
+

+ Documentation +

+ +
+
+ + {/* Main Content */} + +
+
+ {currentSection && ( + <> + +

+ {currentSection.title} +

+ + )} +
+ +
+
+ {(() => { + const out: React.ReactNode[] = []; + const lines = currentSection?.content.split("\n") ?? []; + let inCode = false; + let list: string[] = []; + + const flushList = (key: string) => { + if (!list.length) return; + out.push( +
    + {list.map((t, i) =>
  • {t}
  • )} +
+ ); + list = []; + }; + + lines.forEach((line, idx) => { + if (line.startsWith("```")) { + inCode = !inCode; + flushList(`list-${idx}`); + return; + } + if (inCode) return; + + if (line.startsWith("## ")) { + flushList(`list-${idx}`); + out.push( +

+ {line.replace("## ", "")} +

+ ); + return; + } + if (line.startsWith("### ")) { + flushList(`list-${idx}`); + out.push( +

+ {line.replace("### ", "")} +

+ ); + return; + } + if (line.startsWith("- ")) { + list.push(line.replace("- ", "")); + return; + } + if (line.trim()) { + flushList(`list-${idx}`); + out.push(

{line}

); + return; + } + flushList(`list-${idx}`); + out.push(
); + }); + + flushList("list-end"); + return out; + })()} +
+
+
+
+
+ + {/* Resources Section */} + +

+ Resources & Links +

+
+ {resources.map((resource, index) => ( + +
+ + +
+

+ {resource.title} +

+

+ {resource.description} +

+
+ ))} +
+
+
+
+ ); +} diff --git a/client/app/globals.css b/client/app/globals.css index c898587..0b3a94c 100644 --- a/client/app/globals.css +++ b/client/app/globals.css @@ -5,7 +5,7 @@ body { background-color: #ffffff; margin: 0; - overflow: hidden; + overflow-y: auto; } html {