brewlog/templates/partials/brew_card.html
Jon Seager 902d52b171
feat(brews): add brew time field
- Add brew_time INTEGER column to brews table (nullable, stored as seconds)
- Display as M:SS format with stepper control (+/-5s) in add form
- Replace ratio with brew time in brew list Recipe column
- Show brew time in brew cards and timeline events
- Add --brew-time CLI flag and update bootstrap script (1:45-2:45 range)
2026-02-07 11:24:07 +00:00

53 lines
2.7 KiB
HTML

{% import "partials/icons.html" as icons %}
{% macro card(brew, is_authenticated) %}
<div class="relative w-[45vw] md:w-[200px] h-[280px] shrink-0 snap-start rounded-lg border bg-surface p-4 flex flex-col">
{% if is_authenticated %}
<form
class="absolute top-4 right-3"
data-on:submit="$_brewing = true; @post('/api/v1/brews', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_brewing) return; if (evt.detail.type === 'finished') { window.location.reload() } else if (evt.detail.type === 'error') { $_brewing = false }"
>
<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 }}" />
{% if let Some(fp_id) = brew.filter_paper_id %}
<input type="hidden" name="filter_paper_id" value="{{ fp_id }}" />
{% endif %}
<input type="hidden" name="water_volume" value="{{ brew.water_volume_raw }}" />
<input type="hidden" name="water_temp" value="{{ brew.water_temp_raw }}" />
<input type="hidden" name="quick_notes" value="{{ brew.quick_notes_raw }}" />
{% if let Some(bt) = brew.brew_time_raw %}
<input type="hidden" name="brew_time" value="{{ bt }}" />
{% endif %}
<button
type="submit"
class="inline-flex h-6 w-6 items-center justify-center rounded-md text-text-muted transition hover:text-accent hover:bg-surface-alt"
title="Brew Again"
>
{{ icons::refresh("h-4.5 w-4.5") }}
</button>
</form>
{% endif %}
<div class="h-[4.5rem] overflow-hidden pr-5">
<span class="block font-semibold text-text truncate">{{ brew.roast_name }}</span>
<p class="mt-0.5 text-sm text-text-muted truncate">{{ brew.roaster_name }}</p>
</div>
<div class="mt-2 flex-1 space-y-1 text-text-secondary" style="font-size: 0.8125rem">
<p>{{ brew.coffee_weight }} &middot; {{ brew.water_volume }}{% if let Some(bt) = brew.brew_time %} &middot; {{ bt }}{% endif %}</p>
<p>{{ brew.grinder_model }} &middot; {{ brew.grind_setting }}</p>
<p>{{ brew.brewer_name }}</p>
{% if let Some(fp) = brew.filter_paper_name %}<p>{{ fp }}</p>{% endif %}
</div>
<div class="flex flex-wrap gap-1">
{% if !brew.quick_notes.is_empty() %}
{% for qn in brew.quick_notes %}
<span class="{{ qn.pill_class }}" style="font-size: 0.65rem">{{ qn.label }}</span>
{% endfor %}
{% else %}
<span class="pill pill-muted" style="font-size: 0.65rem">No Notes</span>
{% endif %}
</div>
</div>
{% endmacro %}