import { useState, useEffect } from 'react'; import { Vote, Plus, RefreshCw, AlertCircle, Clock, CheckCircle, XCircle, Users, TrendingUp, ChevronDown, ChevronUp, Zap, } from 'lucide-react'; import { useGovernanceStore, getStatusLabel, getStatusColor, calculateVotePercentage, } from '../../store/governance'; export default function GovernanceDashboard() { const { proposals, votingPower, isLoading, isVoting, error, clearError, fetchProposals, fetchVotingPower, createProposal, vote, delegate, } = useGovernanceStore(); const [activeTab, setActiveTab] = useState<'proposals' | 'voting-power'>('proposals'); const [showCreateForm, setShowCreateForm] = useState(false); const [showDelegateForm, setShowDelegateForm] = useState(false); const [expandedProposal, setExpandedProposal] = useState(null); const [isCreating, setIsCreating] = useState(false); // Create form state const [newTitle, setNewTitle] = useState(''); const [newDescription, setNewDescription] = useState(''); const [newActions, setNewActions] = useState(''); // Delegate form state const [delegateAddress, setDelegateAddress] = useState(''); useEffect(() => { fetchProposals(); fetchVotingPower(); }, [fetchProposals, fetchVotingPower]); const handleCreateProposal = async () => { if (!newTitle || !newDescription) return; setIsCreating(true); try { // Parse actions as string array let actions: string[] = []; if (newActions) { try { actions = JSON.parse(newActions); } catch { // If not valid JSON, treat as single action actions = [newActions]; } } await createProposal(newTitle, newDescription, actions); setShowCreateForm(false); setNewTitle(''); setNewDescription(''); setNewActions(''); fetchProposals(); } catch { // Error handled by store } finally { setIsCreating(false); } }; const handleVote = async (proposalId: string, support: 'for' | 'against' | 'abstain') => { await vote(proposalId, support); fetchProposals(); }; const handleDelegate = async () => { if (!delegateAddress) return; await delegate(delegateAddress); setShowDelegateForm(false); setDelegateAddress(''); fetchVotingPower(); }; const getStatusIcon = (status: string) => { switch (status) { case 'pending': return ; case 'active': return ; case 'passed': return ; case 'rejected': return ; case 'executed': return ; default: return ; } }; const formatVotes = (votes: string) => { const num = parseFloat(votes); if (num >= 1_000_000) return `${(num / 1_000_000).toFixed(1)}M`; if (num >= 1_000) return `${(num / 1_000).toFixed(1)}K`; return votes; }; return (
{/* Header */}

Governance

Participate in Synor DAO decisions

{/* Error Alert */} {error && (

{error}

)} {/* Create Proposal Modal */} {showCreateForm && (

Create Proposal

setNewTitle(e.target.value)} placeholder="Proposal title" className="w-full px-4 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-synor-500" />