diff --git a/src/application/routes/api/brews.rs b/src/application/routes/api/brews.rs index 46511f9..53534b4 100644 --- a/src/application/routes/api/brews.rs +++ b/src/application/routes/api/brews.rs @@ -278,9 +278,7 @@ pub(crate) async fn create_brew( Ok(response) } } else if matches!(source, PayloadSource::Form) { - let target = - ListNavigator::new(BREW_PAGE_PATH, BREW_FRAGMENT_PATH, request, search).page_href(1); - Ok(Redirect::to(&target).into_response()) + Ok(Redirect::to("/").into_response()) } else { Ok((StatusCode::CREATED, Json(enriched)).into_response()) } diff --git a/src/application/routes/app/add.rs b/src/application/routes/app/add.rs index bcd1cb5..7f42b67 100644 --- a/src/application/routes/app/add.rs +++ b/src/application/routes/app/add.rs @@ -49,6 +49,16 @@ pub(crate) struct AddQuery { #[serde(rename = "type", default = "default_type")] entity_type: String, bag_id: Option, + // Brew-again overrides + coffee_weight: Option, + grinder_id: Option, + grind_setting: Option, + brewer_id: Option, + filter_paper_id: Option, + water_volume: Option, + water_temp: Option, + brew_time: Option, + quick_notes: Option, } fn default_type() -> String { @@ -75,6 +85,50 @@ pub(crate) async fn add_page( ) .map_err(map_app_error)?; + let mut defaults = brew_form.defaults; + + // Apply brew-again query param overrides + if let Some(cw) = query.coffee_weight { + defaults.coffee_weight = cw; + } + if let Some(ref gid) = query.grinder_id { + if let Some(opt) = brew_form.grinder_options.iter().find(|o| o.id == *gid) { + defaults.grinder_name = opt.label.clone(); + } + defaults.grinder_id = gid.clone(); + } + if let Some(gs) = query.grind_setting { + defaults.grind_setting = gs; + } + if let Some(ref bid) = query.brewer_id { + if let Some(opt) = brew_form.brewer_options.iter().find(|o| o.id == *bid) { + defaults.brewer_name = opt.label.clone(); + } + defaults.brewer_id = bid.clone(); + } + if let Some(ref fpid) = query.filter_paper_id { + if let Some(opt) = brew_form + .filter_paper_options + .iter() + .find(|o| o.id == *fpid) + { + defaults.filter_paper_name = opt.label.clone(); + } + defaults.filter_paper_id = fpid.clone(); + } + if let Some(wv) = query.water_volume { + defaults.water_volume = wv; + } + if let Some(wt) = query.water_temp { + defaults.water_temp = wt; + } + if let Some(bt) = query.brew_time { + defaults.brew_time = Some(bt); + } + if let Some(ref qn) = query.quick_notes { + defaults.quick_notes_raw.clone_from(qn); + } + let template = AddTemplate { nav_active: "data", is_authenticated, @@ -99,7 +153,7 @@ pub(crate) async fn add_page( brewer_options: brew_form.brewer_options, filter_paper_options: brew_form.filter_paper_options, cafe_options, - defaults: brew_form.defaults, + defaults, quick_note_options: brew_form.quick_note_options, pre_select_bag_id: query.bag_id, }; diff --git a/src/presentation/web/views/brews.rs b/src/presentation/web/views/brews.rs index 736deea..0f9c918 100644 --- a/src/presentation/web/views/brews.rs +++ b/src/presentation/web/views/brews.rs @@ -1,3 +1,5 @@ +use std::fmt::Write; + use crate::domain::brews::{BrewWithDetails, QuickNote, format_brew_time}; use super::relative_date; @@ -126,6 +128,30 @@ impl BrewView { brew_time_raw: brew.brew.brew_time, } } + + /// Build a URL to the add-brew form pre-filled with this brew's parameters. + pub fn brew_again_url(&self) -> String { + let mut url = format!( + "/add?type=brew&bag_id={}&coffee_weight={}&grinder_id={}&grind_setting={}&brewer_id={}&water_volume={}&water_temp={}", + self.bag_id, + self.coffee_weight_raw, + self.grinder_id, + self.grind_setting_raw, + self.brewer_id, + self.water_volume_raw, + self.water_temp_raw, + ); + if let Some(fp_id) = self.filter_paper_id { + let _ = write!(url, "&filter_paper_id={fp_id}"); + } + if let Some(bt) = self.brew_time_raw { + let _ = write!(url, "&brew_time={bt}"); + } + if !self.quick_notes_raw.is_empty() { + let _ = write!(url, "&quick_notes={}", self.quick_notes_raw); + } + url + } } pub struct BrewDefaultsView { @@ -141,6 +167,8 @@ pub struct BrewDefaultsView { pub water_volume: i32, pub water_temp: f64, pub brew_time: Option, + /// Comma-separated quick note form values (e.g. "good,too-fast") for pre-filling toggles. + pub quick_notes_raw: String, } impl Default for BrewDefaultsView { @@ -158,6 +186,7 @@ impl Default for BrewDefaultsView { water_volume: 250, water_temp: 91.0, brew_time: Some(120), + quick_notes_raw: String::new(), } } } @@ -181,6 +210,7 @@ impl From for BrewDefaultsView { water_volume: brew.brew.water_volume, water_temp: brew.brew.water_temp, brew_time: brew.brew.brew_time, + quick_notes_raw: String::new(), } } } diff --git a/templates/pages/add.html b/templates/pages/add.html index c415a6e..5aea1f9 100644 --- a/templates/pages/add.html +++ b/templates/pages/add.html @@ -89,12 +89,12 @@ data-signals:_user-lat="0" data-signals:_user-lng="0" data-signals:_reviewing-cafe="false" - data-signals:_qn-good="false" - data-signals:_qn-too-fast="false" - data-signals:_qn-too-slow="false" - data-signals:_qn-too-hot="false" - data-signals:_qn-under-extracted="false" - data-signals:_qn-over-extracted="false" + data-signals:_qn-good="{% if defaults.quick_notes_raw.contains("good") %}true{% else %}false{% endif %}" + data-signals:_qn-too-fast="{% if defaults.quick_notes_raw.contains("too-fast") %}true{% else %}false{% endif %}" + data-signals:_qn-too-slow="{% if defaults.quick_notes_raw.contains("too-slow") %}true{% else %}false{% endif %}" + data-signals:_qn-too-hot="{% if defaults.quick_notes_raw.contains("too-hot") %}true{% else %}false{% endif %}" + data-signals:_qn-under-extracted="{% if defaults.quick_notes_raw.contains("under-extracted") %}true{% else %}false{% endif %}" + data-signals:_qn-over-extracted="{% if defaults.quick_notes_raw.contains("over-extracted") %}true{% else %}false{% endif %}" >

Manual Add

diff --git a/templates/partials/brew_card.html b/templates/partials/brew_card.html index 0632c79..0835854 100644 --- a/templates/partials/brew_card.html +++ b/templates/partials/brew_card.html @@ -2,33 +2,13 @@ {% macro card(brew, is_authenticated) %}
{% if is_authenticated %} -
- - - - - - {% if let Some(fp_id) = brew.filter_paper_id %} - - {% endif %} - - - - {% if let Some(bt) = brew.brew_time_raw %} - - {% endif %} - -
+ {{ icons::refresh("h-4.5 w-4.5") }} + {% endif %}
{{ brew.roast_name }} diff --git a/templates/partials/lists/brew_list.html b/templates/partials/lists/brew_list.html index fb4f16b..461a455 100644 --- a/templates/partials/lists/brew_list.html +++ b/templates/partials/lists/brew_list.html @@ -3,26 +3,10 @@ {% macro brew_actions(brew, navigator) %}
-
- - - - - - {% if let Some(fp_id) = brew.filter_paper_id %} - - {% endif %} - - - - {% if let Some(bt) = brew.brew_time_raw %} - - {% endif %} - -
+ + {{ icons::plus_circle("h-4 w-4") }} Brew Again +