diff --git a/.DS_Store b/.DS_Store index 346f1030..2993e811 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..09a9e9cb --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +PRIVATE_KEY= +RPC_URL_SEPOLIA= +RPC_URL_FUJI= +ETHERSCAN_KEY= diff --git a/blockchain/.env.example b/blockchain/.env.example deleted file mode 100644 index d26c2bc2..00000000 --- a/blockchain/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -PRIVATE_KEY = ENTER_YOUR_KEY_VALUE -RPC_URL_SEPOLIA = ENTER_YOUR_KEY_VALUE -RPC_URL_FUJI = ENTER_YOUR_KEY_VALUE -RPC_URL_AMOY = ENTER_YOUR_KEY_VALUE -RPC_URL_BSC = ENTER_YOUR_KEY_VALUE -ETHERSCAN_KEY = ENTER_YOUR_KEY_VALUE diff --git a/client/.env.example b/client/.env.example deleted file mode 100644 index 16d49007..00000000 --- a/client/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -NEXT_PUBLIC_SEPOLIA_RPC_URL = ENTER_RPC_URL -NEXT_PUBLIC_AMOY_RPC_URL = ENTER_RPC_URL -NEXT_PUBLIC_FUJI_RPC_URL = ENTER_RPC_URL -NEXT_PUBLIC_PINATA_JWT = ENTER_PINATA_API_KEY \ No newline at end of file diff --git a/client/WALLET_FEATURE.md b/client/WALLET_FEATURE.md new file mode 100644 index 00000000..fef62726 --- /dev/null +++ b/client/WALLET_FEATURE.md @@ -0,0 +1,249 @@ +# Wallet Management Feature + +## 📋 Overview + +A comprehensive Wallet Management page has been implemented for the Agora-Blockchain voting platform. This feature allows users to view, manage, and interact with their connected Web3 wallets. + +## ✨ Features Implemented + +### 1. **Wallet Connection & Display** +- Real-time wallet connection status +- Display of connected wallet address with copy-to-clipboard functionality +- Wallet connector identification (MetaMask, WalletConnect, Coinbase Wallet, etc.) +- ENS name and avatar support + +### 2. **Balance Overview** +- Native token balance display (ETH, AVAX, etc.) +- Real-time balance updates using wagmi hooks +- Network-specific balance information +- Token decimals and full balance details + +### 3. **Network Management** +- Visual network selector with supported chains: + - Sepolia Testnet (Ethereum) + - Avalanche Fuji Testnet +- One-click network switching +- Clear indication of active network +- Warning for unsupported networks + +### 4. **Wallet Information** +- ENS identity display with avatar +- Wallet type and address format verification +- Connection status indicators +- Security information about the connected wallet + +### 5. **Voting History** +- Placeholder for voting transaction history +- Ready for integration with blockchain voting records +- Statistics summary (total votes, elections participated, networks used) +- Transaction hash links to block explorers + +### 6. **Security Tips** +- Expandable security tips section +- Best practices for wallet security +- Warnings about phishing and scams +- Guidelines for safe Web3 interactions + +### 7. **User Experience** +- Beautiful gradient UI with Tailwind CSS +- Smooth animations using Framer Motion +- Responsive design (mobile, tablet, desktop) +- Toast notifications for user actions +- Loading states and skeleton screens + +## 🏗️ Architecture + +### File Structure +``` +client/app/ +├── wallet/ +│ └── page.tsx # Main wallet management page +└── components/ + └── Wallet/ + ├── WalletInfo.tsx # Wallet details and ENS info + ├── BalanceCard.tsx # Token balance display + ├── NetworkSelector.tsx # Network switching UI + ├── VotingHistory.tsx # Voting transaction history + └── SecurityTips.tsx # Security guidelines +``` + +### Technology Stack +- **Next.js 14** - App Router +- **wagmi** - React Hooks for Ethereum +- **RainbowKit** - Wallet connection UI +- **viem** - Ethereum library +- **Framer Motion** - Animations +- **Heroicons** - Icons +- **Tailwind CSS** - Styling +- **react-hot-toast** - Notifications + +## 🎨 UI Components + +### WalletInfo +Displays detailed wallet information including: +- ENS avatar and name +- Wallet type and status +- Address format verification +- Security information + +### BalanceCard +Shows comprehensive balance information: +- Native token balance with 4 decimal precision +- Network-specific token symbols +- Gradient backgrounds based on network +- Full balance and decimals + +### NetworkSelector +Provides network switching functionality: +- Grid layout of supported networks +- Visual indication of active network +- One-click network switching +- Warning for unsupported networks + +### VotingHistory +Tracks user's voting participation: +- List of voting transactions +- Election names and timestamps +- Transaction hash links +- Statistics summary + +### SecurityTips +Educational component for security: +- Expandable accordion design +- Key security guidelines +- Warning about phishing +- Platform-specific safety notes + +## 🔗 Integration Points + +### wagmi Hooks Used +- `useAccount()` - Current wallet account info +- `useBalance()` - Token balance +- `useEnsName()` - ENS name resolution +- `useEnsAvatar()` - ENS avatar +- `useChainId()` - Current network ID +- `useSwitchChain()` - Network switching +- `useDisconnect()` - Wallet disconnection + +### RainbowKit Integration +- ConnectButton for wallet connection +- Automatic wallet provider detection +- Support for multiple wallet types + +## 🚀 Usage + +### Accessing the Wallet Page +1. Navigate to `/wallet` route +2. Or click "Wallet" in the navigation menu + +### Wallet Connection +If not connected: +1. Click the "Connect Wallet" button +2. Select your preferred wallet provider +3. Approve the connection + +If connected: +1. View wallet details, balance, and history +2. Switch networks as needed +3. Disconnect when finished + +### Network Switching +1. Scroll to the "Network Selection" section +2. Click on the desired network card +3. Approve the network switch in your wallet + +## 🔧 Future Enhancements + +### Planned Features +1. **Voting History Integration** + - Fetch actual voting records from blockchain + - Filter by date, network, or election + - Export voting history + +2. **Multi-Wallet Support** + - Connect multiple wallets simultaneously + - Set default wallet for transactions + - Switch between connected wallets + +3. **Token Management** + - Display ERC-20 token balances + - Token transfer functionality + - Token approval management + +4. **Transaction History** + - Complete transaction history + - Filter and search capabilities + - CSV export functionality + +5. **Advanced Security** + - Wallet health checks + - Connection permissions audit + - Security score indicators + +6. **Analytics Dashboard** + - Voting participation metrics + - Network usage statistics + - Gas fee analytics + +## 📝 Code Examples + +### Using Wallet Info in Other Components +```tsx +import { useAccount, useBalance } from 'wagmi'; + +function MyComponent() { + const { address, isConnected } = useAccount(); + const { data: balance } = useBalance({ address }); + + return ( +
+ {isConnected && ( +

Balance: {balance?.formatted} {balance?.symbol}

+ )} +
+ ); +} +``` + +### Network Switching +```tsx +import { useSwitchChain } from 'wagmi'; +import { sepolia } from 'wagmi/chains'; + +function SwitchNetwork() { + const { switchChain } = useSwitchChain(); + + const handleSwitch = () => { + switchChain({ chainId: sepolia.id }); + }; + + return ; +} +``` + +## 🐛 Known Issues + +1. **Voting History**: Currently uses mock data - needs integration with blockchain indexer or backend API +2. **ENS Resolution**: May be slow on some networks - consider caching +3. **Balance Updates**: Real-time updates depend on RPC endpoint reliability + +## 🤝 Contributing + +When extending this feature: +1. Follow the existing component structure +2. Use wagmi hooks for blockchain interactions +3. Maintain responsive design patterns +4. Add loading states for async operations +5. Include error handling with user-friendly messages + +## 📄 License + +This feature is part of the Agora-Blockchain project and follows the same license. + +## 👥 Credits + +Developed as part of the GSOC contribution to Agora-Blockchain. + +--- + +For more information, see the main project README or visit the [documentation](../README.md). diff --git a/client/app/components/Cards/ElectionMini.tsx b/client/app/components/Cards/ElectionMini.tsx index 3c731eb3..97b42e74 100644 --- a/client/app/components/Cards/ElectionMini.tsx +++ b/client/app/components/Cards/ElectionMini.tsx @@ -1,6 +1,6 @@ "use client"; -import React from "react"; +import React, { useEffect } from "react"; import { motion } from "framer-motion"; import SkeletonElection from "../Helper/SkeletonElection"; import { FaRegUser } from "react-icons/fa6"; @@ -30,11 +30,21 @@ const ElectionMini = ({ electionAddress: electionAddress, }); - if (isLoading || electionInfo == undefined) return ; - const isStarting = Math.floor(Date.now() / 1000) < Number(electionInfo[0]); - const isEnded = Math.floor(Date.now() / 1000) > Number(electionInfo[1]); + // Calculate election status (safe to do even if electionInfo is undefined) + const isStarting = electionInfo ? Math.floor(Date.now() / 1000) < Number(electionInfo[0]) : false; + const isEnded = electionInfo ? Math.floor(Date.now() / 1000) > Number(electionInfo[1]) : false; const electionStat = isStarting ? 1 : isEnded ? 3 : 2; - update?.(electionAddress, electionStat); + + // Move state update to useEffect to avoid updating parent during render + // This must be called before any conditional returns (Rules of Hooks) + useEffect(() => { + if (update && electionInfo) { + update(electionAddress, electionStat); + } + }, [electionAddress, electionStat, update, electionInfo]); + + // Early return AFTER all hooks have been called + if (isLoading || electionInfo == undefined) return ; return ( { @@ -40,7 +44,7 @@ const Header = () => { Agora Blockchain diff --git a/client/app/components/Help/CategoryCard.tsx b/client/app/components/Help/CategoryCard.tsx new file mode 100644 index 00000000..acd5bb97 --- /dev/null +++ b/client/app/components/Help/CategoryCard.tsx @@ -0,0 +1,54 @@ +"use client"; + +import React from "react"; +import { motion } from "framer-motion"; + +interface Category { + id: string; + title: string; + icon: React.ComponentType>; + color: string; + description: string; +} + +interface CategoryCardProps { + category: Category; + index: number; + isSelected: boolean; + onClick: () => void; +} + +export default function CategoryCard({ + category, + index, + isSelected, + onClick, +}: CategoryCardProps) { + const Icon = category.icon; + + return ( + +
+ +
+

+ {category.title} +

+

{category.description}

+
+ ); +} diff --git a/client/app/components/Help/ContactSupport.tsx b/client/app/components/Help/ContactSupport.tsx new file mode 100644 index 00000000..ed101d88 --- /dev/null +++ b/client/app/components/Help/ContactSupport.tsx @@ -0,0 +1,227 @@ +"use client"; + +import React, { useState } from "react"; +import { motion } from "framer-motion"; +import { + EnvelopeIcon, + ChatBubbleLeftRightIcon, + DocumentTextIcon, + CodeBracketIcon, +} from "@heroicons/react/24/outline"; +import toast from "react-hot-toast"; + +export default function ContactSupport() { + const [formData, setFormData] = useState({ + name: "", + email: "", + subject: "", + message: "", + }); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + // In a real implementation, this would send to a backend or support system + toast.success( + "Thank you! Your message has been received. We'll get back to you soon." + ); + + setFormData({ name: "", email: "", subject: "", message: "" }); + }; + + const handleChange = ( + e: React.ChangeEvent + ) => { + setFormData({ + ...formData, + [e.target.name]: e.target.value, + }); + }; + + return ( + +

Contact Support

+ +
+ {/* Contact Cards */} + + +

Discord Community

+

+ Join our active community for real-time help and discussions +

+
+ + + +

GitHub Issues

+

+ Report bugs or request features on our GitHub repository +

+
+ + + +

Documentation

+

+ Explore detailed documentation and contribution guidelines +

+
+
+ + {/* Contact Form */} +
+
+ +

+ Send Us a Message +

+
+ +
+
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ +