/ src / pages / DashboardPage.tsx
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  }