feat: Add total vote counts to governance views

- Add functionality to calculate total yes, no, and abstain votes
  across all proposals. This provides a summary of community
  voting patterns on the governance page.
- Improve the user experience by displaying total vote counts
  prominently on the "My Votes" page. This gives users a quick
  overview of the overall voting results.
- Enhance the "Create Proposal" page with informative guidelines
  and a helpful alert to guide users through the proposal creation
  process.  This improves clarity and ensures proposals are well-
  structured.
This commit is contained in:
Mahmoud-Emad 2025-05-22 16:08:12 +03:00
parent 4659697ae2
commit fad288f67d
3 changed files with 106 additions and 71 deletions

View File

@ -443,6 +443,12 @@ impl GovernanceController {
} }
} }
// Calculate total vote counts for all proposals
let total_vote_counts = Self::calculate_total_vote_counts(&proposals);
ctx.insert("total_yes_votes", &total_vote_counts.0);
ctx.insert("total_no_votes", &total_vote_counts.1);
ctx.insert("total_abstain_votes", &total_vote_counts.2);
ctx.insert("votes", &user_votes); ctx.insert("votes", &user_votes);
render_template(&tmpl, "governance/my_votes.html", &ctx) render_template(&tmpl, "governance/my_votes.html", &ctx)
@ -607,6 +613,30 @@ impl GovernanceController {
} }
// The calculate_statistics_from_database function is now defined at the top of the impl block // The calculate_statistics_from_database function is now defined at the top of the impl block
/// Calculate total vote counts across all proposals
/// Returns a tuple of (yes_count, no_count, abstain_count)
fn calculate_total_vote_counts(proposals: &[Proposal]) -> (usize, usize, usize) {
let mut yes_count = 0;
let mut no_count = 0;
let mut abstain_count = 0;
for proposal in proposals {
// Extract votes from this proposal
let votes = Self::extract_votes_from_proposal(proposal);
// Count votes by type
for vote in votes {
match vote.vote_type {
VoteType::Yes => yes_count += 1,
VoteType::No => no_count += 1,
VoteType::Abstain => abstain_count += 1,
}
}
}
(yes_count, no_count, abstain_count)
}
} }
/// Represents the data submitted in the proposal form /// Represents the data submitted in the proposal form

View File

@ -4,13 +4,6 @@
{% block content %} {% block content %}
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-4">
<div class="col-12">
<h1 class="display-5 mb-4">Create Governance Proposal</h1>
<p class="lead">Submit a new proposal for the community to vote on.</p>
</div>
</div>
<!-- Navigation Tabs --> <!-- Navigation Tabs -->
<div class="row mb-4"> <div class="row mb-4">
<div class="col-12"> <div class="col-12">
@ -30,11 +23,26 @@
</ul> </ul>
</div> </div>
</div> </div>
<!-- Proposal Form --> <!-- Info Alert -->
<div class="row">
<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 Creating Proposals</h5>
<p>Creating a proposal is an important step in our community governance process. Well-crafted proposals clearly state the problem, solution, and implementation details. The community will review and vote on your proposal, so be thorough and thoughtful in your submission.</p>
<div class="mt-2">
<a href="/governance/proposal-templates" class="btn btn-sm btn-outline-primary"><i class="bi bi-file-earmark-text"></i> Proposal Templates</a>
</div>
</div>
</div>
</div>
<!-- Proposal Form and Guidelines in Flex Layout -->
<div class="row mb-4"> <div class="row mb-4">
<div class="col-md-8 mx-auto"> <!-- Proposal Form Column -->
<div class="card"> <div class="col-lg-8">
<div class="card h-100">
<div class="card-header"> <div class="card-header">
<h5 class="mb-0">New Proposal</h5> <h5 class="mb-0">New Proposal</h5>
</div> </div>
@ -49,7 +57,7 @@
<div class="mb-3"> <div class="mb-3">
<label for="description" class="form-label">Description</label> <label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="6" required <textarea class="form-control" id="description" name="description" rows="8" required
placeholder="Provide a detailed description of your proposal..."></textarea> placeholder="Provide a detailed description of your proposal..."></textarea>
<div class="form-text">Explain the purpose, benefits, and implementation details</div> <div class="form-text">Explain the purpose, benefits, and implementation details</div>
</div> </div>
@ -84,12 +92,10 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Guidelines Column -->
<!-- Guidelines Card --> <div class="col-lg-4">
<div class="row mb-4"> <div class="card bg-light h-100">
<div class="col-md-8 mx-auto">
<div class="card bg-light">
<div class="card-header"> <div class="card-header">
<h5 class="mb-0">Proposal Guidelines</h5> <h5 class="mb-0">Proposal Guidelines</h5>
</div> </div>

View File

@ -23,6 +23,57 @@
</div> </div>
</div> </div>
<!-- Info Alert -->
<div class="row">
<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 Votes</h5>
<p>Voting is a fundamental right of all token holders in our governance system. Each vote carries weight
proportional to your token holdings, ensuring fair representation. The voting statistics below show the
community's collective decision-making across all proposals.</p>
<div class="mt-2">
<a href="/governance/voting-guide" class="btn btn-sm btn-outline-primary"><i
class="bi bi-check2-square"></i> Voting Guide</a>
</div>
</div>
</div>
</div>
<!-- Voting Stats -->
<div class="row mb-4">
<div class="col-md-4 mb-3">
<div class="card text-white bg-success h-100">
<div class="card-body text-center">
<h5 class="card-title">Yes Votes</h5>
<p class="display-4">
{{ total_yes_votes }}
</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-white bg-danger h-100">
<div class="card-body text-center">
<h5 class="card-title">No Votes</h5>
<p class="display-4">
{{ total_no_votes }}
</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-white bg-secondary h-100">
<div class="card-body text-center">
<h5 class="card-title">Abstain Votes</h5>
<p class="display-4">
{{ total_abstain_votes }}
</p>
</div>
</div>
</div>
</div>
<!-- My Votes List --> <!-- My Votes List -->
<div class="row mb-4"> <div class="row mb-4">
<div class="col-12"> <div class="col-12">
@ -82,57 +133,5 @@
</div> </div>
</div> </div>
<!-- Voting Stats -->
{% if votes | length > 0 %}
<div class="row mb-4">
<div class="col-md-4 mb-3">
<div class="card text-white bg-success h-100">
<div class="card-body text-center">
<h5 class="card-title">Yes Votes</h5>
<p class="display-4">
{% set yes_count = 0 %}
{% for item in votes %}{% set vote = item.0 %}{% set proposal = item.1 %}
{% if vote.vote_type == 'Yes' %}
{% set yes_count = yes_count + 1 %}
{% endif %}
{% endfor %}
{{ yes_count }}
</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-white bg-danger h-100">
<div class="card-body text-center">
<h5 class="card-title">No Votes</h5>
<p class="display-4">
{% set no_count = 0 %}
{% for item in votes %}{% set vote = item.0 %}{% set proposal = item.1 %}
{% if vote.vote_type == 'No' %}
{% set no_count = no_count + 1 %}
{% endif %}
{% endfor %}
{{ no_count }}
</p>
</div>
</div>
</div>
<div class="col-md-4 mb-3">
<div class="card text-white bg-secondary h-100">
<div class="card-body text-center">
<h5 class="card-title">Abstain Votes</h5>
<p class="display-4">
{% set abstain_count = 0 %}
{% for item in votes %}{% set vote = item.0 %}{% set proposal = item.1 %}
{% if vote.vote_type == 'Abstain' %}
{% set abstain_count = abstain_count + 1 %}
{% endif %}
{% endfor %}
{{ abstain_count }}
</p>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %} {% endblock %}