feat: Remove mock proposals

This commit is contained in:
Mahmoud-Emad 2025-05-21 15:43:17 +03:00
parent 916f435dbc
commit 8f1438dc01

View File

@ -40,6 +40,43 @@ impl GovernanceController {
}) })
} }
/// Calculate statistics from the database
fn calculate_statistics_from_database(proposals: &[Proposal]) -> GovernanceStats {
let mut stats = GovernanceStats {
total_proposals: proposals.len(),
active_proposals: 0,
approved_proposals: 0,
rejected_proposals: 0,
draft_proposals: 0,
total_votes: 0,
participation_rate: 0.0,
};
// Count proposals by status
for proposal in proposals {
match proposal.status {
ProposalStatus::Active => stats.active_proposals += 1,
ProposalStatus::Approved => stats.approved_proposals += 1,
ProposalStatus::Rejected => stats.rejected_proposals += 1,
ProposalStatus::Draft => stats.draft_proposals += 1,
_ => {} // Handle other statuses if needed
}
// Count total votes
stats.total_votes += proposal.ballots.len();
}
// Calculate participation rate (if there are any proposals)
if stats.total_proposals > 0 {
// This is a simplified calculation - in a real application, you would
// calculate this based on the number of eligible voters
stats.participation_rate =
(stats.total_votes as f64 / stats.total_proposals as f64) * 100.0;
}
stats
}
/// Handles the governance dashboard page route /// Handles the governance dashboard page route
pub async fn index(tmpl: web::Data<Tera>, session: Session) -> Result<impl Responder> { pub async fn index(tmpl: web::Data<Tera>, session: Session) -> Result<impl Responder> {
let mut ctx = tera::Context::new(); let mut ctx = tera::Context::new();
@ -58,6 +95,9 @@ impl GovernanceController {
} }
}; };
// Make a copy of proposals for statistics
let proposals_for_stats = proposals.clone();
// Filter for active proposals only // Filter for active proposals only
let active_proposals: Vec<heromodels::models::Proposal> = proposals let active_proposals: Vec<heromodels::models::Proposal> = proposals
.into_iter() .into_iter()
@ -75,14 +115,15 @@ impl GovernanceController {
ctx.insert("nearest_proposal", nearest_proposal); ctx.insert("nearest_proposal", nearest_proposal);
} }
// Get recent activity for the timeline // Calculate statistics from the database
let recent_activity = Self::get_mock_recent_activity(); let stats = Self::calculate_statistics_from_database(&proposals_for_stats);
ctx.insert("recent_activity", &recent_activity);
// Get some statistics
let stats = Self::get_mock_statistics();
ctx.insert("stats", &stats); ctx.insert("stats", &stats);
// For now, we'll use empty recent activity
// In a real application, this would be populated from a database
let recent_activity = Vec::<serde_json::Value>::new();
ctx.insert("recent_activity", &recent_activity);
render_template(&tmpl, "governance/index.html", &ctx) render_template(&tmpl, "governance/index.html", &ctx)
} }
@ -334,174 +375,38 @@ impl GovernanceController {
let user = Self::get_user_from_session(&session).unwrap(); let user = Self::get_user_from_session(&session).unwrap();
ctx.insert("user", &user); ctx.insert("user", &user);
// Get mock votes for this user // Extract user ID
let votes = Self::get_mock_votes_for_user(1); // Assuming user ID 1 for mock data let user_id = user.get("id").and_then(|v| v.as_i64()).unwrap_or(1) as i32;
ctx.insert("votes", &votes);
// Get all proposals from the database
let proposals = match crate::db::proposals::get_proposals() {
Ok(props) => props,
Err(e) => {
ctx.insert("error", &format!("Failed to load proposals: {}", e));
vec![]
}
};
// Extract votes for this user from all proposals
let mut user_votes = Vec::new();
for proposal in &proposals {
// Extract votes from this proposal
let votes = Self::extract_votes_from_proposal(proposal);
// Filter votes for this user
for vote in votes {
if vote.voter_id == user_id {
user_votes.push((vote, proposal.clone()));
}
}
}
ctx.insert("votes", &user_votes);
render_template(&tmpl, "governance/my_votes.html", &ctx) render_template(&tmpl, "governance/my_votes.html", &ctx)
} }
/// Generate mock recent activity data for the dashboard // No more mock recent activity - we're using an empty vector in the index function
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
/// Generate mock proposals for testing
fn get_mock_proposals() -> Vec<Proposal> {
let now = Utc::now();
vec![
Proposal::new(
Some(1),
"1",
"Ibrahim Faraji",
"Establish Zanzibar Digital Trade Hub",
"This proposal aims to create a dedicated digital trade hub within the Zanzibar Digital Freezone to facilitate international e-commerce for local businesses. The hub will provide logistics support, digital marketing services, and regulatory compliance assistance to help Zanzibar businesses reach global markets.",
ProposalStatus::Active,
now - Duration::days(5),
now - Duration::days(5),
now - Duration::days(3),
now + Duration::days(4),
),
Proposal::new(
Some(2),
"2",
"Amina Salim",
"ZDFZ Sustainable Tourism Framework",
"A comprehensive framework for sustainable tourism development within the Zanzibar Digital Freezone. This proposal outlines environmental standards, community benefit-sharing mechanisms, and digital infrastructure for eco-tourism businesses. It includes tokenization standards for tourism assets and a certification system for sustainable operators.",
ProposalStatus::Approved,
now - Duration::days(15),
now - Duration::days(2),
now - Duration::days(14),
now - Duration::days(2),
),
Proposal::new(
Some(3),
"3",
"Hassan Mwinyi",
"Spice Industry Modernization Initiative",
"This proposal seeks to modernize Zanzibar's traditional spice industry through blockchain-based supply chain tracking, international quality certification, and digital marketplace integration. The initiative will help local spice farmers and processors access premium international markets while preserving traditional cultivation methods.",
ProposalStatus::Draft,
now - Duration::days(1),
now - Duration::days(1),
now - Duration::days(1),
now + Duration::days(1),
),
Proposal::new(
Some(4),
"4",
"Ibrahim Faraji",
"ZDFZ Regulatory Framework for Digital Financial Services",
"Establish a comprehensive regulatory framework for digital financial services within the Zanzibar Digital Freezone. This includes licensing requirements for crypto exchanges, digital payment providers, and tokenized asset platforms operating within the zone, while ensuring compliance with international AML/KYC standards.",
ProposalStatus::Rejected,
now - Duration::days(20),
now - Duration::days(5),
now - Duration::days(19),
now - Duration::days(5),
),
Proposal::new(
Some(5),
"5",
"Fatma Busaidy",
"Digital Arts Incubator and Artwork Marketplace",
"Create a dedicated digital arts incubator and Artwork marketplace to support Zanzibar's creative economy. The initiative will provide technical training, equipment, and a curated marketplace for local artists to create and sell digital art that celebrates Zanzibar's rich cultural heritage while accessing global markets.",
ProposalStatus::Active,
now - Duration::days(7),
now - Duration::days(7),
now - Duration::days(6),
now + Duration::days(1),
),
Proposal::new(
Some(6),
"6",
"Omar Makame",
"Zanzibar Renewable Energy Microgrid Network",
"Develop a network of renewable energy microgrids across the Zanzibar Digital Freezone using tokenized investment and community ownership models. This proposal outlines the technical specifications, governance structure, and token economics for deploying solar and tidal energy systems that will ensure energy independence for the zone.",
ProposalStatus::Active,
now - Duration::days(10),
now - Duration::days(9),
now - Duration::days(8),
now + Duration::days(6),
),
Proposal::new(
Some(7),
"7",
"Saida Juma",
"ZDFZ Educational Technology Initiative",
"Establish a comprehensive educational technology program within the Zanzibar Digital Freezone to develop local tech talent. This initiative includes coding academies, blockchain development courses, and digital entrepreneurship training, with a focus on preparing Zanzibar's youth for careers in the zone's growing digital economy.",
ProposalStatus::Draft,
now - Duration::days(3),
now - Duration::days(2),
now - Duration::days(1),
now + Duration::days(1),
),
]
}
/// Get a mock proposal by ID
fn get_mock_proposal_by_id(id: &str) -> Option<Proposal> {
Self::get_mock_proposals()
.into_iter()
.find(|p| p.base_data.id.to_string() == id)
}
/// Generate mock votes for a specific proposal /// Generate mock votes for a specific proposal
fn get_mock_votes_for_proposal(proposal_id: &str) -> Vec<Vote> { fn get_mock_votes_for_proposal(proposal_id: &str) -> Vec<Vote> {
@ -550,75 +455,6 @@ impl GovernanceController {
] ]
} }
/// Generate mock votes for a specific user
fn get_mock_votes_for_user(user_id: i32) -> Vec<(Vote, Proposal)> {
let votes = vec![
Vote {
id: "vote-001".to_string(),
proposal_id: "prop-001".to_string(),
voter_id: user_id,
voter_name: "Robert Callingham".to_string(),
vote_type: VoteType::Yes,
comment: Some("I strongly support this initiative.".to_string()),
created_at: Utc::now() - Duration::days(2),
updated_at: Utc::now() - Duration::days(2),
},
Vote {
id: "vote-005".to_string(),
proposal_id: "prop-002".to_string(),
voter_id: user_id,
voter_name: "Robert Callingham".to_string(),
vote_type: VoteType::No,
comment: Some("I don't think this is a priority right now.".to_string()),
created_at: Utc::now() - Duration::days(10),
updated_at: Utc::now() - Duration::days(10),
},
Vote {
id: "vote-008".to_string(),
proposal_id: "prop-004".to_string(),
voter_id: user_id,
voter_name: "Robert Callingham".to_string(),
vote_type: VoteType::Yes,
comment: None,
created_at: Utc::now() - Duration::days(18),
updated_at: Utc::now() - Duration::days(18),
},
Vote {
id: "vote-010".to_string(),
proposal_id: "prop-005".to_string(),
voter_id: user_id,
voter_name: "Robert Callingham".to_string(),
vote_type: VoteType::Yes,
comment: Some("Security is always a top priority.".to_string()),
created_at: Utc::now() - Duration::days(5),
updated_at: Utc::now() - Duration::days(5),
},
];
let proposals = Self::get_mock_proposals();
votes
.into_iter()
.filter_map(|vote| {
proposals
.iter()
.find(|p| p.base_data.id.to_string() == vote.proposal_id)
.map(|p| (vote.clone(), p.clone()))
})
.collect()
}
/// Generate mock voting results for a proposal
fn get_mock_voting_results(proposal_id: &str) -> VotingResults {
let votes = Self::get_mock_votes_for_proposal(proposal_id);
let mut results = VotingResults::new(proposal_id.to_string());
for vote in votes {
results.add_vote(&vote.vote_type);
}
results
}
/// Calculate voting results from a proposal /// Calculate voting results from a proposal
fn calculate_voting_results_from_proposal(proposal: &Proposal) -> VotingResults { fn calculate_voting_results_from_proposal(proposal: &Proposal) -> VotingResults {
let mut results = VotingResults::new(proposal.base_data.id.to_string()); let mut results = VotingResults::new(proposal.base_data.id.to_string());
@ -728,18 +564,7 @@ impl GovernanceController {
votes votes
} }
/// Generate mock statistics for the governance dashboard // The calculate_statistics_from_database function is now defined at the top of the impl block
fn get_mock_statistics() -> GovernanceStats {
GovernanceStats {
total_proposals: 5,
active_proposals: 2,
approved_proposals: 1,
rejected_proposals: 1,
draft_proposals: 1,
total_votes: 15,
participation_rate: 75.0,
}
}
} }
/// Represents the data submitted in the proposal form /// Represents the data submitted in the proposal form