fix(setup,ui): risolve errori setup + logo SVG theme-aware

- setup: corregge path templates (sibling di api/, non figlio) e firma TemplateResponse
- setup: invalida sessione client dopo operazioni che ruotano l'API key (init DB, creazione admin, cambio password, attivazione utente)
- api_client: include il nome del campo nei messaggi di errore 422 (FastAPI validation)
- ui: nuovo componente _app_logo.html (SVG inline theme-aware) usato su login e navbar
This commit is contained in:
Adriano Dal Pastro
2026-05-20 07:42:49 +00:00
parent 182aa9fa9a
commit 6772e3166a
6 changed files with 80 additions and 19 deletions
+14 -4
View File
@@ -56,11 +56,21 @@ class APIClient:
try:
error_body = response.json()
detail = error_body.get("detail", str(error_body))
# FastAPI 422 returns detail as a list of validation errors
# FastAPI 422 returns detail as a list of validation errors:
# [{"type": ..., "loc": ["body", "password"], "msg": "...", ...}, ...]
if isinstance(detail, list):
detail = "; ".join(
e.get("msg", str(e)) for e in detail if isinstance(e, dict)
) or str(detail)
parts = []
for e in detail:
if not isinstance(e, dict):
parts.append(str(e))
continue
msg = e.get("msg", str(e))
loc = e.get("loc") or []
# Strip leading "body"/"query"/"path" segments; keep field path.
field_path = [str(p) for p in loc if p not in ("body", "query", "path")]
field = ".".join(field_path) if field_path else None
parts.append(f"{field}: {msg}" if field else msg)
detail = "; ".join(parts) or str(detail)
except Exception:
detail = response.text or f"HTTP {response.status_code}"
@@ -8,13 +8,10 @@
<div class="bg-white dark:bg-slate-800 shadow-lg rounded-xl p-8">
<!-- Logo -->
<div class="text-center mb-8">
<img src="{{ url_for('static', filename='img/tmflow-logo.svg') }}"
alt="TieMeasureFlow Logo"
class="mx-auto h-16 w-auto mb-4"
onerror="this.style.display='none'">
<h2 class="text-3xl font-bold text-slate-900 dark:text-white mb-2">
TieMeasureFlow
</h2>
<div class="mx-auto mb-4 inline-flex justify-center text-slate-900 dark:text-white">
{% set logo_class = 'h-16 w-auto' %}
{% include 'components/_app_logo.html' %}
</div>
<p class="text-sm text-slate-600 dark:text-slate-400">
{{ _('Accedi al sistema') }}
</p>
@@ -0,0 +1,35 @@
<!--
Inline TieMeasureFlow logo. Text fills use `currentColor`, so wrap with a
parent that sets `color` (e.g. `text-slate-900 dark:text-white`) to make the
wordmark adapt to the active theme. The caliper/flow icon keeps its brand
blue regardless of theme.
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 260 48" fill="none"
class="{{ logo_class|default('h-10 w-auto') }}"
aria-label="TieMeasureFlow">
<!-- Caliper + flow icon (always brand color) -->
<g transform="translate(2, 6)">
<rect x="0" y="4" width="6" height="32" rx="1.5" fill="#2563EB"/>
<rect x="0" y="4" width="24" height="6" rx="1.5" fill="#2563EB"/>
<rect x="0" y="30" width="24" height="6" rx="1.5" fill="#2563EB"/>
<rect x="14" y="10" width="5" height="8" rx="1" fill="#1E40AF"/>
<rect x="14" y="22" width="5" height="8" rx="1" fill="#1E40AF"/>
<rect x="2" y="18" width="16" height="4" rx="1" fill="#3B82F6" opacity="0.6"/>
<rect x="7" y="7" width="1" height="3" rx="0.5" fill="#FFFFFF" opacity="0.7"/>
<rect x="10" y="7" width="1" height="3" rx="0.5" fill="#FFFFFF" opacity="0.7"/>
<rect x="13" y="7" width="1" height="3" rx="0.5" fill="#FFFFFF" opacity="0.7"/>
<rect x="16" y="7" width="1" height="3" rx="0.5" fill="#FFFFFF" opacity="0.7"/>
<rect x="19" y="7" width="1" height="3" rx="0.5" fill="#FFFFFF" opacity="0.7"/>
<path d="M26 20 C30 20, 32 14, 36 14 C40 14, 40 20, 36 20"
stroke="#2563EB" stroke-width="2.5" stroke-linecap="round" fill="none"/>
<path d="M34 17 L37 20 L34 23"
stroke="#2563EB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
</g>
<!-- Wordmark: themed via currentColor; "Measure" stays brand-tinted -->
<g transform="translate(52, 0)" font-family="Inter, system-ui, sans-serif" letter-spacing="-0.5">
<text x="0" y="34" font-size="28" font-weight="700" fill="currentColor">Tie</text>
<text x="44" y="34" font-size="28" font-weight="500" fill="#2563EB">Measure</text>
<text x="166" y="34" font-size="28" font-weight="700" fill="currentColor">Flow</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -6,14 +6,14 @@
<!-- Left: Logo -->
<div class="flex items-center gap-3">
<a href="{{ url_for('index') }}" class="flex items-center gap-2.5 group">
<a href="{{ url_for('index') }}"
class="flex items-center gap-2.5 group text-slate-900 dark:text-white">
{% if company_logo %}
<img src="{{ url_for('static', filename='img/' ~ company_logo) }}" alt="Logo" class="h-8 w-auto"
onerror="this.src='{{ url_for('static', filename='img/tmflow-logo.svg') }}'">
<img src="{{ url_for('static', filename='img/' ~ company_logo) }}" alt="Logo" class="h-10 w-auto"
onerror="this.style.display='none'">
{% else %}
<img src="{{ url_for('static', filename='img/tmflow-logo.svg') }}"
alt="TieMeasureFlow"
class="h-8 w-auto">
{% set logo_class = 'h-10 w-auto' %}
{% include 'components/_app_logo.html' %}
{% endif %}
</a>
</div>