Files
SteUP_Dotnet/SteUp.Shared/Components/Pages/LoginPage.razor
T
MarcoE 66ed92299b Ridisegna la schermata di accesso
Ogni campo era un riquadro dentro il riquadro, con l'etichetta che saltava
sopra il testo al primo tocco: un modulo web, non una schermata. Ora i tre
campi stanno in un pannello solo diviso da una linea, come le liste del resto
dell'app, e l'etichetta sta ferma sopra il campo.

Lo sfondo passa alla superficie di lavoro, la stessa dello splash e della prima
schermata: l'avvio non cambia colore tre volte. L'errore di accesso usa il
riquadro di avviso gia' in uso dentro l'app invece di uno stile suo.

Non verificata sul terminale: la sessione sul dispositivo e' aperta e non l'ho
chiusa per non far perdere l'accesso.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 12:47:36 +02:00

147 lines
5.5 KiB
Plaintext

@page "/login"
@using Microsoft.Extensions.Logging
@using SteUp.Shared.Core.BarcodeReader.Contracts
@using SteUp.Shared.Core.Interface.System
@using SteUp.Shared.Core.Services
@inject IUserAccountService UserAccountService
@inject AppAuthenticationStateProvider AuthenticationStateProvider
@inject IGenericSystemService GenericSystemService
@inject IBarcodeManager BarcodeManager
@inject ILogger<LoginPage> Logger
@*
Accesso (STILE_UI §7): stessa struttura dell'app, registro diverso.
Niente accento cromatico — l'attenzione sta sul marchio; il corallo torna
dentro l'app, dove significa "qui si agisce".
*@
<div class="onboarding">
<form class="onboarding__panel" @onsubmit="SignInUser" @onsubmit:preventDefault="true">
<img src="_content/SteUp.Shared/images/logo_steup.svg" class="onboarding__logo" alt="SteUP"/>
@* Un solo pannello con tre righe divise da una linea, come le liste
del resto dell'app. Prima ogni campo era un riquadro dentro il
riquadro, con l'etichetta che saltava sopra il testo al primo tocco:
un gesto da modulo web, non da applicazione. Qui l'etichetta sta
ferma sopra il campo e non si muove mai. *@
<div class="onboarding__fields">
<label class="onboarding__field">
<span class="onboarding__label">Username</span>
<input class="onboarding__input" type="text" autocomplete="username"
autocapitalize="none" autocorrect="off" enterkeyhint="next"
value="@UserData.Username" @oninput="@(e => UserData.Username = e.Value?.ToString())"/>
</label>
<label class="onboarding__field">
<span class="onboarding__label">Password</span>
<span class="onboarding__input-row">
<input class="onboarding__input" type="@(_isShow ? "text" : "password")"
autocomplete="current-password" enterkeyhint="next"
value="@UserData.Password" @oninput="@(e => UserData.Password = e.Value?.ToString())"/>
<button type="button" class="onboarding__reveal" @onclick="ShowPassword"
aria-label="@(_isShow ? "Nascondi la password" : "Mostra la password")">
<i class="@(_isShow ? "ri-eye-off-line" : "ri-eye-line")" aria-hidden="true"></i>
</button>
</span>
</label>
<label class="onboarding__field">
<span class="onboarding__label">Profilo azienda</span>
<input class="onboarding__input" type="text" autocomplete="organization"
autocapitalize="none" autocorrect="off" enterkeyhint="go"
value="@UserData.CodHash" @oninput="@(e => UserData.CodHash = e.Value?.ToString())"/>
</label>
</div>
@if (_attemptFailed)
{
@* Stesso riquadro di avviso usato dentro l'app: l'errore di accesso
non e' un caso speciale che merita un suo stile. *@
<div class="feedback feedback--danger onboarding__error" role="alert" aria-live="assertive">
<i class="feedback__icon ri-error-warning-line" aria-hidden="true"></i>
<span>@ErrorMessage</span>
</div>
}
<button type="submit" class="onboarding__submit" disabled="@(_busy || !CanSubmit)">
@if (_busy)
{
<span class="onboarding__spinner" aria-hidden="true"></span>
<span>Accesso in corso…</span>
}
else
{
<span>Accedi</span>
}
</button>
<div class="onboarding__footer">
<span>@GenericSystemService.GetCurrentAppVersion() · Powered by</span>
<img src="_content/SteUp.Shared/images/logoIntegry.svg" alt="Integry"/>
</div>
</form>
</div>
@code {
private SignIn UserData { get; } = new();
private string ErrorMessage { get; set; } = "";
private bool _attemptFailed;
private bool _busy;
private bool _isShow;
private bool CanSubmit =>
!string.IsNullOrWhiteSpace(UserData.Username) &&
!string.IsNullOrWhiteSpace(UserData.Password) &&
!string.IsNullOrWhiteSpace(UserData.CodHash);
private void ShowPassword() => _isShow = !_isShow;
protected override void OnInitialized()
{
UserData.CodHash = LocalStorage.GetString("codHash");
StateHasChanged();
}
private async Task SignInUser()
{
if (_busy || !CanSubmit) return;
_attemptFailed = false;
_busy = true;
StateHasChanged();
try
{
SteupDataService.RegisterAppVersion();
await UserAccountService.Login(UserData.Username!, UserData.Password!, UserData.CodHash!);
AuthenticationStateProvider.NotifyAuthenticationState(); //Chiamato per forzare il refresh
await SteupDataService.Init();
BarcodeManager.Init();
LocalStorage.SetString("codHash", UserData.CodHash!);
NavigationManager.NavigateTo("/");
}
catch (Exception e)
{
ErrorMessage = e.Message;
Logger.LogError(e, ErrorMessage);
_attemptFailed = true;
}
finally
{
_busy = false;
StateHasChanged();
}
}
public class SignIn
{
public string? Username { get; set; }
public string? Password { get; set; }
public string? CodHash { get; set; }
}
}