From: Greg Burri Date: Mon, 3 Feb 2025 22:42:07 +0000 (+0100) Subject: Add default servings to profile + choose servings when scheduling X-Git-Url: https://git.euphorik.ch/?a=commitdiff_plain;h=ae6da1a5ae248f8d55d18feb7ffeb8166916295f;p=recipes.git Add default servings to profile + choose servings when scheduling --- diff --git a/Cargo.lock b/Cargo.lock index aef3812..01a5811 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,9 +327,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "cc" @@ -1438,9 +1438,9 @@ dependencies = [ [[package]] name = "lettre" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c9a167ff73df98a5ecc07e8bf5ce90b583665da3d1762eb1f775ad4d0d6f5" +checksum = "e882e1489810a45919477602194312b1a7df0e5acc30a6188be7b520268f63f8" dependencies = [ "async-trait", "base64 0.22.1", @@ -1742,18 +1742,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" +checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" +checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" dependencies = [ "proc-macro2", "quote", diff --git a/backend/src/data/db/user.rs b/backend/src/data/db/user.rs index 4e1768e..f057d8c 100644 --- a/backend/src/data/db/user.rs +++ b/backend/src/data/db/user.rs @@ -77,7 +77,7 @@ FROM [UserLoginToken] WHERE [token] = $1 pub async fn load_user(&self, user_id: i64) -> Result> { sqlx::query_as( - "SELECT [id], [email], [name], [lang], [is_admin] FROM [User] WHERE [id] = $1", + "SELECT [id], [email], [name], [default_servings], [lang], [is_admin] FROM [User] WHERE [id] = $1", ) .bind(user_id) .fetch_optional(&self.pool) @@ -92,13 +92,17 @@ FROM [UserLoginToken] WHERE [token] = $1 user_id: i64, new_email: Option<&str>, new_name: Option<&str>, + new_default_servings: Option, new_password: Option<&str>, ) -> Result { let mut tx = self.tx().await?; let hashed_new_password = new_password.map(|p| hash(p).unwrap()); - let (email, name, hashed_password) = sqlx::query_as::<_, (String, String, String)>( - "SELECT [email], [name], [password] FROM [User] WHERE [id] = $1", + let (email, name, default_servings, hashed_password) = sqlx::query_as::< + _, + (String, String, u32, String), + >( + "SELECT [email], [name], [default_servings], [password] FROM [User] WHERE [id] = $1", ) .bind(user_id) .fetch_one(&mut *tx) @@ -144,13 +148,14 @@ WHERE [id] = $1 sqlx::query( r#" UPDATE [User] -SET [email] = $2, [name] = $3, [password] = $4 +SET [email] = $2, [name] = $3, [default_servings] = $4, [password] = $5 WHERE [id] = $1 "#, ) .bind(user_id) .bind(new_email.unwrap_or(&email)) .bind(new_name.map(str::trim).unwrap_or(&name)) + .bind(new_default_servings.unwrap_or(default_servings)) .bind(hashed_new_password.unwrap_or(hashed_password)) .execute(&mut *tx) .await?; diff --git a/backend/src/data/model.rs b/backend/src/data/model.rs index ceb7128..a6834c8 100644 --- a/backend/src/data/model.rs +++ b/backend/src/data/model.rs @@ -7,6 +7,7 @@ pub struct User { pub id: i64, pub name: String, pub email: String, + pub default_servings: u32, pub lang: String, pub is_admin: bool, } diff --git a/backend/src/html_templates.rs b/backend/src/html_templates.rs index 3ee4ff1..294f4ae 100644 --- a/backend/src/html_templates.rs +++ b/backend/src/html_templates.rs @@ -112,6 +112,7 @@ pub struct ProfileTemplate<'a> { pub username: &'a str, pub email: &'a str, + pub default_servings: u32, pub message: &'a str, pub message_email: &'a str, pub message_password: &'a str, diff --git a/backend/src/main.rs b/backend/src/main.rs index 4c07c00..5ac03eb 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -212,7 +212,7 @@ async fn main() { ) // Recipes. .route("/recipe/new", get(services::recipe::create)) - .route("/recipe/edit/{id}", get(services::recipe::edit_recipe)) + .route("/recipe/edit/{id}", get(services::recipe::edit)) .route("/recipe/view/{id}", get(services::recipe::view)) // User. .route( diff --git a/backend/src/services/recipe.rs b/backend/src/services/recipe.rs index 09eb138..799ffee 100644 --- a/backend/src/services/recipe.rs +++ b/backend/src/services/recipe.rs @@ -28,7 +28,7 @@ pub async fn create( } #[debug_handler] -pub async fn edit_recipe( +pub async fn edit( State(connection): State, Extension(user): Extension>, Extension(tr): Extension, diff --git a/backend/src/services/user.rs b/backend/src/services/user.rs index 985dc7b..ede66c5 100644 --- a/backend/src/services/user.rs +++ b/backend/src/services/user.rs @@ -655,6 +655,7 @@ pub async fn edit_user_get( ProfileTemplate { username: &user.name, email: &user.email, + default_servings: user.default_servings, message: "", message_email: "", message_password: "", @@ -673,6 +674,7 @@ pub async fn edit_user_get( pub struct EditUserForm { name: String, email: String, + default_servings: u32, password_1: String, password_2: String, } @@ -712,6 +714,7 @@ pub async fn edit_user_post( user: Some(user), username: &form_data.name, email: &form_data.email, + default_servings: form_data.default_servings, message_email: match error { ProfileUpdateError::InvalidEmail => tr.t(Sentence::InvalidEmail), ProfileUpdateError::EmailAlreadyTaken => tr.t(Sentence::EmailAlreadyTaken), @@ -760,6 +763,7 @@ pub async fn edit_user_post( user.id, Some(email_trimmed), Some(&form_data.name), + Some(form_data.default_servings), new_password, ) .await @@ -815,6 +819,7 @@ pub async fn edit_user_post( user, username: &form_data.name, email: &form_data.email, + default_servings: form_data.default_servings, message, message_email: "", message_password: "", diff --git a/backend/src/translation.rs b/backend/src/translation.rs index 9fc14c5..1e272cb 100644 --- a/backend/src/translation.rs +++ b/backend/src/translation.rs @@ -76,6 +76,7 @@ pub enum Sentence { // Profile ProfileTitle, ProfileEmail, + ProfileDefaultServings, ProfileNewPassword, ProfileFollowEmailLink, ProfileEmailSent, diff --git a/backend/templates/profile.html b/backend/templates/profile.html index 1ec5955..8bc7ec9 100644 --- a/backend/templates/profile.html +++ b/backend/templates/profile.html @@ -2,8 +2,7 @@ {% block main_container %} -{% match user %} -{% when Some with (user) %} +{% if let Some(user) = user %}

{{ tr.t(Sentence::ProfileTitle) }}

@@ -27,6 +26,14 @@ {{ message_email }} + + + @@ -40,7 +47,6 @@ {{ message }}
-{% when None %} -{% endmatch %} +{% endif %} {% endblock %} \ No newline at end of file diff --git a/backend/templates/recipe_view.html b/backend/templates/recipe_view.html index 3a2d487..231f85c 100644 --- a/backend/templates/recipe_view.html +++ b/backend/templates/recipe_view.html @@ -80,7 +80,18 @@ {% endfor %}
- {% include "calendar.html" %} + {# To create a modal dialog to choose a date and and servings #} + {% if let Some(user) = user %} +
+ {% include "calendar.html" %} + + +
+ {% endif %}
diff --git a/backend/translation.ron b/backend/translation.ron index 8089431..f99b3a3 100644 --- a/backend/translation.ron +++ b/backend/translation.ron @@ -62,6 +62,7 @@ (ProfileTitle, "Profile"), (ProfileEmail, "Email (need to be revalidated if changed)"), + (ProfileDefaultServings, "Default servings"), (ProfileNewPassword, "New password (minimum {} characters)"), (ProfileFollowEmailLink, "Follow this link to validate this email address, {}"), (ProfileEmailSent, "An email has been sent, follow the link to validate your new email"), @@ -188,6 +189,7 @@ (ProfileTitle, "Profile"), (ProfileEmail, "Email (doit être revalidé si changé)"), + (ProfileDefaultServings, "Nombre de portions par défaut"), (ProfileNewPassword, "Nouveau mot de passe (minimum {} caractères)"), (ProfileFollowEmailLink, "Suivez ce lien pour valider l'adresse email, {}"), (ProfileEmailSent, "Un email a été envoyé, suivez le lien pour valider la nouvelle adresse email"), @@ -198,7 +200,7 @@ (RecipeNotFound, "Recette non-trouvée"), (RecipeTitle, "Titre"), (RecipeDescription, "Description"), - (RecipeServings, "Nombre de personnes"), + (RecipeServings, "Nombre de portions"), (RecipeEstimatedTime, "Temps estimé"), (RecipeDifficulty, "Difficulté"), (RecipeDifficultyEasy, "Facile"), diff --git a/frontend/src/calendar.rs b/frontend/src/calendar.rs index dec6540..64c16e5 100644 --- a/frontend/src/calendar.rs +++ b/frontend/src/calendar.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::{cell::RefCell, rc::Rc}; use chrono::{offset::Local, DateTime, Datelike, Days, Months, Weekday}; use common::ron_api; @@ -19,14 +19,14 @@ struct CalendarStateInternal { #[derive(Clone)] struct CalendarState { - internal_state: Arc>, + internal_state: Rc>, } impl CalendarState { pub fn new() -> Self { let current_date = Local::now(); Self { - internal_state: Arc::new(Mutex::new(CalendarStateInternal { + internal_state: Rc::new(RefCell::new(CalendarStateInternal { displayed_date: current_date, selected_date: current_date, })), @@ -34,25 +34,25 @@ impl CalendarState { } pub fn displayed_date_next_month(&self) { - let mut locker = self.internal_state.lock().unwrap(); - locker.displayed_date = locker.displayed_date + Months::new(1); + let mut state_borrowed = self.internal_state.borrow_mut(); + state_borrowed.displayed_date = state_borrowed.displayed_date + Months::new(1); } pub fn displayed_date_previous_month(&self) { - let mut locker = self.internal_state.lock().unwrap(); - locker.displayed_date = locker.displayed_date - Months::new(1); + let mut state_borrowed = self.internal_state.borrow_mut(); + state_borrowed.displayed_date = state_borrowed.displayed_date - Months::new(1); } pub fn get_displayed_date(&self) -> DateTime { - self.internal_state.lock().unwrap().displayed_date + self.internal_state.borrow().displayed_date } pub fn get_selected_date(&self) -> DateTime { - self.internal_state.lock().unwrap().selected_date + self.internal_state.borrow().selected_date } pub fn set_selected_date(&self, date: DateTime) { - self.internal_state.lock().unwrap().selected_date = date; + self.internal_state.borrow_mut().selected_date = date; } } @@ -173,7 +173,8 @@ fn display_month(calendar: &Element, state: CalendarState) { .unwrap(); for recipe in scheduled_recipes.recipes { - log!(recipe.1); + // log!(recipe.1); + // TODO } }); } diff --git a/frontend/src/recipe_view.rs b/frontend/src/recipe_view.rs index ba30b4d..bee05c6 100644 --- a/frontend/src/recipe_view.rs +++ b/frontend/src/recipe_view.rs @@ -24,9 +24,12 @@ pub fn setup_page(recipe_id: i64) -> Result<(), JsValue> { let add_to_planner: Element = selector("#recipe-view .add-to-planner"); EventListener::new(&add_to_planner, "click", move |_event| { spawn_local(async move { - modal_dialog::show_and_initialize("#hidden-templates .calendar", async |element| { - calendar::setup(element); - }) + modal_dialog::show_and_initialize( + "#hidden-templates .date-and-servings", + async |element| { + calendar::setup(element.selector(".calendar")); + }, + ) .await; }); })