diff --git a/src/web/home.rs b/src/web/home.rs index 81ba00e..49fbb4a 100644 --- a/src/web/home.rs +++ b/src/web/home.rs @@ -1,7 +1,7 @@ use axum::extract::State; use axum::response::IntoResponse; use cache_bust::asset; -use jiff::{Timestamp, Unit, Zoned, civil, tz::TimeZone}; +use jiff::{Timestamp, ToSpan, Unit, Zoned, civil, tz::TimeZone}; use maud::{Markup, html}; use sqlx::sqlite::SqlitePool; @@ -53,13 +53,40 @@ fn birthdays_section( prev_birthdays: &Vec, upcoming_birthdays: &Vec, ) -> Result { + let now = Timestamp::now().to_zoned(TimeZone::UTC); + let in_a_week = upcoming_birthdays + .iter() + .position(|b| { + now.until(&b.next_birthday.to_zoned(TimeZone::UTC).unwrap()) + .unwrap() + .compare((&1_i32.week(), &now)) + .unwrap() + != std::cmp::Ordering::Less + }) + .unwrap_or(upcoming_birthdays.len()); + let upcoming = &upcoming_birthdays + [0..std::cmp::min(std::cmp::max(3, in_a_week + 1), upcoming_birthdays.len())]; + + let a_week_ago = prev_birthdays + .iter() + .position(|b| { + now.since(&b.prev_birthday.to_zoned(TimeZone::UTC).unwrap()) + .unwrap() + .compare((&1_i32.week(), &now)) + .unwrap() + != std::cmp::Ordering::Less + }) + .unwrap_or(upcoming_birthdays.len()); + let recent = + &prev_birthdays[0..std::cmp::min(std::cmp::max(3, a_week_ago + 1), prev_birthdays.len())]; + Ok(html! { div id="birthdays" { h2 { "Birthdays" } #birthday-sections { .datelist #upcoming { h3 { "upcoming" } - @for contact in &upcoming_birthdays[0..std::cmp::min(3, upcoming_birthdays.len())] { + @for contact in upcoming { a href=(format!("/contact/{}", contact.contact_id)) { (contact.display) } @@ -70,7 +97,7 @@ fn birthdays_section( } .datelist #recent { h3 { "recent" } - @for contact in &prev_birthdays[0..std::cmp::min(3, prev_birthdays.len())] { + @for contact in recent { a href=(format!("/contact/{}", contact.contact_id)) { (contact.display) }