fix(brews): improve table layout and add "brew again" feature
- Combine weight/water/ratio into single "Recipe" column - Reorder columns: Coffee, Grind, Recipe, Temp, Brewer, Date, Actions - Style actions column with icon buttons (consistent with roasts) - Add "brew again" button to repeat a brew with same parameters - Use data-model for form inputs (fixes Datastar binding error) - Add raw values to BrewView for repeat brew functionality
This commit is contained in:
parent
7e579cb2d1
commit
9402d98bb6
3 changed files with 43 additions and 7 deletions
|
|
@ -585,19 +585,26 @@ impl GearView {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BrewView {
|
pub struct BrewView {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub bag_id: String,
|
pub bag_id: i64,
|
||||||
pub roast_name: String,
|
pub roast_name: String,
|
||||||
pub roaster_name: String,
|
pub roaster_name: String,
|
||||||
pub roast_slug: String,
|
pub roast_slug: String,
|
||||||
pub roaster_slug: String,
|
pub roaster_slug: String,
|
||||||
pub coffee_weight: String,
|
pub coffee_weight: String,
|
||||||
|
pub grinder_id: i64,
|
||||||
pub grinder_name: String,
|
pub grinder_name: String,
|
||||||
pub grind_setting: String,
|
pub grind_setting: String,
|
||||||
|
pub brewer_id: i64,
|
||||||
pub brewer_name: String,
|
pub brewer_name: String,
|
||||||
pub water_volume: String,
|
pub water_volume: String,
|
||||||
pub water_temp: String,
|
pub water_temp: String,
|
||||||
pub ratio: String,
|
pub ratio: String,
|
||||||
pub created_at: String,
|
pub created_at: String,
|
||||||
|
// Raw values for "brew again" feature
|
||||||
|
pub coffee_weight_raw: f64,
|
||||||
|
pub grind_setting_raw: f64,
|
||||||
|
pub water_volume_raw: i32,
|
||||||
|
pub water_temp_raw: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BrewView {
|
impl BrewView {
|
||||||
|
|
@ -613,19 +620,25 @@ impl BrewView {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
id: brew.brew.id.to_string(),
|
id: brew.brew.id.to_string(),
|
||||||
bag_id: brew.brew.bag_id.to_string(),
|
bag_id: brew.brew.bag_id.into_inner(),
|
||||||
roast_name: brew.roast_name,
|
roast_name: brew.roast_name,
|
||||||
roaster_name: brew.roaster_name,
|
roaster_name: brew.roaster_name,
|
||||||
roast_slug: brew.roast_slug,
|
roast_slug: brew.roast_slug,
|
||||||
roaster_slug: brew.roaster_slug,
|
roaster_slug: brew.roaster_slug,
|
||||||
coffee_weight: format!("{:.1}g", brew.brew.coffee_weight),
|
coffee_weight: format!("{:.1}g", brew.brew.coffee_weight),
|
||||||
|
grinder_id: brew.brew.grinder_id.into_inner(),
|
||||||
grinder_name: brew.grinder_name,
|
grinder_name: brew.grinder_name,
|
||||||
grind_setting: format!("{:.1}", brew.brew.grind_setting),
|
grind_setting: format!("{:.1}", brew.brew.grind_setting),
|
||||||
|
brewer_id: brew.brew.brewer_id.into_inner(),
|
||||||
brewer_name: brew.brewer_name,
|
brewer_name: brew.brewer_name,
|
||||||
water_volume: format!("{}ml", brew.brew.water_volume),
|
water_volume: format!("{}ml", brew.brew.water_volume),
|
||||||
water_temp: format!("{:.1}\u{00B0}C", brew.brew.water_temp),
|
water_temp: format!("{:.1}\u{00B0}C", brew.brew.water_temp),
|
||||||
ratio,
|
ratio,
|
||||||
created_at: brew.brew.created_at.format("%Y-%m-%d %H:%M").to_string(),
|
created_at: brew.brew.created_at.format("%Y-%m-%d %H:%M").to_string(),
|
||||||
|
coffee_weight_raw: brew.brew.coffee_weight,
|
||||||
|
grind_setting_raw: brew.brew.grind_setting,
|
||||||
|
water_volume_raw: brew.brew.water_volume,
|
||||||
|
water_temp_raw: brew.brew.water_temp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@
|
||||||
<span class="text-stone-700">Coffee (g) *</span>
|
<span class="text-stone-700">Coffee (g) *</span>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button type="button" class="btn-adjust" data-on:click="$weight = Math.max(1, $weight - 1)">-</button>
|
<button type="button" class="btn-adjust" data-on:click="$weight = Math.max(1, $weight - 1)">-</button>
|
||||||
<input type="number" name="coffee_weight" step="0.5" min="1" required class="input-field flex-1 text-center" value="15.0" data-bind:value="$weight" />
|
<input type="number" name="coffee_weight" step="0.5" min="1" required class="input-field flex-1 text-center" data-attr:value="$weight" data-on:input="$weight = this.valueAsNumber" />
|
||||||
<button type="button" class="btn-adjust" data-on:click="$weight = $weight + 1">+</button>
|
<button type="button" class="btn-adjust" data-on:click="$weight = $weight + 1">+</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -102,7 +102,7 @@
|
||||||
<span class="text-stone-700">Grind Setting *</span>
|
<span class="text-stone-700">Grind Setting *</span>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button type="button" class="btn-adjust" data-on:click="$grind = Math.max(0, $grind - 0.5)">-</button>
|
<button type="button" class="btn-adjust" data-on:click="$grind = Math.max(0, $grind - 0.5)">-</button>
|
||||||
<input type="number" name="grind_setting" step="0.5" min="0" required class="input-field flex-1 text-center" value="6.0" data-bind:value="$grind" />
|
<input type="number" name="grind_setting" step="0.5" min="0" required class="input-field flex-1 text-center" data-attr:value="$grind" data-on:input="$grind = this.valueAsNumber" />
|
||||||
<button type="button" class="btn-adjust" data-on:click="$grind = $grind + 0.5">+</button>
|
<button type="button" class="btn-adjust" data-on:click="$grind = $grind + 0.5">+</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -112,7 +112,7 @@
|
||||||
<span class="text-stone-700">Water (ml) *</span>
|
<span class="text-stone-700">Water (ml) *</span>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button type="button" class="btn-adjust" data-on:click="$volume = Math.max(10, $volume - 10)">-</button>
|
<button type="button" class="btn-adjust" data-on:click="$volume = Math.max(10, $volume - 10)">-</button>
|
||||||
<input type="number" name="water_volume" step="10" min="10" required class="input-field flex-1 text-center" value="250" data-bind:value="$volume" />
|
<input type="number" name="water_volume" step="10" min="10" required class="input-field flex-1 text-center" data-attr:value="$volume" data-on:input="$volume = this.valueAsNumber" />
|
||||||
<button type="button" class="btn-adjust" data-on:click="$volume = $volume + 10">+</button>
|
<button type="button" class="btn-adjust" data-on:click="$volume = $volume + 10">+</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -122,7 +122,7 @@
|
||||||
<span class="text-stone-700">Temp (C) *</span>
|
<span class="text-stone-700">Temp (C) *</span>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button type="button" class="btn-adjust" data-on:click="$temp = Math.max(0, $temp - 0.5)">-</button>
|
<button type="button" class="btn-adjust" data-on:click="$temp = Math.max(0, $temp - 0.5)">-</button>
|
||||||
<input type="number" name="water_temp" step="0.5" min="0" max="100" required class="input-field flex-1 text-center" value="91.0" data-bind:value="$temp" />
|
<input type="number" name="water_temp" step="0.5" min="0" max="100" required class="input-field flex-1 text-center" data-attr:value="$temp" data-on:input="$temp = this.valueAsNumber" />
|
||||||
<button type="button" class="btn-adjust" data-on:click="$temp = Math.min(100, $temp + 0.5)">+</button>
|
<button type="button" class="btn-adjust" data-on:click="$temp = Math.min(100, $temp + 0.5)">+</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
<th scope="col" class="px-4 py-3">Brewer</th>
|
<th scope="col" class="px-4 py-3">Brewer</th>
|
||||||
{% call table::sortable_header("Date", "created-at", navigator, "#brew-list") %}
|
{% call table::sortable_header("Date", "created-at", navigator, "#brew-list") %}
|
||||||
{% if is_authenticated %}
|
{% if is_authenticated %}
|
||||||
<th scope="col" class="px-4 py-3 text-right">Actions</th>
|
<th scope="col" class="px-4 py-3 text-center">Actions</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
@ -47,6 +47,29 @@
|
||||||
<td class="px-4 py-3 whitespace-nowrap text-stone-500">{{ brew.created_at }}</td>
|
<td class="px-4 py-3 whitespace-nowrap text-stone-500">{{ brew.created_at }}</td>
|
||||||
{% if is_authenticated %}
|
{% if is_authenticated %}
|
||||||
<td class="px-4 py-3 text-right">
|
<td class="px-4 py-3 text-right">
|
||||||
|
<form class="inline" data-on:submit="@post('/api/v1/brews?{{ navigator.query() }}', {contentType: 'form', responseOverrides: {selector: '#brew-list', mode: 'replace'}})">
|
||||||
|
<input type="hidden" name="bag_id" value="{{ brew.bag_id }}" />
|
||||||
|
<input type="hidden" name="coffee_weight" value="{{ brew.coffee_weight_raw }}" />
|
||||||
|
<input type="hidden" name="grinder_id" value="{{ brew.grinder_id }}" />
|
||||||
|
<input type="hidden" name="grind_setting" value="{{ brew.grind_setting_raw }}" />
|
||||||
|
<input type="hidden" name="brewer_id" value="{{ brew.brewer_id }}" />
|
||||||
|
<input type="hidden" name="water_volume" value="{{ brew.water_volume_raw }}" />
|
||||||
|
<input type="hidden" name="water_temp" value="{{ brew.water_temp_raw }}" />
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-stone-500 transition hover:text-amber-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500"
|
||||||
|
title="Brew again"
|
||||||
|
>
|
||||||
|
<span class="sr-only">Brew again</span>
|
||||||
|
<svg class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M15.312 11.424a5.5 5.5 0 0 1-9.201 2.466l-.312-.311h2.433a.75.75 0 0 0 0-1.5H3.989a.75.75 0 0 0-.75.75v4.242a.75.75 0 0 0 1.5 0v-2.43l.31.31a7 7 0 0 0 11.712-3.138.75.75 0 0 0-1.449-.39Zm1.23-3.723a.75.75 0 0 0 .219-.53V2.929a.75.75 0 0 0-1.5 0v2.43l-.31-.31A7 7 0 0 0 3.239 8.188a.75.75 0 1 0 1.448.389 5.5 5.5 0 0 1 9.2-2.466l.312.311h-2.433a.75.75 0 0 0 0 1.5h4.243a.75.75 0 0 0 .53-.22Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-stone-500 transition hover:text-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500"
|
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-stone-500 transition hover:text-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue