update governance ui
This commit is contained in:
		@@ -12,9 +12,24 @@ pub struct GovernanceController;
 | 
			
		||||
 | 
			
		||||
impl GovernanceController {
 | 
			
		||||
    /// Helper function to get user from session
 | 
			
		||||
    /// For testing purposes, this will always return a mock user
 | 
			
		||||
    fn get_user_from_session(session: &Session) -> Option<Value> {
 | 
			
		||||
        session.get::<String>("user").ok().flatten().and_then(|user_json| {
 | 
			
		||||
        // Try to get user from session first
 | 
			
		||||
        let session_user = session.get::<String>("user").ok().flatten().and_then(|user_json| {
 | 
			
		||||
            serde_json::from_str(&user_json).ok()
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        // If user is not in session, return a mock user for testing
 | 
			
		||||
        session_user.or_else(|| {
 | 
			
		||||
            // Create a mock user
 | 
			
		||||
            let mock_user = serde_json::json!({
 | 
			
		||||
                "id": 1,
 | 
			
		||||
                "username": "test_user",
 | 
			
		||||
                "email": "test@example.com",
 | 
			
		||||
                "name": "Test User",
 | 
			
		||||
                "role": "member"
 | 
			
		||||
            });
 | 
			
		||||
            Some(mock_user)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -23,14 +38,32 @@ impl GovernanceController {
 | 
			
		||||
        let mut ctx = tera::Context::new();
 | 
			
		||||
        ctx.insert("active_page", "governance");
 | 
			
		||||
        
 | 
			
		||||
        // Add user to context if available
 | 
			
		||||
        if let Some(user) = Self::get_user_from_session(&session) {
 | 
			
		||||
            ctx.insert("user", &user);
 | 
			
		||||
        }
 | 
			
		||||
        // Add user to context (will always be available with our mock user)
 | 
			
		||||
        let user = Self::get_user_from_session(&session).unwrap();
 | 
			
		||||
        ctx.insert("user", &user);
 | 
			
		||||
        
 | 
			
		||||
        // Get mock proposals for the dashboard
 | 
			
		||||
        let proposals = Self::get_mock_proposals();
 | 
			
		||||
        ctx.insert("proposals", &proposals);
 | 
			
		||||
        let mut proposals = Self::get_mock_proposals();
 | 
			
		||||
        
 | 
			
		||||
        // Filter for active proposals only
 | 
			
		||||
        let active_proposals: Vec<Proposal> = proposals.into_iter()
 | 
			
		||||
            .filter(|p| p.status == ProposalStatus::Active)
 | 
			
		||||
            .collect();
 | 
			
		||||
        
 | 
			
		||||
        // Sort active proposals by voting end date (ascending)
 | 
			
		||||
        let mut sorted_active_proposals = active_proposals.clone();
 | 
			
		||||
        sorted_active_proposals.sort_by(|a, b| a.voting_ends_at.cmp(&b.voting_ends_at));
 | 
			
		||||
        
 | 
			
		||||
        ctx.insert("proposals", &sorted_active_proposals);
 | 
			
		||||
        
 | 
			
		||||
        // Get the nearest deadline proposal for the voting pane
 | 
			
		||||
        if let Some(nearest_proposal) = sorted_active_proposals.first() {
 | 
			
		||||
            ctx.insert("nearest_proposal", nearest_proposal);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Get recent activity for the timeline
 | 
			
		||||
        let recent_activity = Self::get_mock_recent_activity();
 | 
			
		||||
        ctx.insert("recent_activity", &recent_activity);
 | 
			
		||||
        
 | 
			
		||||
        // Get some statistics
 | 
			
		||||
        let stats = Self::get_mock_statistics();
 | 
			
		||||
@@ -106,13 +139,9 @@ impl GovernanceController {
 | 
			
		||||
        ctx.insert("active_page", "governance");
 | 
			
		||||
        ctx.insert("active_tab", "create");
 | 
			
		||||
        
 | 
			
		||||
        // Add user to context if available
 | 
			
		||||
        if let Some(user) = Self::get_user_from_session(&session) {
 | 
			
		||||
            ctx.insert("user", &user);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Redirect to login if not logged in
 | 
			
		||||
            return Ok(HttpResponse::Found().append_header(("Location", "/login")).finish());
 | 
			
		||||
        }
 | 
			
		||||
        // Add user to context (will always be available with our mock user)
 | 
			
		||||
        let user = Self::get_user_from_session(&session).unwrap();
 | 
			
		||||
        ctx.insert("user", &user);
 | 
			
		||||
        
 | 
			
		||||
        render_template(&tmpl, "governance/create_proposal.html", &ctx)
 | 
			
		||||
    }
 | 
			
		||||
@@ -123,18 +152,12 @@ impl GovernanceController {
 | 
			
		||||
        tmpl: web::Data<Tera>,
 | 
			
		||||
        session: Session
 | 
			
		||||
    ) -> Result<impl Responder> {
 | 
			
		||||
        // Check if user is logged in
 | 
			
		||||
        if Self::get_user_from_session(&session).is_none() {
 | 
			
		||||
            return Ok(HttpResponse::Found().append_header(("Location", "/login")).finish());
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        let mut ctx = tera::Context::new();
 | 
			
		||||
        ctx.insert("active_page", "governance");
 | 
			
		||||
        
 | 
			
		||||
        // Add user to context if available
 | 
			
		||||
        if let Some(user) = Self::get_user_from_session(&session) {
 | 
			
		||||
            ctx.insert("user", &user);
 | 
			
		||||
        }
 | 
			
		||||
        // Add user to context (will always be available with our mock user)
 | 
			
		||||
        let user = Self::get_user_from_session(&session).unwrap();
 | 
			
		||||
        ctx.insert("user", &user);
 | 
			
		||||
        
 | 
			
		||||
        // In a real application, we would save the proposal to a database
 | 
			
		||||
        // For now, we'll just redirect to the proposals page with a success message
 | 
			
		||||
@@ -204,19 +227,77 @@ impl GovernanceController {
 | 
			
		||||
        ctx.insert("active_page", "governance");
 | 
			
		||||
        ctx.insert("active_tab", "my_votes");
 | 
			
		||||
        
 | 
			
		||||
        // Add user to context if available
 | 
			
		||||
        if let Some(user) = Self::get_user_from_session(&session) {
 | 
			
		||||
            ctx.insert("user", &user);
 | 
			
		||||
            
 | 
			
		||||
            // Get mock votes for this user
 | 
			
		||||
            let votes = Self::get_mock_votes_for_user(1); // Assuming user ID 1 for mock data
 | 
			
		||||
            ctx.insert("votes", &votes);
 | 
			
		||||
            
 | 
			
		||||
            render_template(&tmpl, "governance/my_votes.html", &ctx)
 | 
			
		||||
        } else {
 | 
			
		||||
            // Redirect to login if not logged in
 | 
			
		||||
            Ok(HttpResponse::Found().append_header(("Location", "/login")).finish())
 | 
			
		||||
        }
 | 
			
		||||
        // Add user to context (will always be available with our mock user)
 | 
			
		||||
        let user = Self::get_user_from_session(&session).unwrap();
 | 
			
		||||
        ctx.insert("user", &user);
 | 
			
		||||
        
 | 
			
		||||
        // Get mock votes for this user
 | 
			
		||||
        let votes = Self::get_mock_votes_for_user(1); // Assuming user ID 1 for mock data
 | 
			
		||||
        ctx.insert("votes", &votes);
 | 
			
		||||
        
 | 
			
		||||
        render_template(&tmpl, "governance/my_votes.html", &ctx)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Generate mock recent activity data for the dashboard
 | 
			
		||||
    fn get_mock_recent_activity() -> Vec<serde_json::Value> {
 | 
			
		||||
        vec![
 | 
			
		||||
            serde_json::json!({
 | 
			
		||||
                "type": "vote",
 | 
			
		||||
                "user": "Sarah Johnson",
 | 
			
		||||
                "proposal_id": "prop-001",
 | 
			
		||||
                "proposal_title": "Community Garden Initiative",
 | 
			
		||||
                "action": "voted Yes",
 | 
			
		||||
                "timestamp": (Utc::now() - Duration::hours(2)).to_rfc3339(),
 | 
			
		||||
                "icon": "bi-check-circle-fill text-success"
 | 
			
		||||
            }),
 | 
			
		||||
            serde_json::json!({
 | 
			
		||||
                "type": "comment",
 | 
			
		||||
                "user": "Michael Chen",
 | 
			
		||||
                "proposal_id": "prop-003",
 | 
			
		||||
                "proposal_title": "Weekly Community Calls",
 | 
			
		||||
                "action": "commented",
 | 
			
		||||
                "comment": "I think this would greatly improve communication.",
 | 
			
		||||
                "timestamp": (Utc::now() - Duration::hours(5)).to_rfc3339(),
 | 
			
		||||
                "icon": "bi-chat-left-text-fill text-primary"
 | 
			
		||||
            }),
 | 
			
		||||
            serde_json::json!({
 | 
			
		||||
                "type": "vote",
 | 
			
		||||
                "user": "Robert Callingham",
 | 
			
		||||
                "proposal_id": "prop-005",
 | 
			
		||||
                "proposal_title": "Security Audit Implementation",
 | 
			
		||||
                "action": "voted Yes",
 | 
			
		||||
                "timestamp": (Utc::now() - Duration::hours(8)).to_rfc3339(),
 | 
			
		||||
                "icon": "bi-check-circle-fill text-success"
 | 
			
		||||
            }),
 | 
			
		||||
            serde_json::json!({
 | 
			
		||||
                "type": "proposal",
 | 
			
		||||
                "user": "Emma Rodriguez",
 | 
			
		||||
                "proposal_id": "prop-004",
 | 
			
		||||
                "proposal_title": "Sustainability Roadmap",
 | 
			
		||||
                "action": "created proposal",
 | 
			
		||||
                "timestamp": (Utc::now() - Duration::hours(12)).to_rfc3339(),
 | 
			
		||||
                "icon": "bi-file-earmark-text-fill text-info"
 | 
			
		||||
            }),
 | 
			
		||||
            serde_json::json!({
 | 
			
		||||
                "type": "vote",
 | 
			
		||||
                "user": "David Kim",
 | 
			
		||||
                "proposal_id": "prop-002",
 | 
			
		||||
                "proposal_title": "Governance Framework Update",
 | 
			
		||||
                "action": "voted No",
 | 
			
		||||
                "timestamp": (Utc::now() - Duration::hours(16)).to_rfc3339(),
 | 
			
		||||
                "icon": "bi-x-circle-fill text-danger"
 | 
			
		||||
            }),
 | 
			
		||||
            serde_json::json!({
 | 
			
		||||
                "type": "comment",
 | 
			
		||||
                "user": "Lisa Wang",
 | 
			
		||||
                "proposal_id": "prop-001",
 | 
			
		||||
                "proposal_title": "Community Garden Initiative",
 | 
			
		||||
                "action": "commented",
 | 
			
		||||
                "comment": "I'd like to volunteer to help coordinate this effort.",
 | 
			
		||||
                "timestamp": (Utc::now() - Duration::hours(24)).to_rfc3339(),
 | 
			
		||||
                "icon": "bi-chat-left-text-fill text-primary"
 | 
			
		||||
            }),
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Mock data generation methods
 | 
			
		||||
 
 | 
			
		||||
@@ -65,8 +65,8 @@ pub fn configure_routes(cfg: &mut web::ServiceConfig) {
 | 
			
		||||
            .route("/governance/proposals", web::get().to(GovernanceController::proposals))
 | 
			
		||||
            .route("/governance/proposals/{id}", web::get().to(GovernanceController::proposal_detail))
 | 
			
		||||
            .route("/governance/proposals/{id}/vote", web::post().to(GovernanceController::submit_vote))
 | 
			
		||||
            .route("/governance/create-proposal", web::get().to(GovernanceController::create_proposal_form))
 | 
			
		||||
            .route("/governance/create-proposal", web::post().to(GovernanceController::submit_proposal))
 | 
			
		||||
            .route("/governance/create", web::get().to(GovernanceController::create_proposal_form))
 | 
			
		||||
            .route("/governance/create", web::post().to(GovernanceController::submit_proposal))
 | 
			
		||||
            .route("/governance/my-votes", web::get().to(GovernanceController::my_votes))
 | 
			
		||||
            
 | 
			
		||||
            // Flow routes
 | 
			
		||||
 
 | 
			
		||||
@@ -3,51 +3,8 @@
 | 
			
		||||
{% block title %}Governance Dashboard{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <h1 class="display-5 mb-4">Governance Dashboard</h1>
 | 
			
		||||
            <p class="lead">Participate in the decision-making process by voting on proposals and creating new ones.</p>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Statistics Cards -->
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-md-3 mb-3">
 | 
			
		||||
            <div class="card text-white bg-primary h-100">
 | 
			
		||||
                <div class="card-body">
 | 
			
		||||
                    <h5 class="card-title">Total Proposals</h5>
 | 
			
		||||
                    <p class="card-text display-6">{{ stats.total_proposals }}</p>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col-md-3 mb-3">
 | 
			
		||||
            <div class="card text-white bg-success h-100">
 | 
			
		||||
                <div class="card-body">
 | 
			
		||||
                    <h5 class="card-title">Active Proposals</h5>
 | 
			
		||||
                    <p class="card-text display-6">{{ stats.active_proposals }}</p>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col-md-3 mb-3">
 | 
			
		||||
            <div class="card text-white bg-info h-100">
 | 
			
		||||
                <div class="card-body">
 | 
			
		||||
                    <h5 class="card-title">Total Votes</h5>
 | 
			
		||||
                    <p class="card-text display-6">{{ stats.total_votes }}</p>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col-md-3 mb-3">
 | 
			
		||||
            <div class="card text-white bg-secondary h-100">
 | 
			
		||||
                <div class="card-body">
 | 
			
		||||
                    <h5 class="card-title">Participation Rate</h5>
 | 
			
		||||
                    <p class="card-text display-6">{{ stats.participation_rate }}%</p>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Navigation Tabs -->
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
    <div class="row mb-3">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <ul class="nav nav-tabs">
 | 
			
		||||
                <li class="nav-item">
 | 
			
		||||
@@ -66,43 +23,109 @@
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Active Proposals Section -->
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <div class="card">
 | 
			
		||||
        <!-- Info Alert -->
 | 
			
		||||
        <div class="row mb-2">
 | 
			
		||||
            <div class="col-12">
 | 
			
		||||
                <div class="alert alert-info alert-dismissible fade show">
 | 
			
		||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
			
		||||
                    <h5><i class="bi bi-info-circle"></i> About Governance</h5>
 | 
			
		||||
                    <p>The governance system allows token holders to participate in decision-making processes by voting on proposals that affect the platform's future. Create proposals, cast votes, and help shape the direction of our decentralized ecosystem.</p>
 | 
			
		||||
                    <div class="mt-2">
 | 
			
		||||
                        <a href="/governance/documentation" class="btn btn-sm btn-outline-primary"><i class="bi bi-book"></i> Read Documentation</a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    
 | 
			
		||||
    <!-- Dashboard Main Content -->
 | 
			
		||||
    <div class="row mb-3">
 | 
			
		||||
        <!-- Voting Pane for Nearest Deadline Proposal -->
 | 
			
		||||
        <div class="col-lg-8 mb-4 mb-lg-0">
 | 
			
		||||
            {% if nearest_proposal is defined %}
 | 
			
		||||
            <div class="card h-100">
 | 
			
		||||
                <div class="card-header d-flex justify-content-between align-items-center">
 | 
			
		||||
                    <h5 class="mb-0">Active Proposals</h5>
 | 
			
		||||
                    <a href="/governance/proposals" class="btn btn-sm btn-outline-primary">View All</a>
 | 
			
		||||
                    <h5 class="mb-0">Urgent: Voting Closes Soon</h5>
 | 
			
		||||
                    <div>
 | 
			
		||||
                        <span class="badge bg-warning text-dark me-2">Ends: {{ nearest_proposal.voting_ends_at | date(format="%Y-%m-%d") }}</span>
 | 
			
		||||
                        <a href="/governance/proposals/{{ nearest_proposal.id }}" class="btn btn-sm btn-outline-primary">View Full Proposal</a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="card-body">
 | 
			
		||||
                    <div class="table-responsive">
 | 
			
		||||
                        <table class="table table-hover">
 | 
			
		||||
                            <thead>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <th>Title</th>
 | 
			
		||||
                                    <th>Creator</th>
 | 
			
		||||
                                    <th>Status</th>
 | 
			
		||||
                                    <th>Voting Ends</th>
 | 
			
		||||
                                    <th>Actions</th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                            </thead>
 | 
			
		||||
                            <tbody>
 | 
			
		||||
                                {% for proposal in proposals %}
 | 
			
		||||
                                    {% if proposal.status == "Active" %}
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td>{{ proposal.title }}</td>
 | 
			
		||||
                                        <td>{{ proposal.creator_name }}</td>
 | 
			
		||||
                                        <td><span class="badge bg-success">{{ proposal.status }}</span></td>
 | 
			
		||||
                                        <td>{{ proposal.voting_ends_at | date(format="%Y-%m-%d") }}</td>
 | 
			
		||||
                                        <td>
 | 
			
		||||
                                            <a href="/governance/proposals/{{ proposal.id }}" class="btn btn-sm btn-primary">View</a>
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                {% endfor %}
 | 
			
		||||
                            </tbody>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    <h4 class="card-title">{{ nearest_proposal.title }}</h4>
 | 
			
		||||
                    <h6 class="card-subtitle mb-3 text-muted">Proposed by {{ nearest_proposal.creator_name }}</h6>
 | 
			
		||||
                    
 | 
			
		||||
                    <div class="mb-4">
 | 
			
		||||
                        <p>{{ nearest_proposal.description }}</p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    
 | 
			
		||||
                    <div class="progress mb-3" style="height: 25px;">
 | 
			
		||||
                        <div class="progress-bar bg-success" role="progressbar" style="width: 65%" aria-valuenow="65" aria-valuemin="0" aria-valuemax="100">65% Yes</div>
 | 
			
		||||
                        <div class="progress-bar bg-danger" role="progressbar" style="width: 35%" aria-valuenow="35" aria-valuemin="0" aria-valuemax="100">35% No</div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    
 | 
			
		||||
                    <div class="d-flex justify-content-between text-muted small mb-4">
 | 
			
		||||
                        <span>26 votes cast</span>
 | 
			
		||||
                        <span>Quorum: 75% reached</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    
 | 
			
		||||
                    <div class="mb-4">
 | 
			
		||||
                        <h5 class="mb-3">Cast Your Vote</h5>
 | 
			
		||||
                        <form>
 | 
			
		||||
                            <div class="mb-3">
 | 
			
		||||
                                <input type="text" class="form-control" placeholder="Optional comment on your vote" aria-label="Vote comment">
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="d-flex justify-content-between">
 | 
			
		||||
                                <button type="submit" name="vote" value="yes" class="btn btn-success">Vote Yes</button>
 | 
			
		||||
                                <button type="submit" name="vote" value="no" class="btn btn-danger">Vote No</button>
 | 
			
		||||
                                <button type="submit" name="vote" value="abstain" class="btn btn-secondary">Abstain</button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </form>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            {% else %}
 | 
			
		||||
            <div class="card h-100">
 | 
			
		||||
                <div class="card-body text-center py-5">
 | 
			
		||||
                    <i class="bi bi-clipboard-check fs-1 text-muted mb-3"></i>
 | 
			
		||||
                    <h5>No active proposals requiring votes</h5>
 | 
			
		||||
                    <p class="text-muted">When new proposals are created, they will appear here for voting.</p>
 | 
			
		||||
                    <a href="/governance/create" class="btn btn-primary mt-3">Create Proposal</a>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <!-- Recent Activity Timeline -->
 | 
			
		||||
        <div class="col-lg-4">
 | 
			
		||||
            <div class="card h-100">
 | 
			
		||||
                <div class="card-header">
 | 
			
		||||
                    <h5 class="mb-0">Recent Activity</h5>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="card-body p-0">
 | 
			
		||||
                    <div class="list-group list-group-flush">
 | 
			
		||||
                        {% for activity in recent_activity %}
 | 
			
		||||
                        <div class="list-group-item border-start-0 border-end-0 py-3">
 | 
			
		||||
                            <div class="d-flex">
 | 
			
		||||
                                <div class="me-3">
 | 
			
		||||
                                    <i class="bi {{ activity.icon }} fs-4"></i>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div>
 | 
			
		||||
                                    <div class="d-flex justify-content-between align-items-center">
 | 
			
		||||
                                        <strong>{{ activity.user }}</strong>
 | 
			
		||||
                                        <small class="text-muted">{{ activity.timestamp | date(format="%H:%M") }}</small>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <p class="mb-1">{{ activity.action }} on <a href="/governance/proposals/{{ activity.proposal_id }}">{{ activity.proposal_title }}</a></p>
 | 
			
		||||
                                    {% if activity.type == "comment" and activity.comment is defined %}
 | 
			
		||||
                                    <p class="mb-0 small text-muted">"{{ activity.comment }}"</p>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="card-footer text-center">
 | 
			
		||||
                    <a href="/governance/proposals" class="btn btn-sm btn-outline-info">View All Activity</a>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -113,7 +136,7 @@
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <div class="card">
 | 
			
		||||
                <div class="card-header">
 | 
			
		||||
                    <h5 class="mb-0">Recent Proposals</h5>
 | 
			
		||||
                    <h5 class="mb-0">Active Proposals (Ending Soon)</h5>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="card-body">
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
@@ -133,8 +156,8 @@
 | 
			
		||||
                                                <a href="/governance/proposals/{{ proposal.id }}" class="btn btn-sm btn-outline-primary">View Details</a>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="card-footer text-muted">
 | 
			
		||||
                                            Created: {{ proposal.created_at | date(format="%Y-%m-%d") }}
 | 
			
		||||
                                        <div class="card-footer text-muted text-center">
 | 
			
		||||
                                            <span>Voting ends: {{ proposal.voting_ends_at | date(format="%Y-%m-%d") }}</span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
@@ -146,17 +169,4 @@
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Call to Action -->
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <div class="card bg-light">
 | 
			
		||||
                <div class="card-body text-center">
 | 
			
		||||
                    <h4 class="mb-3">Have an idea to improve our platform?</h4>
 | 
			
		||||
                    <p class="mb-4">Create a proposal and let the community vote on it.</p>
 | 
			
		||||
                    <a href="/governance/create" class="btn btn-primary">Create Proposal</a>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,14 +3,6 @@
 | 
			
		||||
{% block title %}My Votes - Governance Dashboard{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="container-fluid">
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <h1 class="display-5 mb-4">My Votes</h1>
 | 
			
		||||
            <p class="lead">View all proposals you have voted on.</p>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Navigation Tabs -->
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
@@ -52,7 +44,7 @@
 | 
			
		||||
                                </tr>
 | 
			
		||||
                            </thead>
 | 
			
		||||
                            <tbody>
 | 
			
		||||
                                {% for vote, proposal in votes %}
 | 
			
		||||
                                {% for item in votes %}{% set vote = item.0 %}{% set proposal = item.1 %}
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td>{{ proposal.title }}</td>
 | 
			
		||||
                                    <td>
 | 
			
		||||
@@ -96,7 +88,7 @@
 | 
			
		||||
                    <h5 class="card-title">Yes Votes</h5>
 | 
			
		||||
                    <p class="display-4">
 | 
			
		||||
                        {% set yes_count = 0 %}
 | 
			
		||||
                        {% for vote, proposal in votes %}
 | 
			
		||||
                        {% for item in votes %}{% set vote = item.0 %}{% set proposal = item.1 %}
 | 
			
		||||
                            {% if vote.vote_type == 'Yes' %}
 | 
			
		||||
                                {% set yes_count = yes_count + 1 %}
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
@@ -112,7 +104,7 @@
 | 
			
		||||
                    <h5 class="card-title">No Votes</h5>
 | 
			
		||||
                    <p class="display-4">
 | 
			
		||||
                        {% set no_count = 0 %}
 | 
			
		||||
                        {% for vote, proposal in votes %}
 | 
			
		||||
                        {% for item in votes %}{% set vote = item.0 %}{% set proposal = item.1 %}
 | 
			
		||||
                            {% if vote.vote_type == 'No' %}
 | 
			
		||||
                                {% set no_count = no_count + 1 %}
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
@@ -128,7 +120,7 @@
 | 
			
		||||
                    <h5 class="card-title">Abstain Votes</h5>
 | 
			
		||||
                    <p class="display-4">
 | 
			
		||||
                        {% set abstain_count = 0 %}
 | 
			
		||||
                        {% for vote, proposal in votes %}
 | 
			
		||||
                        {% for item in votes %}{% set vote = item.0 %}{% set proposal = item.1 %}
 | 
			
		||||
                            {% if vote.vote_type == 'Abstain' %}
 | 
			
		||||
                                {% set abstain_count = abstain_count + 1 %}
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
@@ -140,5 +132,4 @@
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,14 +3,6 @@
 | 
			
		||||
{% block title %}Proposals - Governance Dashboard{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="container-fluid">
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <h1 class="display-5 mb-4">Governance Proposals</h1>
 | 
			
		||||
            <p class="lead">View and vote on all proposals in the system.</p>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Success message if present -->
 | 
			
		||||
    {% if success %}
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
@@ -24,7 +16,7 @@
 | 
			
		||||
    {% endif %}
 | 
			
		||||
 | 
			
		||||
    <!-- Navigation Tabs -->
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
    <div class="row mb-3">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
            <ul class="nav nav-tabs">
 | 
			
		||||
                <li class="nav-item">
 | 
			
		||||
@@ -43,6 +35,17 @@
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="col-12">
 | 
			
		||||
        <div class="alert alert-info alert-dismissible fade show">
 | 
			
		||||
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
			
		||||
            <h5><i class="bi bi-info-circle"></i> About Proposals</h5>
 | 
			
		||||
            <p>Proposals are formal requests for changes to the platform that require community approval. Each proposal includes a detailed description, implementation plan, and voting period. Browse the list below to see all active and past proposals.</p>
 | 
			
		||||
            <div class="mt-2">
 | 
			
		||||
                <a href="/governance/proposal-guidelines" class="btn btn-sm btn-outline-primary"><i class="bi bi-file-text"></i> Proposal Guidelines</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Filter Controls -->
 | 
			
		||||
    <div class="row mb-4">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
@@ -124,5 +127,4 @@
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user