diff --git a/Cargo.lock b/Cargo.lock index 274a840..1b0056b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2456,6 +2456,7 @@ dependencies = [ "serde", "skjera_api", "sqlx", + "time", "tokio", "tower-http", "tracing", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 4be70b4..cc885d5 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -24,3 +24,4 @@ tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } url = "2.5.4" headers = "0.4.0" once_cell = "1.20.2" +time = "0.3.37" diff --git a/backend/src/employee.rs b/backend/src/employee.rs index 8c32943..653246e 100644 --- a/backend/src/employee.rs +++ b/backend/src/employee.rs @@ -1,12 +1,12 @@ use sqlx::*; +use sqlx::types::time::Date; #[derive(Debug, Clone, sqlx::FromRow)] pub struct Employee { pub id: i64, pub email: String, pub name: String, - pub dob_month: Option, - pub dob_day: Option, + pub dob: Option // pub some_accounts: Vec, } @@ -23,7 +23,7 @@ impl EmployeeDao { pub(crate) async fn employees(&self) -> Result, Error> { sqlx::query_as!( Employee, - "SELECT id, email, name, dob_month, dob_day FROM skjera.employee" + "SELECT id, email, name, dob FROM skjera.employee" ) .fetch_all(&self.pool) .await @@ -32,7 +32,7 @@ impl EmployeeDao { pub(crate) async fn employee_by_id(&self, id: i64) -> Result, Error> { sqlx::query_as!( Employee, - "SELECT id, email, name, dob_month, dob_day FROM skjera.employee WHERE id=$1", + "SELECT id, email, name, dob FROM skjera.employee WHERE id=$1", id ) .fetch_optional(&self.pool) @@ -42,7 +42,7 @@ impl EmployeeDao { pub(crate) async fn employee_by_email(&self, email: String) -> Result, Error> { sqlx::query_as!( Employee, - "SELECT id, email, name, dob_month, dob_day FROM skjera.employee WHERE email=$1", + "SELECT id, email, name, dob FROM skjera.employee WHERE email=$1", email ) .fetch_optional(&self.pool) @@ -52,10 +52,9 @@ impl EmployeeDao { pub(crate) async fn update(&self, employee: &Employee) -> Result { sqlx::query_as!( Employee, - "UPDATE skjera.employee SET dob_month=$1, dob_day=$2 WHERE id=$3 - RETURNING id, email, name, dob_month, dob_day", - employee.dob_month, - employee.dob_day, + "UPDATE skjera.employee SET dob=$1 WHERE id=$2 + RETURNING id, email, name, dob", + employee.dob, employee.id, ) .fetch_one(&self.pool) diff --git a/backend/src/html.rs b/backend/src/html.rs index be877da..2be36ea 100644 --- a/backend/src/html.rs +++ b/backend/src/html.rs @@ -7,6 +7,7 @@ use axum::response::{Html, Redirect}; use axum::Form; use once_cell::sync::Lazy; use serde::Deserialize; +use time::{format_description, Date, Month}; use tracing::debug; use url; use url::Url; @@ -50,8 +51,8 @@ pub async fn get_me( let template = MeTemplate { month_names: MONTH_NAMES.as_slice(), days: (1..31).collect::>(), - dob_month: me.dob_month.unwrap_or_default().try_into().unwrap_or_default(), - dob_day: me.dob_day.unwrap_or_default().try_into().unwrap_or_default(), + dob_month: me.dob.map(|d| d.month() as usize).unwrap_or_default(), + dob_day: me.dob.map(|d| d.day() as usize).unwrap_or_default(), }; Ok(Html(template.render()?)) @@ -59,8 +60,8 @@ pub async fn get_me( #[derive(Deserialize, Debug)] pub(crate) struct MeForm { - dob_month: i32, - dob_day: i32, + dob_month: u8, + dob_day: u8, } pub async fn post_me( @@ -76,14 +77,19 @@ pub async fn post_me( .await? .context("error loading me")?; - if input.dob_month >= 1 && input.dob_day >= 1 { - me.dob_month = Some(input.dob_month); - me.dob_day = Some(input.dob_day); + let year = me.dob.map(|dob| dob.year()).unwrap_or_else(|| 1900); + let month: Option = input.dob_month.try_into().ok(); - me = app.employee_dao.update(&me).await?; + let dob: Option = match (month, input.dob_day) { + (Some(m), d) if d >= 1 => Date::from_calendar_date(year, m, d).ok(), + _ => None, + }; - debug!("Updated Employee: {:?}", me); - } + me.dob = dob; + + me = app.employee_dao.update(&me).await?; + + debug!("Updated Employee: {:?}", me); Ok(Redirect::to("/")) } @@ -96,8 +102,12 @@ struct EmployeeTemplate { impl EmployeeTemplate { pub fn dob(&self) -> String { - match (self.employee.dob_month, self.employee.dob_day) { - (Some(m), Some(d)) => format!("{}-{}", m, d), + let f = format_description::parse("[year]-[month]-[day]") + .ok() + .unwrap(); + + match self.employee.dob { + Some(dob) => dob.format(&f).ok().unwrap_or_default(), _ => "".to_string(), } } diff --git a/backend/src/skjera.rs b/backend/src/skjera.rs index 022d027..8a00d15 100644 --- a/backend/src/skjera.rs +++ b/backend/src/skjera.rs @@ -16,7 +16,7 @@ impl Skjera for ServerImpl { host: Host, cookies: CookieJar, ) -> Result { - let employees = sqlx::query_as!(Employee, "SELECT id, email, name, dob_month, dob_day FROM skjera.employee") + let employees = sqlx::query_as!(Employee, "SELECT id, email, name, dob FROM skjera.employee") .fetch_all(&self.pool) .await .map_err(|e| { diff --git a/backend/templates/hello.html b/backend/templates/hello.html index b9bc153..a621313 100644 --- a/backend/templates/hello.html +++ b/backend/templates/hello.html @@ -27,7 +27,9 @@

Employees

{{ employee.name }} - {{ employee.dob_day|fmt("{:?}") }} {{ employee.dob_month|fmt("{:?}") }} + {% if let Some(dob) = employee.dob %} + {{ dob.day()|fmt("{:?}") }}{{ dob.month()|fmt("{:?}") }} + {% endif %} {% endfor %} diff --git a/backend/templates/me.html b/backend/templates/me.html index 37aae28..596185f 100644 --- a/backend/templates/me.html +++ b/backend/templates/me.html @@ -7,7 +7,7 @@

Edit profile

month: {{ dob_month }}
- day: {{ dob_day }} + day: {{ dob_day }}

diff --git a/migrations/20241231152001_dob.sql b/migrations/20241231152001_dob.sql new file mode 100644 index 0000000..e01ddcf --- /dev/null +++ b/migrations/20241231152001_dob.sql @@ -0,0 +1,11 @@ +ALTER TABLE skjera.employee + DROP COLUMN IF EXISTS dob_month, + DROP COLUMN IF EXISTS dob_day, + DROP COLUMN IF EXISTS dob; + +ALTER TABLE skjera.employee + ADD COLUMN dob DATE; + +UPDATE skjera.employee +SET dob = '1980-12-09' +WHERE email = 'trygvis@scienta.no';