feat(setari): meniu grupat + pagina Setari cu sub-taburi + schimbare parola
Meniu hamburger reorganizat pe grupuri cu etichete (LUCRU / CONT) cu iconite SVG discrete; "Cont" redenumit "Setari" (URL ?tab=cont pastrat, zero rute moarte). Pagina Setari restructurata in sub-taburi interne: Date firma / Credentiale RAR / Cheie API / Cont (plan + schimbare parola), cu indicator de stare per tab. Sub-tabul activ e pastrat server-side (activ_subtab) dupa fiecare swap HTMX; comutarea intre taburi e client-side, delegata pe document (supravietuieste swap-urilor). Credentiale RAR: mediile Testare/Productie ca doua carduri paralele. Schimbare parola de acces din sub-tabul Cont (functie noua, lipsea): - users.change_password (scrypt): verifica parola actuala constant-time, valideaza noua (10..128, diferita), rescrie hash+salt nou; - ruta POST /cont/schimba-parola, scoped pe user_id din sesiune, CSRF enforce, parola niciodata re-pusa in raspuns, jurnal 'parola_schimbata'. Referinte copy "Meniu cont > Cont" -> "Setari". Teste: schimbare parola (succes / parola actuala gresita / confirmare nepotrivita / lungime) + izolare rate-limit login in fixture-ul clientului. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -36,8 +36,8 @@
|
||||
})();
|
||||
</script>
|
||||
<style>
|
||||
/* US-001 PRD 5.16: stive de font standard web. Toate regulile font-face IBM Plex sterse.
|
||||
Motiv: decizie user (risc AI-Slop #11 acceptat constient), uniformitate cross-page.
|
||||
/* Stive de font standard web. Toate regulile font-face IBM Plex sterse.
|
||||
Motiv: decizie user, uniformitate cross-page.
|
||||
Fisierele woff2 raman pe disc (curatare = follow-up optional, non-blocant).
|
||||
Referinte catre directorul de fonturi statice eliminate — font-ui si font-mono sunt stive sistem. */
|
||||
/* Paleta dark (default) — accent azur ROMFAST.
|
||||
@@ -45,10 +45,10 @@
|
||||
--line2: separator subtire (intre --bg si --line). */
|
||||
:root { --bg:#0f1218; --card:#181c24; --card2:#0f1218; --ink:#e6e9ef; --muted:#8b93a7; --line:#262b36; --line2:#1f2530;
|
||||
--ok:#2FBF8F; --warn:#E0A93B; --err:#E05D5D; --accent:#2E74D6;
|
||||
/* US-001 (PRD 5.16): stive font standard web — sursa unica de adevar */
|
||||
/* Stive font standard web — sursa unica de adevar */
|
||||
--font-ui: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
--font-mono: ui-monospace, "SF Mono", "Cascadia Code", "Segoe UI Mono", "Roboto Mono", Menlo, Consolas, monospace;
|
||||
/* US-002 (PRD 5.16): scala tipografica uniforma — sursa unica de adevar */
|
||||
/* Scala tipografica uniforma — sursa unica de adevar */
|
||||
--fs-xs:12px; --fs-sm:13.5px; --fs-base:15px; --fs-md:16px;
|
||||
--fs-lg:18px; --fs-xl:20px; --fs-2xl:28px; --fs-3xl:34px;
|
||||
--lh-tight:1.25; --lh-body:1.55; }
|
||||
@@ -60,7 +60,7 @@
|
||||
[data-theme="petrol"] { --bg:#0e1416; --card:#161e20; --card2:#0e1416; --ink:#e6e9ef; --muted:#8b93a7; --line:#232c2e; --line2:#1c2426;
|
||||
--ok:#2FBF8F; --warn:#E0A93B; --err:#E05D5D; --accent:#0E7C7B; }
|
||||
/* Paleta Grafit — similara cu dark, accent azur deschis (#6ea2ec = landing --infot).
|
||||
Distinta de dark la cererea userului (D2 PRD 5.15). */
|
||||
Distinta de dark la cererea userului. */
|
||||
[data-theme="grafit"] { --bg:#0f1218; --card:#181c24; --card2:#0f1218; --ink:#e6e9ef; --muted:#8b93a7; --line:#262b36; --line2:#1f2530;
|
||||
--ok:#2FBF8F; --warn:#E0A93B; --err:#E05D5D; --accent:#6ea2ec; }
|
||||
/* Paleta Cobalt — fundal bleumarin adanc, accent albastru viu (#8aa0ff = landing --infot). */
|
||||
@@ -70,7 +70,7 @@
|
||||
[data-theme="cupru"] { --bg:#15110b; --card:#211a12; --card2:#15110b; --ink:#efe6d6; --muted:#a89a85; --line:#36291c; --line2:#281e14;
|
||||
--ok:#67b98c; --warn:#c97d2e; --err:#e2685a; --accent:#dfa45c; }
|
||||
/* Paleta Hartie — fundal crem cald, accent albastru clasic (#1F5FBF = landing --infot = --accent).
|
||||
Similara cu light, distinta la cererea userului (D2 PRD 5.15). */
|
||||
Similara cu light, distinta la cererea userului. */
|
||||
[data-theme="hartie"] { --bg:#f3efe6; --card:#fffdf7; --card2:#f3efe6; --ink:#1e1a13; --muted:#6a6052; --line:#e2dccc; --line2:#ece6d9;
|
||||
--ok:#1c7d5d; --warn:#b45309; --err:#bd463c; --accent:#1F5FBF; }
|
||||
* { box-sizing:border-box; }
|
||||
@@ -104,7 +104,7 @@
|
||||
th { color:var(--muted); font-weight:500; font-size:12px; text-transform:uppercase; letter-spacing:.04em; }
|
||||
.empty { color:var(--muted); padding:24px; text-align:center; }
|
||||
.pill { font-size:12px; padding:2px 8px; border-radius:99px; border:1px solid var(--line); }
|
||||
/* Badge sursa sugestie (5.18 US-007): de unde vine sugestia de cod in editorul de mapare.
|
||||
/* Badge sursa sugestie: de unde vine sugestia de cod in editorul de mapare.
|
||||
confirmat = GOLD validat de om (verde); similar = SILVER/embedding k-NN (azur);
|
||||
non-operatie = pre-filtru NUL / vecin NUL (gri-cald). Suggestion-only, doar indiciu vizual. */
|
||||
.sugg-sursa { display:inline-block; font-size:10px; font-weight:700; line-height:1; padding:2px 6px;
|
||||
@@ -142,7 +142,7 @@
|
||||
.s-ok{color:var(--ok);}
|
||||
.s-needs_review{color:var(--warn);}
|
||||
.s-already_sent,.s-duplicate_in_file{color:var(--muted);}
|
||||
/* Badge mediu RAR (US-010 PRD 5.20) — semantica risc L.142.
|
||||
/* Badge mediu RAR — semantica risc L.142.
|
||||
Productie: fill atentie (ton --err), text alb — declaratie reala, ireversibila.
|
||||
Testare: outline discret, ton --muted — mediu de proba, low-stakes.
|
||||
NU se foloseste verde pentru Productie (ar semnala "sigur"). */
|
||||
@@ -167,7 +167,7 @@
|
||||
flex-wrap:wrap; z-index:10; }
|
||||
/* Indicator HTMX — ascuns pana la request */
|
||||
.htmx-indicator { display:none; }
|
||||
/* US-011 (PRD 5.16): selector tema stil pill — icon + eticheta temei curente.
|
||||
/* Selector tema stil pill — icon + eticheta temei curente.
|
||||
Eticheta se ascunde pe <=560px (spatiu ingust), ramane iconita. */
|
||||
.tema-btn { display:inline-flex; align-items:center; gap:6px; height:36px; padding:0 12px;
|
||||
border-radius:8px; background:transparent; border:1px solid var(--line);
|
||||
@@ -176,7 +176,7 @@
|
||||
.tema-btn:hover { border-color:var(--accent); color:var(--ink); }
|
||||
.tema-btn:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
|
||||
@media (max-width:560px) { #tema-label { display:none; } }
|
||||
/* US-003 (PRD 5.16): dot RAR compact in antet.
|
||||
/* Dot RAR compact in antet.
|
||||
Stare OK: dot verde pulsant + "RAR online". Stare BLOCAT: dot rosu.
|
||||
Stilat ca pill; sensul NU depinde de culoare (aria-label + title). */
|
||||
.rar-chip { display:inline-flex; align-items:center; gap:7px; height:36px; padding:0 12px;
|
||||
@@ -190,7 +190,7 @@
|
||||
.rar-dot.live { animation:rar-pulse 2s ease-in-out infinite; }
|
||||
@keyframes rar-pulse { 0%,100%{opacity:1;} 50%{opacity:.5;} }
|
||||
@media (max-width:560px) { .rar-chip .rar-tx { display:none; } }
|
||||
/* US-010 (PRD 5.16): sub-titlu cu numele service-ului (cand autentificat). */
|
||||
/* Sub-titlu cu numele service-ului (cand autentificat). */
|
||||
.h-sub { font-size:var(--fs-xs); color:var(--muted); margin-top:2px; line-height:1.2; }
|
||||
.h-sub .svc { color:var(--ink); font-weight:600; }
|
||||
/* Badge env (test/prod) si badge tier (plan cont) langa titlu. */
|
||||
@@ -367,7 +367,7 @@
|
||||
border-radius:6px; cursor:pointer; min-height:36px; white-space:nowrap; }
|
||||
.kebab-menu button:hover, .kebab-menu a:hover { background:var(--line); }
|
||||
.kebab-menu button.danger { color:var(--err); }
|
||||
/* === Accordion import compact (US-006 — regiune CSS disjuncta) ===
|
||||
/* === Accordion import compact (regiune CSS disjuncta) ===
|
||||
<details id="import-details"> invelete stepper + upload pe Acasa.
|
||||
Atribut `open` setat de server din `are_trimiteri`:
|
||||
False (first-run) → open; True (returning) → colapsat.
|
||||
@@ -394,7 +394,7 @@
|
||||
border-bottom:none; border-radius:0;
|
||||
margin-bottom:0; }
|
||||
/* === Sfarsit regiune accordion import === */
|
||||
/* === Inceput regiune nav links status-bar (US-005) ===
|
||||
/* === Inceput regiune nav links status-bar ===
|
||||
Linkuri Trimiteri + Mapari sub contoare; marcaj activ cu aria-current/status-nav-activ. */
|
||||
.status-nav-link { color:var(--accent); text-decoration:none; padding:2px 6px; border-radius:4px;
|
||||
transition:background .1s; }
|
||||
@@ -504,7 +504,7 @@
|
||||
/* === Preview import: coloane extra fata de tabelul Trimiteri.
|
||||
SCOPAT prin .tabel-trimiteri (clasa partajata). Regiune separata —
|
||||
nu atinge coloanele existente (col-chk/id/stare/data/rar/actualizat).
|
||||
US-007: 8 coloane (coloana de verificare manuala eliminata).
|
||||
8 coloane (coloana de verificare manuala eliminata).
|
||||
Suma latimi fixe: col-id(48) + col-stare(104) + col-data(104) +
|
||||
col-km(76) + col-note(176) + col-actiuni(92) = 600px.
|
||||
Restul (~680px la 1280px) revine lui col-vehicul + col-operatie (fluid). === */
|
||||
@@ -561,7 +561,7 @@
|
||||
font-size:12px; margin-bottom:2px; }
|
||||
.tabel-trimiteri td.col-chk, .tabel-trimiteri td.col-id { display:none; }
|
||||
|
||||
/* === Card COMPACT (PRD 5.13, corectie dogfood) ===
|
||||
/* === Card COMPACT ===
|
||||
Inlocuieste stiva generica eticheta+valoare (prea inalta) cu un card
|
||||
scanabil la prima vedere: vehicul = titlu, stare = pill dreapta-sus,
|
||||
operatie+cod pe rand, meta (data/km/rar) muted mic, nota mica. Fara
|
||||
@@ -701,10 +701,10 @@
|
||||
.sticky-bar { padding:10px 12px; gap:10px; }
|
||||
.sticky-bar button { width:100%; min-height:44px; }
|
||||
}
|
||||
/* === SENTINEL-COMPONENTE-SLIM: inceput componente slim US-002 (PRD 5.15).
|
||||
/* === SENTINEL-COMPONENTE-SLIM: inceput componente slim.
|
||||
Testele ancoreaza pe acest marker. Nu muta/sterge. === */
|
||||
/* .contor-card — card cifra contor: fundal --card2, bordura --line, radius 8px.
|
||||
US-002 PRD 5.16: padding marit (18px), cifra pe --fs-2xl, label pe --fs-sm, sub pe --fs-xs.
|
||||
Padding marit (18px), cifra pe --fs-2xl, label pe --fs-sm, sub pe --fs-xs.
|
||||
Variante de culoare a cifrei prin clasele .s-* existente (verde/accent/rosu). */
|
||||
.contor-card { background:var(--card2); border:1px solid var(--line); border-radius:8px; padding:18px 18px; }
|
||||
.contor-cifra { font-size:var(--fs-2xl); font-weight:700; line-height:1; }
|
||||
@@ -796,8 +796,8 @@
|
||||
@media (max-width:767px) {
|
||||
.trimitere-slim { padding:12px 14px; }
|
||||
}
|
||||
/* === SENTINEL-COMPONENTE-SLIM: sfarsit componente slim US-002 === */
|
||||
/* === Fix mobil Mapari (bug live 2026-06-29) ===
|
||||
/* === SENTINEL-COMPONENTE-SLIM: sfarsit componente slim === */
|
||||
/* === Fix mobil Mapari ===
|
||||
Doua probleme raportate la 390px pe pagina Mapari:
|
||||
(1) butoanele Salveaza/Sterge taiate: regula `.tabel-card td button {width:100%}`
|
||||
(specificitate 0,1,2) batea `.act {width:44px}` (0,1,0) -> cele doua butoane act
|
||||
@@ -823,10 +823,88 @@
|
||||
.tabel-card td .act .act-tx { display:inline; }
|
||||
.tabel-card td .act .act-ic { display:inline-block; }
|
||||
}
|
||||
/* === Meniu hamburger grupat === */
|
||||
/* Iconite SVG stroke unic, currentColor — mostenesc culoarea intrarii. */
|
||||
.ic { width:18px; height:18px; stroke:currentColor; fill:none; stroke-width:1.7;
|
||||
stroke-linecap:round; stroke-linejoin:round; flex-shrink:0; }
|
||||
.cont-menu a, .cont-menu form button { display:flex; align-items:center; gap:10px; }
|
||||
.cont-menu a .mi, .cont-menu form button .mi { display:inline-flex; opacity:.6; }
|
||||
.cont-menu a:hover .mi, .cont-menu form button:hover .mi { opacity:.9; }
|
||||
.cont-menu-group { font-size:10px; text-transform:uppercase; letter-spacing:.08em;
|
||||
color:var(--muted); font-weight:700; padding:8px 12px 4px; }
|
||||
/* Badge-ul de mapari se ancoreaza la dreapta chiar cand intrarea e flex. */
|
||||
.cont-menu a .tab-badge { margin-left:auto; }
|
||||
/* === Pagina Setari cu sub-taburi === */
|
||||
.setari-head { margin-bottom:4px; }
|
||||
.setari-title { font-size:var(--fs-lg); margin:0 0 2px; letter-spacing:-.01em;
|
||||
display:flex; align-items:center; gap:9px; }
|
||||
.setari-title .ic { width:20px; height:20px; opacity:.7; }
|
||||
.setari-sub { color:var(--muted); font-size:var(--fs-sm); margin:0 0 14px; }
|
||||
.setari-subtabs { display:flex; gap:2px; border-bottom:1px solid var(--line); margin-bottom:20px;
|
||||
overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none; }
|
||||
.setari-subtabs::-webkit-scrollbar { display:none; }
|
||||
.setari-subtab { appearance:none; background:transparent; border:none; border-bottom:2px solid transparent;
|
||||
color:var(--muted); font:inherit; font-size:var(--fs-sm); font-weight:500; cursor:pointer;
|
||||
padding:10px 2px; margin-right:22px; white-space:nowrap; display:inline-flex;
|
||||
align-items:center; gap:8px; margin-bottom:-1px; transition:color .12s, border-color .12s; }
|
||||
.setari-subtab:hover { color:var(--ink); }
|
||||
/* Stare activa prin clasa (nu selector pe atribut): aria-selected ramane pe buton
|
||||
pentru accesibilitate, dar stilul nu depinde de el. */
|
||||
.setari-subtab.is-active { color:var(--ink); border-bottom-color:var(--accent); font-weight:600; }
|
||||
.setari-subtab:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
|
||||
.st-dot { width:7px; height:7px; border-radius:99px; flex-shrink:0; }
|
||||
.st-dot.ok { background:var(--ok); }
|
||||
.st-dot.warn { background:var(--warn); }
|
||||
.st-dot.info { background:var(--muted); }
|
||||
.setari-pane[hidden] { display:none; }
|
||||
.setari-zone-title { font-size:var(--fs-md); font-weight:600; margin:0 0 4px; display:flex;
|
||||
align-items:center; gap:10px; flex-wrap:wrap; }
|
||||
.setari-zone-title .ic { opacity:.7; }
|
||||
.setari-zone-desc { color:var(--muted); font-size:var(--fs-sm); margin:0 0 16px; max-width:64ch; line-height:1.5; }
|
||||
.setari-badge { font-size:11px; font-weight:700; padding:2px 9px; border-radius:99px;
|
||||
text-transform:uppercase; letter-spacing:.03em; border:1px solid transparent; }
|
||||
.setari-badge.sb-ok { color:var(--ok); background:color-mix(in srgb,var(--ok) 12%,transparent);
|
||||
border-color:color-mix(in srgb,var(--ok) 40%,transparent); }
|
||||
.setari-badge.sb-warn { color:var(--warn); background:color-mix(in srgb,var(--warn) 12%,transparent);
|
||||
border-color:color-mix(in srgb,var(--warn) 40%,transparent); }
|
||||
.setari-badge.sb-info { color:var(--muted); background:color-mix(in srgb,var(--muted) 12%,transparent);
|
||||
border-color:color-mix(in srgb,var(--muted) 35%,transparent); }
|
||||
.setari-subzone-sep { border:none; border-top:1px solid var(--line); margin:26px 0 22px; }
|
||||
/* Cheie API afisata o singura data. */
|
||||
.keybox { font-family:var(--font-mono); font-size:14px; background:var(--card2);
|
||||
border:1px solid var(--line); border-radius:8px; padding:12px 14px; word-break:break-all;
|
||||
max-width:480px; }
|
||||
.btn-warn { background:transparent; color:var(--warn); border:1px solid var(--warn); border-radius:6px;
|
||||
padding:8px 14px; font:inherit; font-weight:500; cursor:pointer; min-height:36px;
|
||||
display:inline-flex; align-items:center; justify-content:center; gap:6px; }
|
||||
.btn-warn:hover, .btn-warn:focus-visible { background:var(--warn); color:#fff; filter:none; }
|
||||
/* Credentiale RAR: doua carduri de mediu paralele. */
|
||||
.env-cards { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-bottom:18px; }
|
||||
.env-card { border:1px solid var(--line); border-radius:10px; padding:16px; background:var(--card2); }
|
||||
.env-card.active-test { border-color:color-mix(in srgb,var(--ok) 45%,var(--line)); }
|
||||
.env-card h4 { margin:0 0 12px; font-size:var(--fs-sm); display:flex; align-items:center;
|
||||
justify-content:space-between; gap:8px; }
|
||||
.env-card .env-sw { display:flex; align-items:center; gap:8px; font-size:var(--fs-sm);
|
||||
color:var(--muted); margin-bottom:12px; }
|
||||
.env-card .env-lbl { display:block; font-size:var(--fs-xs); color:var(--muted); margin-bottom:5px; }
|
||||
.env-card input[type=email], .env-card input[type=password] {
|
||||
width:100%; font:inherit; background:var(--bg); color:var(--ink); border:1px solid var(--line);
|
||||
border-radius:6px; padding:8px 10px; margin-bottom:10px; font-size:var(--fs-sm); }
|
||||
.env-card .env-confirm { display:flex; align-items:flex-start; gap:8px; font-size:var(--fs-xs);
|
||||
color:var(--muted); line-height:1.4;
|
||||
background:color-mix(in srgb,var(--err) 7%,transparent);
|
||||
border:1px solid color-mix(in srgb,var(--err) 22%,transparent);
|
||||
border-radius:7px; padding:9px 11px; margin-top:2px; }
|
||||
.env-card .env-confirm input { margin-top:2px; flex-shrink:0; }
|
||||
.default-env { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:0 0 18px;
|
||||
padding:14px; border:1px solid var(--line); border-radius:9px; background:var(--card2); }
|
||||
.default-env select { font:inherit; background:var(--bg); color:var(--ink); border:1px solid var(--line);
|
||||
border-radius:6px; padding:7px 10px; max-width:340px; }
|
||||
@media (max-width:640px) { .env-cards { grid-template-columns:1fr; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{# US-010 (PRD 5.16): antet branduit ROA AUTOPASS.
|
||||
{# Antet branduit ROA AUTOPASS.
|
||||
Grila 3 coloane — stanga (logo) | centru (titlu+env+tier+account_name) | dreapta (RAR dot + tema + burger).
|
||||
Antet MINIMAL pe /login: nu afiseaza RAR dot, meniu burger sau account_name (nelogat). #}
|
||||
<header>
|
||||
@@ -850,7 +928,7 @@
|
||||
</div>
|
||||
{# Celula dreapta: dot RAR (numai cand logat) + selector tema + versiune + meniu burger #}
|
||||
<div class="header-right">
|
||||
{# US-003 (PRD 5.16): dot RAR in antet — OK = chip verde pulsant, BLOCAT = chip rosu.
|
||||
{# Dot RAR in antet — OK = chip verde pulsant, BLOCAT = chip rosu.
|
||||
Banda plina apare DOAR in _status.html cand BLOCAT (nu mai e mereu vizibila). #}
|
||||
{% if is_authenticated|default(false) %}
|
||||
{% if sanatate_ok|default(true) %}
|
||||
@@ -868,11 +946,11 @@
|
||||
<span class="rar-tx">RAR blocat</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# US-004 (PRD 5.19 / D1): comutatorul "Trimite automat la RAR" langa semnalul RAR.
|
||||
In afara swap-ului periodic al #status-bar (D3). #}
|
||||
{# Comutatorul "Trimite automat la RAR" langa semnalul RAR.
|
||||
In afara swap-ului periodic al #status-bar. #}
|
||||
{% include '_auto_send_toggle.html' %}
|
||||
{% endif %}
|
||||
{# US-011 (PRD 5.16): selector tema = pill cu icon FIX (acelasi SVG ca landing) +
|
||||
{# Selector tema = pill cu icon FIX (acelasi SVG ca landing) +
|
||||
eticheta temei curente. Eticheta ascunsa pe <=560px via CSS. JS actualizeaza
|
||||
doar #tema-label (iconita nu se mai schimba per tema — consecventa cu landing). #}
|
||||
<button id="tema-toggle" class="tema-btn"
|
||||
@@ -885,14 +963,14 @@
|
||||
<span class="muted" style="font-size:var(--fs-xs);">v{{ version }}</span>
|
||||
{% if is_authenticated|default(false) %}
|
||||
{# Meniu cont: Cont/Integrare/Nomenclator + (admin) + logout.
|
||||
US-010: structura cu <hr> separatori + RAR status (prima intrare) + Plan tier.
|
||||
Structura cu <hr> separatori + RAR status (prima intrare) + Plan tier.
|
||||
Pe paginile neautentificate (login/signup) nu se randeaza deloc. #}
|
||||
<div class="cont-menu-wrap">
|
||||
<button id="cont-menu-toggle" class="icon-btn"
|
||||
aria-haspopup="true" aria-expanded="false" aria-controls="cont-menu"
|
||||
aria-label="Meniu cont" title="Meniu cont">☰</button>
|
||||
<div id="cont-menu" class="cont-menu" role="menu" aria-labelledby="cont-menu-toggle" hidden>
|
||||
{# Prima intrare: starea RAR (US-003) #}
|
||||
{# Prima intrare: starea RAR #}
|
||||
{% if sanatate_ok|default(true) %}
|
||||
<div class="menu-rar-line ok" role="menuitem" aria-disabled="true">
|
||||
<span style="width:8px;height:8px;border-radius:99px;background:currentColor;display:inline-block;"></span>
|
||||
@@ -904,31 +982,31 @@
|
||||
RAR indisponibil
|
||||
</div>
|
||||
{% endif %}
|
||||
{# Plan cont curent (US-006 PRD 5.17): linie detaliata cu trial/consum/warn.
|
||||
Warn = culoare + text (accesibilitate, decizie #14). #}
|
||||
{# Plan cont curent: linie detaliata cu trial/consum/warn.
|
||||
Warn = culoare + text (accesibilitate). #}
|
||||
<div class="menu-rar-line" role="menuitem" aria-disabled="true"
|
||||
style="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|default('Plan: ' + (tier_label|default('Gratuit'))) }}
|
||||
</div>
|
||||
<hr>
|
||||
{# Navigare principala: Trimiteri + Mapari #}
|
||||
<a role="menuitem" href="/">Trimiteri</a>
|
||||
{# Grup LUCRU: fluxul zilnic — trimiteri, mapari, nomenclator. #}
|
||||
<div class="cont-menu-group">Lucru</div>
|
||||
<a role="menuitem" href="/"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M22 2 11 13"/><path d="M22 2 15 22l-4-9-9-4z"/></svg></span>Trimiteri</a>
|
||||
{% set _mapari_badge = (badges.mapari if (badges is defined and badges and badges.mapari) else 0) %}
|
||||
<a role="menuitem" href="/?tab=mapari">Mapari{% if _mapari_badge %}<span class="tab-badge" aria-hidden="true" style="display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px; margin-left:6px; padding:0 5px; border-radius:99px; background:var(--err); color:#fff; font-size:11px; font-weight:700;">{{ _mapari_badge }}</span>{% endif %}</a>
|
||||
<a role="menuitem" href="/?tab=mapari"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M10 14 14 10"/><path d="M11.5 6.5 13 5a4 4 0 0 1 6 6l-1.5 1.5"/><path d="M12.5 17.5 11 19a4 4 0 0 1-6-6l1.5-1.5"/></svg></span>Mapari{% if _mapari_badge %}<span class="tab-badge" aria-hidden="true" style="display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px; padding:0 5px; border-radius:99px; background:var(--err); color:#fff; font-size:11px; font-weight:700;">{{ _mapari_badge }}</span>{% endif %}</a>
|
||||
<a role="menuitem" href="/?tab=nomenclator"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 4a1 1 0 0 1 1-1h13v18H6a1 1 0 0 0-1 1z"/><path d="M5 18h14"/></svg></span>Nomenclator</a>
|
||||
<hr>
|
||||
{# Nomenclator: coduri RAR — public, dar in meniu arata mai logic la logat #}
|
||||
<a role="menuitem" href="/?tab=nomenclator">Nomenclator</a>
|
||||
<hr>
|
||||
{# Setari cont #}
|
||||
<a role="menuitem" href="/?tab=cont">Cont</a>
|
||||
<a role="menuitem" href="/?tab=integrare">Integrare</a>
|
||||
<a role="menuitem" href="/?tab=jurnal">Jurnal</a>
|
||||
{% if is_admin|default(false) %}<a role="menuitem" href="/admin">Conturi clienti</a>{% endif %}
|
||||
{# Grup CONT: configurare + audit + admin. "Cont" redenumit "Setari" (URL ramane ?tab=cont). #}
|
||||
<div class="cont-menu-group">Cont</div>
|
||||
<a role="menuitem" href="/?tab=cont"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M4.6 4.6l2.1 2.1M17.3 17.3l2.1 2.1M4.6 19.4l2.1-2.1M17.3 6.7l2.1-2.1"/></svg></span>Setari</a>
|
||||
<a role="menuitem" href="/?tab=integrare"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3v6M15 3v6"/><path d="M7 9h10v3a5 5 0 0 1-10 0z"/><path d="M12 17v4"/></svg></span>Integrare</a>
|
||||
<a role="menuitem" href="/?tab=jurnal"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M7 3h8l4 4v14H7z"/><path d="M15 3v4h4"/><path d="M10 13h6M10 17h6"/></svg></span>Jurnal</a>
|
||||
{% if is_admin|default(false) %}<a role="menuitem" href="/admin"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><circle cx="9" cy="8" r="3"/><path d="M3.5 20a5.5 5.5 0 0 1 11 0"/><path d="M16 5.5a3 3 0 0 1 0 5"/><path d="M17.5 14.2A5.5 5.5 0 0 1 21 20"/></svg></span>Conturi clienti</a>{% endif %}
|
||||
<hr>
|
||||
<form method="post" action="/logout">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token|default('') }}">
|
||||
<button role="menuitem" type="submit">Iesi din cont</button>
|
||||
<button role="menuitem" type="submit"><span class="mi"><svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M14 8V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2v-3"/><path d="M9 12h12"/><path d="m18 9 3 3-3 3"/></svg></span>Iesi din cont</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -954,12 +1032,12 @@
|
||||
<div id="detaliu-modal-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
{# Slot pentru modalul de confirmare tipata (PRD 5.19 D4): auto-release OFF->ON injecteaza
|
||||
{# Slot pentru modalul de confirmare tipata: auto-release OFF->ON injecteaza
|
||||
aici modalul via OOB (#modal-confirma-slot). Bulk "Trimite toate" isi randeaza propriul
|
||||
modal inline in _coada.html. #}
|
||||
<div id="modal-confirma-slot"></div>
|
||||
<script>
|
||||
// Comutator tema ciclic (DRY E2 — PRD 5.15): config traieste intr-o singura structura
|
||||
// Comutator tema ciclic: config traieste intr-o singura structura
|
||||
// sursa-de-adevar THEMES din care se DERIVA CYCLE/VALID/LABELS/NEXT.
|
||||
// Adaugarea unei teme noi = O singura intrare in THEMES.
|
||||
// Ciclu: Light->Dark->Petrol->Grafit->Cobalt->Cupru->Hartie->Auto->(inapoi la Light).
|
||||
@@ -997,7 +1075,7 @@
|
||||
}
|
||||
function _syncButton(stored) {
|
||||
var s = VALID[stored] ? stored : 'auto';
|
||||
// US-011: iconita e fixa (nu se schimba per tema); actualizam doar eticheta.
|
||||
// Iconita e fixa (nu se schimba per tema); actualizam doar eticheta.
|
||||
var label = document.getElementById('tema-label');
|
||||
if (label) label.textContent = LABELS[s];
|
||||
btn.setAttribute('aria-label', 'Tema: ' + LABELS[s] + ', apasa pentru ' + NEXT[s]);
|
||||
@@ -1109,6 +1187,28 @@
|
||||
if (saveBtn) saveBtn.classList.add('dirty');
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// Sub-taburi pagina Setari: comutare pur client-side, fara server.
|
||||
// Delegare pe document -> supravietuieste swap-urilor HTMX ale #card-cont (dupa
|
||||
// fiecare salvare serverul re-randeaza cu sub-tabul corect via `aria-selected`/`hidden`,
|
||||
// iar acest handler preia doar navigarea manuala intre taburi).
|
||||
document.addEventListener('click', function(e) {
|
||||
var tab = e.target.closest('.setari-subtab');
|
||||
if (!tab) return;
|
||||
var card = tab.closest('#card-cont');
|
||||
if (!card) return;
|
||||
var name = tab.getAttribute('data-subtab');
|
||||
card.querySelectorAll('.setari-subtab').forEach(function(t) {
|
||||
var on = t === tab;
|
||||
t.setAttribute('aria-selected', on ? 'true' : 'false');
|
||||
t.classList.toggle('is-active', on);
|
||||
});
|
||||
card.querySelectorAll('.setari-pane').forEach(function(p) {
|
||||
if (p.getAttribute('data-subpane') === name) { p.removeAttribute('hidden'); }
|
||||
else { p.setAttribute('hidden', ''); }
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// Toast global: feedback tranzitoriu vizibil + accesibil (aria-live).
|
||||
// window.arataToast(text, stareCss) — stareCss (ex. "s-error"/"s-needs_review")
|
||||
@@ -1274,7 +1374,7 @@
|
||||
// Deschidere la click pe rand (htmx:beforeRequest): arata modalul cu placeholder
|
||||
// inainte ca raspunsul fragmentului sa fie swap-uit in corp.
|
||||
// Trateaza atat .trimitere-row (Trimiteri) cat si .btn-editeaza (preview import)
|
||||
// → open() instaleaza inert pe <main>, focus-trap si readuce focusul la inchidere (US-006).
|
||||
// → open() instaleaza inert pe <main>, focus-trap si readuce focusul la inchidere.
|
||||
document.body.addEventListener('htmx:beforeRequest', function(evt) {
|
||||
var elt = evt.detail && evt.detail.elt;
|
||||
if (!elt || !elt.classList) return;
|
||||
@@ -1387,7 +1487,7 @@
|
||||
// Daca difera (schimbari externe — ex. worker a procesat trimiteri), reincarca automat
|
||||
// pastrand filtrul curent. Fara nudge "Date noi" — auto-refresh e mai consistent.
|
||||
// Decizie: nudge eliminat; distinctia propriu vs extern e imposibila pe client
|
||||
// fara sesiune dedicata — auto-refresh acoper ambele cazuri (US-008).
|
||||
// fara sesiune dedicata — auto-refresh acoper ambele cazuri.
|
||||
var INTERVAL = 20000;
|
||||
function versiuneCurenta() {
|
||||
var e = document.getElementById('trimiteri-versiune');
|
||||
|
||||
Reference in New Issue
Block a user