Files
rar-autopass/app/web/templates/_status.html
Claude Agent 0a1df31126 feat(5.20): US-010 badge mediu RAR in liste/preview/detaliu/jurnal + audit + ecou API
labels.py: ETICHETE_ENV + eticheta_env(env)->(text,css). Productie afisata
"PRODUCȚIE" (majuscule+diacritice) cu badge fill de atentie (--err), Testare
outline discret muted — semnalizare risc L.142 (declaratie reala ireversibila).
Clase .env-badge-prod / .env-badge-test in base.html; eticheta_env expus ca
global Jinja.

Badge de mediu per rand in _submissions, _coada implicit prin view, _preview_rand,
_trimitere_detaliu, _jurnal. Statusbar (_status.html) aliniat la aceeasi conventie
(Productie = atentie, nu verde) — inlocuieste culorile ad-hoc din US-011, toggle
neatins.

rar_env in exportul de audit (AUDIT_COLUMNS + _audit_rows) si ecou in
GET /v1/prezentari(/{id}). _submission_row_view/_detaliu_ctx/fragment_submissions
duc rar_env pana in template.

tests/test_badge_rar_env.py: badge in lista, audit contine rar_env, GET ecou rar_env.
test_statusbar_env: asertie aliniata la eticheta PRODUCȚIE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 20:16:08 +00:00

195 lines
9.9 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.

<div id="status-bar" class="status-bar card"
hx-get="/_fragments/status?tab={{ tab_activ | default('acasa') }}"
hx-trigger="every 15s, trimiteriChanged from:body"
hx-swap="outerHTML"
{% if oob %}hx-swap-oob="outerHTML"{% endif %}>
{# Banner cont in asteptare de activare (mereu vizibil cand contul e inactiv) #}
{% if not account_active %}
<div style="margin-bottom:12px; padding:8px 10px; border-left:3px solid var(--warn);
background:color-mix(in srgb, var(--warn) 12%, var(--card)); border-radius:6px; font-size:13px;">
<strong>Cont in asteptare de activare.</strong>
Configureaza credentialele RAR si pregateste importul acum; trimiterea catre RAR
porneste automat dupa activare de catre administrator.
</div>
{% endif %}
{# US-006 (5.17) — Banner one-time trial->Gratuit (T-DES-1): afisat la prima incarcare
dupa expirarea trial-ului. Discret, non-blocant; dismissibil via sessionStorage.
Nu acopera stripul de sanatate (apare inainte de health strip, la acelasi nivel). #}
{% if trial_expirat_recent|default(false) %}
<div id="banner-trial-expirat"
role="status"
style="margin-bottom:10px; padding:7px 12px;
border-left:3px solid var(--warn);
background:color-mix(in srgb, var(--warn) 10%, var(--card));
border-radius:6px; font-size:var(--fs-sm);
display:flex; align-items:center; justify-content:space-between; gap:8px;">
<span>Trial Pro expirat — esti pe Gratuit, 60/luna</span>
<button onclick="sessionStorage.setItem('tfx','1'); document.getElementById('banner-trial-expirat').style.display='none';"
style="background:transparent; border:none; color:var(--muted); cursor:pointer;
font-size:18px; padding:0 4px; line-height:1; flex-shrink:0;"
aria-label="Inchide bannerul">×</button>
</div>
<script>(function(){ if(sessionStorage.getItem('tfx')){ var el=document.getElementById('banner-trial-expirat'); if(el) el.style.display='none'; } })();</script>
{% endif %}
{# === US-003 (PRD 5.16): Banda de stare RAR — NUMAI cand BLOCAT (rosu, lat de 100%).
OK = dot verde in antet (base.html); banda nu mai apare cand totul e ok.
Elementul id="strip-sanatate" ramane in DOM mereu, dar goleste continutul cand OK,
astfel "hidden" + fara continut eroare in sursa = nu pica testele de prezenta id-ului.
#}
{% if sanatate_ok %}
<div id="strip-sanatate" role="status" aria-live="polite" hidden></div>
{% else %}
<div id="strip-sanatate"
role="status"
aria-live="polite"
style="display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
padding:10px 14px; border-radius:8px; margin-bottom:14px;
background:color-mix(in srgb, var(--err) 16%, var(--card)); border:1px solid color-mix(in srgb, var(--err) 40%, transparent);">
<div style="display:flex; align-items:center; gap:9px;">
<span aria-hidden="true" style="font-weight:700; font-size:15px; color:var(--err);">&#10007;</span>
<span style="font-weight:700; font-size:13px;">{{ sanatate_text }}</span>
</div>
<span style="font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--muted); white-space:nowrap;">
{{ eticheta_ultima_auth }}: {{ last_login }}
</span>
</div>
{% endif %}
{# === US-002 (PRD 5.16): 5 carduri-contor separate (desktop) + bara compacta (mobil <=560px).
Total / Luna asta / Azi / In coada / De corectat.
#}
{# Desktop: 5 carduri side-by-side. display:flex + layout stau in CSS (.contoare-desktop in
base.html), NU inline, ca media query-ul <=560px sa le poata ascunde pe mobil (bara compacta). #}
<div class="contoare-desktop">
{# Total trimise (all-time) #}
<div class="contor-card" style="flex:1; min-width:100px;">
<div class="contor-cifra">{{ counts_sent }}</div>
<div class="contor-label">Total</div>
</div>
{# Luna asta #}
<div class="contor-card" style="flex:1; min-width:100px;">
<div class="contor-cifra s-accent">{{ sent_month }}</div>
<div class="contor-label">Luna asta</div>
</div>
{# Azi #}
<div class="contor-card" style="flex:1; min-width:80px;">
<div class="contor-cifra s-accent">{{ sent_today }}</div>
<div class="contor-label">Azi</div>
</div>
{# In coada #}
<div class="contor-card" style="flex:1; min-width:80px;">
<div class="contor-cifra s-queued">{{ counts_queued }}</div>
<div class="contor-label">In coada</div>
</div>
{# De corectat (rosu daca >0, muted la 0; link catre lista) #}
<a href="/" class="contor-card"
style="flex:1; min-width:80px; text-decoration:none; display:block; cursor:pointer;"
aria-label="De corectat: {{ blocate_total }} — click pentru lista de trimiteri">
<div class="contor-cifra {{ 's-error' if blocate_total else 'muted' }}">{{ blocate_total }}</div>
<div class="contor-label">De corectat</div>
</a>
</div>
{# Mobil (<=560px): bara compacta — numerele + etichete scurte in-line #}
<div class="contoare-compact">
<div class="compact-item">
<div class="compact-nr">{{ counts_sent }}</div>
<div class="compact-lbl">Total</div>
</div>
<div class="compact-item">
<div class="compact-nr s-accent">{{ sent_month }}</div>
<div class="compact-lbl">Luna</div>
</div>
<div class="compact-item">
<div class="compact-nr s-accent">{{ sent_today }}</div>
<div class="compact-lbl">Azi</div>
</div>
<div class="compact-item">
<div class="compact-nr s-queued">{{ counts_queued }}</div>
<div class="compact-lbl">Coada</div>
</div>
<a class="compact-item" href="/" style="text-decoration:none; color:inherit;">
<div class="compact-nr {{ 's-error' if blocate_total else 'muted' }}">{{ blocate_total }}</div>
<div class="compact-lbl">Erori</div>
</a>
</div>
{# === US-011 (5.20): Indicator mediu RAR activ per cont.
La 0 medii: nu afisa (cont fara configuratie RAR).
La 1 mediu: eticheta statica (fara toggle).
La 2 medii: buton de comutare HTMX (toggle conditionat).
US-010: culori prin eticheta_env/clase .env-badge-* (consistenta cu badge-urile din liste).
#}
{% set _medii = medii_disponibile | default([]) %}
{% set _env = env_default | default('prod') %}
{% set _eb = eticheta_env(_env) %}
{% if _medii | length >= 1 %}
<div class="env-indicator"
style="display:flex; align-items:center; gap:8px; margin-bottom:10px;
padding:6px 10px; border-radius:6px; font-size:var(--fs-sm);
background:color-mix(in srgb, {% if _env == 'prod' %}var(--err){% else %}var(--line){% endif %} 10%, var(--card));
border:1px solid color-mix(in srgb, {% if _env == 'prod' %}var(--err){% else %}var(--line){% endif %} 30%, transparent);">
<span style="font-weight:600;">Mediu RAR:</span>
<span class="{{ _eb[1] }}">{{ _eb[0] }}</span>
{% if _medii | length >= 2 %}
{# Toggle: apare DOAR cand sunt cel putin 2 medii disponibile #}
<form method="post" action="/_fragments/status/toggle-env"
hx-post="/_fragments/status/toggle-env"
hx-target="#status-bar"
hx-swap="outerHTML"
style="margin:0; padding:0; display:inline;">
<input type="hidden" name="csrf_token" value="{{ csrf_token | default('') }}">
<button type="submit"
style="padding:2px 10px; font-size:var(--fs-xs); border-radius:99px;
border:1px solid currentColor; background:transparent; cursor:pointer;
color:var(--muted); line-height:1.4;"
title="Comuta la {{ 'PRODUCȚIE' if _env == 'test' else 'Testare' }}">
Comuta
</button>
</form>
{% endif %}
</div>
{% endif %}
{# === Navigatie rapida: Trimiteri + Mapari cu badge needs_mapping ===
Pastrata exact ca inainte (US-005): tab_activ determina marcajul activ.
#}
{% set _tab = tab_activ | default('acasa') %}
<nav class="status-nav" aria-label="Navigatie rapida"
style="display:flex; gap:8px 16px; flex-wrap:wrap; font-size:13px; border-top:1px solid var(--line); padding-top:8px;">
<a href="/"
{% if _tab == 'acasa' or _tab == '' %}aria-current="page"{% endif %}
class="status-nav-link{% if _tab == 'acasa' or _tab == '' %} status-nav-activ{% endif %}">Trimiteri</a>
<a href="/?tab=mapari"
{% if _tab == 'mapari' %}aria-current="page"{% endif %}
class="status-nav-link{% if _tab == 'mapari' %} status-nav-activ{% endif %}">Mapari{% if mapari_badge %}<span class="tab-badge" aria-hidden="true" style="display:inline-flex; align-items:center; justify-content:center; min-width:16px; height:16px; margin-left:4px; padding:0 4px; border-radius:99px; background:var(--err); color:#fff; font-size:11px; font-weight:700;">{{ mapari_badge }}</span>{% endif %}</a>
</nav>
{# US-006 (5.17) + T-6 (5.16): linia de plan in CORP apare DOAR in starea de avertizare
(>=80% -> --warn; limita atinsa -> --err). Consumul normal (N/60) traieste in badge-ul
din antet + linia din meniul burger, nu ca rand permanent in corp (densitate redusa).
Ierarhie: nu concureaza cu stripul de sanatate (zero-silent-failures pastrat). #}
{% if plan_linie and (plan_warn|default(false) or plan_limita_atinsa|default(false)) %}
<div class="plan-status-line"
style="font-size:var(--fs-sm); margin-top:6px; padding-top:6px;
border-top:1px solid var(--line2);
color:{% if plan_limita_atinsa|default(false) %}var(--err){% elif plan_warn|default(false) %}var(--warn){% else %}var(--muted){% endif %};
{% if plan_warn|default(false) %}font-weight:600;{% endif %}">
{{ plan_linie }}
{% if plan_limita_atinsa|default(false) or plan_warn|default(false) %}
&nbsp;<a href="/?tab=cont" style="font-size:var(--fs-xs); font-weight:400; color:var(--accent);">Detalii plan</a>
{% endif %}
</div>
{% endif %}
</div>