From 494f7ff1ee75a7b5f4ad58cc3d2440c5b2979e93 Mon Sep 17 00:00:00 2001 From: Deeman Date: Thu, 26 Feb 2026 02:39:29 +0100 Subject: [PATCH] feat(web): integrate crop stress into Pulse page - index() route: add get_weather_stress_latest() and get_weather_stress_trend(90d) to asyncio.gather; pass weather_stress_latest and weather_stress_trend to template - pulse.html: add 5th metric card (Crop Stress Index, color-coded green/copper/danger) - pulse.html: add 5th sparkline card (90d avg stress trend) linking to /dashboard/weather - pulse.html: update spark-grid to auto-fit (minmax 280px) to accommodate 5 cards - pulse.html: add Weather freshness badge to the freshness bar Co-Authored-By: Claude Opus 4.6 --- .../beanflows/dashboard/templates/pulse.html | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/web/src/beanflows/dashboard/templates/pulse.html b/web/src/beanflows/dashboard/templates/pulse.html index 54779d3..9373b4f 100644 --- a/web/src/beanflows/dashboard/templates/pulse.html +++ b/web/src/beanflows/dashboard/templates/pulse.html @@ -25,16 +25,13 @@ color: var(--color-stone); } -/* 2×2 sparkline grid */ +/* Sparkline grid — auto-fit for 4 or 5 cards */ .spark-grid { display: grid; - grid-template-columns: 1fr 1fr; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem; margin-top: 1.5rem; } -@media (max-width: 600px) { - .spark-grid { grid-template-columns: 1fr; } -} .spark-card { background: white; @@ -94,7 +91,7 @@

Global coffee market — full picture in 10 seconds{% if user.name %} · Welcome back, {{ user.name }}{% endif %}

- +
KC=F Close
@@ -139,6 +136,17 @@
ending stocks / consumption{% if stu_latest %} · {{ stu_latest.market_year }}{% endif %}
+ +
+
Crop Stress Index
+
+ {% if weather_stress_latest %}{{ "{:.0f}".format(weather_stress_latest.avg_crop_stress_index) }}/100{% else %}--{% endif %} +
+
+ avg · {% if weather_stress_latest %}{{ weather_stress_latest.locations_under_stress }} stressed{% endif %} + {% if weather_stress_latest %} · {{ weather_stress_latest.observation_date }}{% endif %} +
+
@@ -156,6 +164,9 @@ ICE Stocks {% if ice_stocks_latest %}{{ ice_stocks_latest.report_date }}{% else %}—{% endif %} + + Weather {% if weather_stress_latest %}{{ weather_stress_latest.observation_date }}{% else %}—{% endif %} + @@ -209,6 +220,18 @@
USDA WASDE · 1,000 60-kg bags · production vs distribution
+ +
+
+
Crop Stress Index — 90 days
+ View details → +
+
+ +
+
Open-Meteo ERA5 · avg across 12 origins · 0 = no stress · 100 = severe
+
+ {% if plan == "free" %} @@ -338,6 +361,27 @@ options: sparkOpts(C.copper, false), }); } + + // Weather crop stress sparkline (90d) + var weatherRaw = {{ weather_stress_trend | tojson }}; + if (weatherRaw && weatherRaw.length > 0) { + var weatherAsc = weatherRaw.slice().reverse(); + new Chart(document.getElementById('sparkWeather'), { + type: 'line', + data: { + labels: weatherAsc.map(function (r) { return r.observation_date; }), + datasets: [{ + data: weatherAsc.map(function (r) { return r.avg_crop_stress_index; }), + borderColor: C.copper, + backgroundColor: C.copper + '22', + fill: true, + tension: 0.3, + borderWidth: 2, + }], + }, + options: sparkOpts(C.copper, true), + }); + } }()); {% endblock %}