read.markets/app/templates/dashboard.html
Giorgio Gilestro 6377c929b8 portfolio-edit: form is edit-mode only; submit becomes a + glyph
Two related polishes:

- The add form was auto-shown by the empty-state path so brand-new
  users would see something to act on. That conflicts with the user's
  preference for "Edit always toggles the form, no other path." The
  empty state now shows guidance copy ("click edit to add one")
  instead. exitEditMode always hides the form too.
- The submit "add" word-button is replaced by a square accent-bordered
  + glyph (26×26). Matches the visual weight of the calendar ghost
  next to it but stays in the accent colour so it reads as primary.
  Adds a tiny active-state scale tick for tactile feedback.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 15:22:13 +02:00

133 lines
5.4 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ BRAND_NAME }} · Dashboard{% endblock %}
{% block main %}
<div id="dash-header-container"
style="grid-column: 1 / -1;"
hx-get="/api/summary/aggregate?as=html"
hx-trigger="load, every 300s, tone-changed"
hx-swap="innerHTML">
<div class="empty">loading aggregate read…</div>
</div>
<section id="indicators-panel" class="panel">
<div class="panel-header">
<span class="title">Indicators</span>
<span class="meta">{% if anchor %}anchor {{ anchor }} · {% endif %}ingest hourly @ :05 UTC</span>
</div>
<div class="group-tabs" id="group-tabs">
{% for g in groups %}
<button
class="{% if loop.first %}active{% endif %}"
hx-get="/api/indicators/{{ g }}?as=html"
hx-target="#indicators-body"
hx-trigger="click"
onclick="document.querySelectorAll('#group-tabs button').forEach(b=>b.classList.remove('active'));this.classList.add('active')"
>{{ g }}</button>
{% endfor %}
</div>
<div id="indicators-body"
class="panel-body panel-body--scroll"
hx-get="/api/indicators/{{ groups[0] }}?as=html"
hx-trigger="load, tone-changed"
hx-swap="innerHTML">
<div class="empty">loading…</div>
</div>
</section>
<script>
// Auto-refresh the *currently selected* group every 60s by simulating a
// click on the active tab. Replaces the hard-coded `every 60s` on
// #indicators-body which always re-fetched groups[0].
setInterval(function () {
var active = document.querySelector('#group-tabs button.active');
if (active) active.click();
}, 60000);
</script>
<section id="portfolio-panel" class="panel">
<div class="panel-header">
<span class="title">Portfolio</span>
<button type="button" id="pf-edit-btn" class="pf-edit-btn"
title="Add or remove positions" aria-pressed="false">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 20h9"/>
<path d="M16.5 3.5a2.121 2.121 0 1 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
</svg>
<span class="pf-edit-btn__label">Edit</span>
</button>
<button type="button" id="pf-done-btn" class="pf-done-btn" hidden>Done</button>
</div>
<div class="panel-body">
<div id="pf-add-form" class="pf-add" hidden>
<div class="pf-add__line">
<span class="pf-add__prompt" aria-hidden="true">$</span>
<input type="text" id="pf-add-ticker" class="pf-add__ticker"
autocomplete="off" spellcheck="false" maxlength="32"
placeholder="ticker">
<span id="pf-add-ticker-status" class="pf-add-status"></span>
<span class="pf-add__div" aria-hidden="true"></span>
<input type="number" id="pf-add-qty" class="pf-add__num pf-add__num--qty"
min="0" step="any" placeholder="qty">
<span class="pf-add__at" aria-hidden="true">@</span>
<input type="number" id="pf-add-cost" class="pf-add__num pf-add__num--cost"
min="0" step="any" placeholder="cost">
<span id="pf-add-cost-currency" class="pf-add-currency"></span>
<button type="button" id="pf-add-date-btn" class="pf-add__icon"
title="Use a buy date to auto-fill cost" aria-label="Pick buy date">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" aria-hidden="true">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/>
<line x1="16" y1="2" x2="16" y2="6"/>
<line x1="8" y1="2" x2="8" y2="6"/>
<line x1="3" y1="10" x2="21" y2="10"/>
</svg>
</button>
<input type="date" id="pf-add-date" class="pf-add__date" hidden>
<button type="button" id="pf-add-submit" class="pf-add__submit"
disabled aria-label="Add position" title="Add position">+</button>
</div>
<div class="pf-add__notes">
<span id="pf-add-date-status" class="pf-add-status"></span>
<span id="pf-add-warning" class="pf-add-warning" hidden></span>
</div>
</div>
<div id="pf-mount">
<div class="empty">loading…</div>
</div>
</div>
</section>
<script src="{{ url_for('static', path='/js/portfolio-sync.js') }}" defer></script>
<script src="{{ url_for('static', path='/js/portfolio.js') }}" defer></script>
<script src="{{ url_for('static', path='/js/portfolio_edit.js') }}" defer></script>
<section id="log-panel" class="panel">
<div class="panel-header">
<span class="title">Strategic Log</span>
<span class="meta">
{% if paid %}refreshed hourly @ :20 UTC{% else %}refreshed every 6 hours &middot; <a href="/pricing">hourly on Paid</a>{% endif %}
</span>
</div>
<div class="panel-body"
hx-get="/api/log/latest?as=html"
hx-trigger="load, every 300s, tone-changed"
hx-swap="innerHTML">
<div class="empty">awaiting first log…</div>
</div>
</section>
<section id="news-panel" class="panel">
<div class="panel-header">
<span class="title">Flash News</span>
<span class="meta">
{% if paid %}last 24h &middot; ingest hourly @ :10 UTC{% else %}last 6h &middot; <a href="/pricing">full 24h on Paid</a>{% endif %}
</span>
</div>
<div class="panel-body panel-body--scroll"
hx-get="/api/news?as=html&limit=40"
hx-trigger="load, every 60s, tags-changed"
hx-swap="innerHTML">
<div class="empty">loading…</div>
</div>
</section>
{% endblock %}