DashboardPage.tsx
1 /** 2 * Governor Dashboard - Central Bank Governor overview 3 */ 4 import { useEffect } from 'react'; 5 import { Link } from 'react-router-dom'; 6 import { useGovernanceStore } from '../store/governance'; 7 8 export function DashboardPage() { 9 const { 10 proposals, 11 networkStatus, 12 recentActivity, 13 isLoading, 14 fetchProposals, 15 fetchNetworkStatus, 16 fetchRecentActivity, 17 } = useGovernanceStore(); 18 19 useEffect(() => { 20 fetchProposals(); 21 fetchNetworkStatus(); 22 fetchRecentActivity(); 23 }, [fetchProposals, fetchNetworkStatus, fetchRecentActivity]); 24 25 const pendingProposals = proposals.filter(p => p.status === 'active'); 26 const pendingCount = pendingProposals.length; 27 28 if (isLoading) { 29 return ( 30 <div className="flex items-center justify-center h-64"> 31 <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-alpha" /> 32 </div> 33 ); 34 } 35 36 return ( 37 <div className="max-w-7xl mx-auto p-6"> 38 <h1 className="text-2xl font-bold text-text-primary mb-8">Governor Dashboard</h1> 39 40 {/* Network Status Section */} 41 <section className="mb-8"> 42 <h2 className="text-lg font-semibold text-text-primary mb-4">Network Status</h2> 43 <div className="grid grid-cols-1 md:grid-cols-4 gap-4"> 44 <div className="bg-card rounded-xl p-6"> 45 <div className="text-text-secondary text-sm">Block Height</div> 46 <div className="text-2xl font-bold text-text-primary mt-1"> 47 {networkStatus.blockHeight.toLocaleString()} 48 </div> 49 </div> 50 <div className="bg-card rounded-xl p-6"> 51 <div className="text-text-secondary text-sm">Total Supply</div> 52 <div className="text-2xl font-bold text-text-primary mt-1"> 53 {(Number(networkStatus.totalSupply) / 1e18).toLocaleString()} ACDC 54 </div> 55 </div> 56 <div className="bg-card rounded-xl p-6"> 57 <div className="text-text-secondary text-sm">Active Validators</div> 58 <div className="text-2xl font-bold text-text-primary mt-1"> 59 {networkStatus.activeValidators} 60 </div> 61 </div> 62 <div className="bg-card rounded-xl p-6"> 63 <div className="text-text-secondary text-sm">Network Status</div> 64 <div className="flex items-center gap-2 mt-1"> 65 <div className={`w-3 h-3 rounded-full ${networkStatus.isHealthy ? 'bg-success' : 'bg-error'}`} /> 66 <span className="text-2xl font-bold text-text-primary"> 67 {networkStatus.isHealthy ? 'Healthy' : 'Degraded'} 68 </span> 69 </div> 70 </div> 71 </div> 72 </section> 73 74 {/* Pending Proposals Section */} 75 <section className="mb-8"> 76 <div className="flex justify-between items-center mb-4"> 77 <h2 className="text-lg font-semibold text-text-primary"> 78 Pending Proposals Requiring Action 79 {pendingCount > 0 && ( 80 <span className="ml-2 px-2 py-0.5 text-xs bg-warning text-text-primary rounded-full"> 81 {pendingCount} 82 </span> 83 )} 84 </h2> 85 <Link 86 to="/proposals" 87 className="text-alpha-light hover:text-alpha text-sm" 88 > 89 View All Proposals 90 </Link> 91 </div> 92 <div className="bg-card rounded-xl overflow-hidden"> 93 {pendingProposals.length === 0 ? ( 94 <div className="p-6 text-center text-text-secondary"> 95 No pending proposals requiring your vote 96 </div> 97 ) : ( 98 <div className="divide-y divide-border"> 99 {pendingProposals.slice(0, 5).map((proposal) => ( 100 <Link 101 key={proposal.id} 102 to={`/proposals/${proposal.id}`} 103 className="flex items-center justify-between p-4 hover:bg-card-hover transition-colors" 104 > 105 <div> 106 <div className="text-sm text-text-secondary">{proposal.id}</div> 107 <div className="text-text-primary font-medium">{proposal.title}</div> 108 </div> 109 <div className="text-sm text-warning"> 110 {Math.ceil((proposal.endTime - Date.now()) / (1000 * 60 * 60 * 24))} days left 111 </div> 112 </Link> 113 ))} 114 </div> 115 )} 116 </div> 117 </section> 118 119 {/* Recent Activity Section */} 120 <section className="mb-8"> 121 <h2 className="text-lg font-semibold text-text-primary mb-4">Recent Governance Activity</h2> 122 <div className="bg-card rounded-xl overflow-hidden"> 123 {recentActivity.length === 0 ? ( 124 <div className="p-6 text-center text-text-secondary"> 125 No recent activity 126 </div> 127 ) : ( 128 <div className="divide-y divide-border"> 129 {recentActivity.map((activity, index) => ( 130 <div key={index} className="flex items-center gap-4 p-4"> 131 <div className={`w-10 h-10 rounded-full flex items-center justify-center ${ 132 activity.type === 'vote' ? 'bg-info/20 text-info' : 133 activity.type === 'proposal' ? 'bg-alpha/20 text-alpha-light' : 134 activity.type === 'mint' ? 'bg-delta/20 text-delta-light' : 135 'bg-card-hover text-text-secondary' 136 }`}> 137 {activity.type === 'vote' && 'V'} 138 {activity.type === 'proposal' && 'P'} 139 {activity.type === 'mint' && 'M'} 140 {activity.type === 'governor_change' && 'G'} 141 </div> 142 <div className="flex-1"> 143 <div className="text-text-primary">{activity.description}</div> 144 <div className="text-sm text-text-secondary"> 145 {new Date(activity.timestamp).toLocaleString()} 146 </div> 147 </div> 148 </div> 149 ))} 150 </div> 151 )} 152 </div> 153 </section> 154 155 {/* Quick Actions Section */} 156 <section> 157 <h2 className="text-lg font-semibold text-text-primary mb-4">Quick Actions</h2> 158 <div className="grid grid-cols-1 md:grid-cols-4 gap-4"> 159 <Link 160 to="/proposals/new" 161 className="bg-alpha hover:bg-alpha-dark rounded-xl p-6 text-center transition-colors" 162 > 163 <div className="text-text-primary font-medium">Create Proposal</div> 164 <div className="text-alpha-light text-sm mt-1">Submit new governance proposal</div> 165 </Link> 166 <Link 167 to="/minting" 168 className="bg-delta hover:bg-delta-dark rounded-xl p-6 text-center transition-colors" 169 > 170 <div className="text-text-primary font-medium">Mint Tokens</div> 171 <div className="text-delta-light text-sm mt-1">Request token minting</div> 172 </Link> 173 <Link 174 to="/governors" 175 className="bg-alpha hover:bg-alpha-dark rounded-xl p-6 text-center transition-colors" 176 > 177 <div className="text-text-primary font-medium">Manage Governors</div> 178 <div className="text-alpha-light text-sm mt-1">View governor status</div> 179 </Link> 180 <Link 181 to="/settings" 182 className="bg-card-hover hover:bg-border-strong rounded-xl p-6 text-center transition-colors" 183 > 184 <div className="text-text-primary font-medium">Settings</div> 185 <div className="text-text-secondary text-sm mt-1">Configure console</div> 186 </Link> 187 </div> 188 </section> 189 </div> 190 ); 191 }