feat: Enhance Governance Controller and Proposal Handling

- Improve proposal search to include description field: This
  allows for more comprehensive search results.
- Fix redirect after voting: The redirect now correctly handles
  the success message.
- Handle potential invalid timestamps in ballots: The code now
  gracefully handles ballots with invalid timestamps, preventing
  crashes and using the current time as a fallback.
- Add local time formatting function:  This provides a way to
  display dates and times in the user's local timezone.
- Update database path: This simplifies the database setup.
- Improve proposal vote handling: Addresses issues with vote
  submission and timestamping.
- Add client-side pagination and filtering to proposal details:
  Improves user experience for viewing large vote lists.
This commit is contained in:
Mahmoud-Emad
2025-05-25 10:48:02 +03:00
parent 97e7a04827
commit d12a082ca1
4 changed files with 142 additions and 70 deletions

View File

@@ -30,6 +30,7 @@ impl std::error::Error for TemplateError {}
pub fn register_tera_functions(tera: &mut tera::Tera) {
tera.register_function("now", NowFunction);
tera.register_function("format_date", FormatDateFunction);
tera.register_function("local_time", LocalTimeFunction);
}
/// Tera function to get the current date/time
@@ -93,6 +94,52 @@ impl Function for FormatDateFunction {
}
}
/// Tera function to convert UTC datetime to local time
#[derive(Clone)]
pub struct LocalTimeFunction;
impl Function for LocalTimeFunction {
fn call(&self, args: &std::collections::HashMap<String, Value>) -> tera::Result<Value> {
let datetime_value = match args.get("datetime") {
Some(val) => val,
None => return Err(tera::Error::msg("The 'datetime' argument is required")),
};
let format = match args.get("format") {
Some(val) => match val.as_str() {
Some(s) => s,
None => "%Y-%m-%d %H:%M",
},
None => "%Y-%m-%d %H:%M",
};
// The datetime comes from Rust as a serialized DateTime<Utc>
// We need to handle it properly
let utc_datetime = if let Some(dt_str) = datetime_value.as_str() {
// Try to parse as RFC3339 first
match DateTime::parse_from_rfc3339(dt_str) {
Ok(dt) => dt.with_timezone(&Utc),
Err(_) => {
// Try to parse as our standard format
match DateTime::parse_from_str(dt_str, "%Y-%m-%d %H:%M:%S%.f UTC") {
Ok(dt) => dt.with_timezone(&Utc),
Err(_) => return Err(tera::Error::msg("Invalid datetime string format")),
}
}
}
} else {
return Err(tera::Error::msg("Datetime must be a string"));
};
// Convert UTC to local time (EEST = UTC+3)
// In a real application, you'd want to get the user's timezone from their profile
let local_offset = chrono::FixedOffset::east_opt(3 * 3600).unwrap(); // +3 hours for EEST
let local_datetime = utc_datetime.with_timezone(&local_offset);
Ok(Value::String(local_datetime.format(format).to_string()))
}
}
/// Formats a date for display
#[allow(dead_code)]
pub fn format_date(date: &DateTime<Utc>, format: &str) -> String {