"use client" import { useState, useEffect } from "react" import Link from "next/link" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { BlockchainVisualizer, BlockchainData } from "@/components/blockchain-visualizer" import { ArrowLeft, RefreshCw } from "lucide-react" export default function BlockchainPage() { const [selectedElection, setSelectedElection] = useState(null) const [blockchainData, setBlockchainData] = useState(null) const [isLoading, setIsLoading] = useState(false) const [isVerifying, setIsVerifying] = useState(false) const [error, setError] = useState(null) const [elections, setElections] = useState>([]) const [electionsLoading, setElectionsLoading] = useState(true) // Fetch available elections useEffect(() => { const fetchElections = async () => { try { setElectionsLoading(true) const token = localStorage.getItem("auth_token") const response = await fetch("/api/elections/active", { headers: { Authorization: `Bearer ${token}`, }, }) if (!response.ok) { throw new Error("Impossible de charger les élections") } const data = await response.json() // API returns array directly, not wrapped in .elections const elections = Array.isArray(data) ? data : data.elections || [] setElections(elections) // Select first election by default if (elections && elections.length > 0) { setSelectedElection(elections[0].id) } } catch (err) { console.error("Error fetching elections:", err) // Mock elections for demo setElections([ { id: 1, name: "Election Présidentielle 2025" }, { id: 2, name: "Référendum : Réforme Constitutionnelle" }, { id: 3, name: "Election Municipale - Île-de-France" }, ]) setSelectedElection(1) } finally { setElectionsLoading(false) } } fetchElections() }, []) // Fetch blockchain data useEffect(() => { if (!selectedElection) return const fetchBlockchain = async () => { try { setIsLoading(true) setError(null) const token = localStorage.getItem("auth_token") const response = await fetch( `/api/votes/blockchain?election_id=${selectedElection}`, { headers: { Authorization: `Bearer ${token}`, }, } ) if (!response.ok) { if (response.status === 404) { // No blockchain yet, create empty state const emptyData = { blocks: [], verification: { chain_valid: true, total_blocks: 0, total_votes: 0, }, } setBlockchainData(emptyData) return } throw new Error("Impossible de charger la blockchain") } const data = await response.json() // Ensure blocks array exists const blockchainData = { blocks: data.blocks || [], verification: data.verification || { chain_valid: true, total_blocks: 0, total_votes: 0, } } setBlockchainData(blockchainData) } catch (err) { const errorMessage = err instanceof Error ? err.message : "Erreur inconnue" setError(errorMessage) // Mock blockchain for demo setBlockchainData({ blocks: [ { index: 0, prev_hash: "0".repeat(64), timestamp: Math.floor(Date.now() / 1000) - 3600, encrypted_vote: "", transaction_id: "genesis", block_hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", signature: "", }, { index: 1, prev_hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", timestamp: Math.floor(Date.now() / 1000) - 2400, encrypted_vote: "aGVsbG8gd29ybGQgdm90ZSBl", transaction_id: "tx-voter1-001", block_hash: "2c26b46911185131006ba5991ab4ef3d89854e7cf44e10898fbee6d29fc80e4d", signature: "d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2", }, { index: 2, prev_hash: "2c26b46911185131006ba5991ab4ef3d89854e7cf44e10898fbee6d29fc80e4d", timestamp: Math.floor(Date.now() / 1000) - 1200, encrypted_vote: "d29ybGQgaGVsbG8gdm90ZSBl", transaction_id: "tx-voter2-001", block_hash: "fcde2b2edba56bf408601fb721fe9b5348ccb48664c11d95d3a0e17de2d63594e", signature: "d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3", }, ], verification: { chain_valid: true, total_blocks: 3, total_votes: 2, }, }) } finally { setIsLoading(false) } } fetchBlockchain() }, [selectedElection]) // Verify blockchain const handleVerifyBlockchain = async () => { if (!selectedElection) return try { setIsVerifying(true) const token = localStorage.getItem("auth_token") const response = await fetch("/api/votes/verify-blockchain", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ election_id: selectedElection }), }) if (!response.ok) { throw new Error("Erreur lors de la vérification") } const data = await response.json() if (blockchainData) { setBlockchainData({ ...blockchainData, verification: { ...blockchainData.verification, chain_valid: data.chain_valid, }, }) } } catch (err) { console.error("Verification error:", err) } finally { setIsVerifying(false) } } return (
{/* Header */}

Blockchain Électorale

Vérifiez l'immuabilité et la transparence des votes enregistrés

{/* Election Selector */} Sélectionner une Élection {electionsLoading ? (
Chargement des élections...
) : (
{elections.map((election) => ( ))}
)}
{/* Error Message */} {error && (

Erreur

{error}

)} {/* Blockchain Visualizer */} {blockchainData && selectedElection && ( <> {/* Refresh Button */}
)} {/* Empty State */} {blockchainData && blockchainData.blocks && blockchainData.blocks.length === 0 && (
⛓️

Aucun vote enregistré

Les votes pour cette élection s'afficheront ici une fois qu'ils seront soumis.

)}
) }