use chrono::Local;
use colored::{ColoredString, Colorize};
use uuid::Uuid;
use crate::models::{Project, Task};
pub fn project_name(project_id: Option<Uuid>, projects: &[Project]) -> &str {
project_id
.and_then(|pid| projects.iter().find(|p| p.uuid == pid && !p.is_deleted()))
.map(|p| p.name.as_str())
.unwrap_or("—")
}
pub fn project_colored(name: &str) -> ColoredString {
if name == "—" {
name.dimmed()
} else {
name.magenta()
}
}
pub fn due_relative_text(due: chrono::NaiveDate) -> String {
due.format("%Y-%m-%d").to_string()
}
pub fn get_due_text(task: &Task) -> String {
task.due_date.map(due_relative_text).unwrap_or_default()
}
pub fn get_due_colored(task: &Task, text: &str) -> ColoredString {
if text.is_empty() {
return "".normal();
}
if task.completed {
return text.dimmed();
}
if let Some(due) = task.due_date {
let today = Local::now().naive_local().date();
let days_until = (due - today).num_days();
if days_until < 0 {
text.red().bold()
} else if days_until == 0 {
text.yellow().bold()
} else if days_until <= 7 {
text.yellow()
} else {
text.cyan()
}
} else {
text.normal()
}
}
pub fn truncate(text: &str, max: usize) -> String {
if text.chars().count() <= max {
text.to_string()
} else {
let truncated: String = text.chars().take(max.saturating_sub(3)).collect();
format!("{}...", truncated)
}
}