feat: Improve user experience after voting on proposals
- Redirect users to the proposal detail page with a success message after a successful vote, improving feedback. - Automatically remove the success message from the URL after a short time to avoid URL clutter and maintain a clean browsing experience. - Add a success alert message on the proposal detail page to provide immediate visual confirmation of a successful vote. - Improve the visual presentation of the votes list on the proposal detail page by adding top margin for better spacing.
This commit is contained in:
parent
52fbc77e3e
commit
3d8aca19cc
@ -196,9 +196,13 @@ impl GovernanceController {
|
||||
/// Handles the proposal detail page route
|
||||
pub async fn proposal_detail(
|
||||
path: web::Path<String>,
|
||||
req: actix_web::HttpRequest,
|
||||
tmpl: web::Data<Tera>,
|
||||
session: Session,
|
||||
) -> Result<impl Responder> {
|
||||
// Extract query parameters from the request
|
||||
let query_str = req.query_string();
|
||||
let vote_success = query_str.contains("vote_success=true");
|
||||
let proposal_id = path.into_inner();
|
||||
let mut ctx = tera::Context::new();
|
||||
ctx.insert("active_page", "governance");
|
||||
@ -220,6 +224,11 @@ impl GovernanceController {
|
||||
// Calculate voting results directly from the proposal
|
||||
let results = Self::calculate_voting_results_from_proposal(&proposal);
|
||||
ctx.insert("results", &results);
|
||||
|
||||
// Check if vote_success parameter is present and add success message
|
||||
if vote_success {
|
||||
ctx.insert("success", "Your vote has been successfully recorded!");
|
||||
}
|
||||
|
||||
render_template(&tmpl, "governance/proposal_detail.html", &ctx)
|
||||
} else {
|
||||
@ -392,18 +401,10 @@ impl GovernanceController {
|
||||
form.comment.as_ref().map(|s| s.to_string()), // Pass the comment from the form
|
||||
) {
|
||||
Ok(updated_proposal) => {
|
||||
ctx.insert("proposal", &updated_proposal);
|
||||
ctx.insert("success", "Your vote has been recorded!");
|
||||
|
||||
// Extract votes directly from the updated proposal
|
||||
let votes = Self::extract_votes_from_proposal(&updated_proposal);
|
||||
ctx.insert("votes", &votes);
|
||||
|
||||
// Calculate voting results directly from the updated proposal
|
||||
let results = Self::calculate_voting_results_from_proposal(&updated_proposal);
|
||||
ctx.insert("results", &results);
|
||||
|
||||
render_template(&tmpl, "governance/proposal_detail.html", &ctx)
|
||||
// Redirect to the proposal detail page with a success message
|
||||
return Ok(HttpResponse::Found()
|
||||
.append_header(("Location", format!("/governance/proposals/{}?vote_success=true", proposal_id)))
|
||||
.finish());
|
||||
}
|
||||
Err(e) => {
|
||||
ctx.insert("error", &format!("Failed to submit vote: {}", e));
|
||||
|
@ -240,7 +240,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Votes List -->
|
||||
<div class="row">
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-light d-flex justify-content-between align-items-center flex-wrap">
|
||||
@ -338,6 +338,23 @@
|
||||
{% block scripts %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Remove query parameters from URL without refreshing the page
|
||||
if (window.location.search.includes('vote_success=true')) {
|
||||
const newUrl = window.location.pathname;
|
||||
window.history.replaceState({}, document.title, newUrl);
|
||||
|
||||
// Auto-hide the success alert after 5 seconds
|
||||
const successAlert = document.querySelector('.alert-success');
|
||||
if (successAlert) {
|
||||
setTimeout(function() {
|
||||
successAlert.classList.remove('show');
|
||||
setTimeout(function() {
|
||||
successAlert.remove();
|
||||
}, 500);
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
// Vote filtering using data-filter attributes
|
||||
const filterButtons = document.querySelectorAll('[data-filter]');
|
||||
const voteRows = document.querySelectorAll('.vote-row');
|
||||
|
Loading…
Reference in New Issue
Block a user