Files
roast_command_center/public/brews.html
T
Shane MaynardandClaude Fable 5 e62b9601a2
Test and deploy / test-and-deploy (push) Successful in 59s
Add Equipment page: owned brewers and grinders filter the Brews UI
- user_gear table (migration 008) + GET/PUT /api/gear (brewer keys
  validated against the taxonomy, grinders deduped/trimmed)
- /gear page: silhouette multi-select for owned brewers (autosaves) and
  a grinder list; nav gains Brewing → Equipment
- Brews page: with gear configured, the picker shows only owned brewers
  (plus the edited brew's method) with a show-all toggle; grinder field
  suggests your grinders; empty-gear state links to /gear
- Included in full backups, per-user export, and the OpenAPI spec

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-09 08:08:32 -04:00

204 lines
8.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Brews — Roast Planner</title>
<link rel="stylesheet" href="/app.css?v=__ASSET_VERSION__" />
<link rel="icon" href="/icon.svg?v=__ASSET_VERSION__" type="image/svg+xml" />
<meta name="theme-color" content="#A8481A" />
</head>
<body>
<div class="app-shell">
<nav class="side-nav" id="side-nav" aria-label="Main navigation">
<div class="side-nav-brand">
<span class="brand-mark" aria-hidden="true"></span>
<span class="brand-name">Roast Planner</span>
</div>
<div id="nav-links"></div>
<div class="nav-spacer"></div>
<button
class="icon-btn nav-collapse-toggle"
type="button"
id="nav-collapse"
aria-label="Collapse navigation"
title="Collapse navigation"
>
«
</button>
<div class="nav-user">
<div class="nav-user-avatar" id="nav-user-avatar" aria-hidden="true"></div>
<div class="nav-user-detail">
<span class="nav-user-email" id="account-email"></span>
<button class="nav-user-logout" type="button" id="btn-logout">
Log out
</button>
</div>
</div>
</nav>
<div class="app-workspace" id="app-workspace">
<header class="app-header">
<div class="header-row-top">
<button
class="icon-btn nav-hamburger"
type="button"
id="nav-hamburger"
aria-label="Open navigation"
aria-expanded="false"
>
</button>
<div class="brand">
<div class="brand-text">
<h1>Brews</h1>
<p class="brand-sub">Log every cup — method, recipe, and how it tasted</p>
</div>
</div>
</div>
</header>
<div class="drawer-overlay hidden" id="drawer-overlay"></div>
<main class="page-content">
<section class="panel-card" id="brew-form-card">
<div class="panel-head">
<h2 id="brew-form-title">Log a brew</h2>
<button class="ghost-btn small hidden" type="button" id="brew-form-cancel">
Cancel edit
</button>
</div>
<div class="panel-body">
<form id="brew-form">
<label class="field" style="max-width:420px"
><span class="field-label">Bean</span>
<select class="field-input" name="beanId" id="brew-bean-select">
<option value="">— no bean selected —</option>
</select></label
>
<div id="brewer-picker" style="margin:12px 0"></div>
<div class="field-grid">
<label class="field"
><span class="field-label">Dose</span>
<div class="unit-input">
<input class="field-input" type="number" name="doseG" inputmode="decimal" min="0" step="any" /><span class="unit">g</span>
</div></label
>
<label class="field" data-espresso-hide
><span class="field-label">Water</span>
<div class="unit-input">
<input class="field-input" type="number" name="waterG" inputmode="decimal" min="0" step="any" /><span class="unit">g</span>
</div></label
>
<label class="field hidden" data-espresso-show
><span class="field-label">Yield (out)</span>
<div class="unit-input">
<input class="field-input" type="number" name="yieldG" inputmode="decimal" min="0" step="any" /><span class="unit">g</span>
</div></label
>
<label class="field"
><span class="field-label">Ratio</span
><input class="field-input" id="brew-ratio" readonly placeholder="—"
/></label>
<label class="field"
><span class="field-label">Water temp</span>
<div class="unit-input">
<input class="field-input" type="number" name="waterTempC" inputmode="decimal" min="0" max="100" step="any" /><span class="unit">°C</span>
</div></label
>
<label class="field"
><span class="field-label">Grinder</span
><input
class="field-input"
name="grinder"
list="grinder-options"
placeholder="e.g. Comandante C40"
/><datalist id="grinder-options"></datalist></label>
<label class="field"
><span class="field-label">Grind setting</span
><input class="field-input" name="grindSetting" placeholder="e.g. 22 clicks"
/></label>
<label class="field"
><span class="field-label">Total time</span
><input class="field-input" name="brewTime" placeholder="m:ss"
/></label>
<label class="field" data-espresso-hide
><span class="field-label">Bloom</span
><input class="field-input" name="bloomTime" placeholder="m:ss"
/></label>
</div>
<label class="field"
><span class="field-label">Recipe / steps</span
><textarea
class="field-input"
name="recipe"
rows="3"
placeholder="e.g. 45 g bloom, swirl · 0:45 pour to 150 g · 1:30 pour to 250 g · drawdown by 2:45"
></textarea></label
>
<label class="field" style="margin-top:6px"
><span class="field-label"
>Rating <span class="rating-pill" id="rating-value"></span></span
>
<input
type="range"
name="rating"
id="brew-rating"
min="0"
max="10"
step="0.5"
value="5"
style="width:min(360px,100%)"
/>
</label>
<label class="field"
><span class="field-label">Tasting notes</span
><textarea
class="field-input"
name="tastingNotes"
rows="2"
placeholder="What you actually tasted — sweetness, acidity, body, finish…"
></textarea></label
>
<label class="field"
><span class="field-label">Notes / next time</span
><input class="field-input" name="notes" placeholder="e.g. grind finer next time"
/></label>
<button class="primary-btn" type="submit" id="brew-form-submit">
Save brew
</button>
</form>
</div>
</section>
<section class="panel-card" id="brew-history">
<div class="panel-head">
<h2>Brew history</h2>
<button class="ghost-btn small hidden" id="clear-bean-filter">
Clear bean filter
</button>
</div>
<div class="panel-body">
<div class="table-wrap">
<table class="data-table" id="brews-table">
<thead>
<tr>
<th>When</th>
<th>Method</th>
<th>Bean</th>
<th>Recipe</th>
<th>Rating</th>
<th></th>
</tr>
</thead>
<tbody id="brews-body"></tbody>
</table>
</div>
</div>
</section>
</main>
</div>
</div>
<script type="module" src="/js/brews.js?v=__ASSET_VERSION__"></script>
</body>
</html>