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>
This commit is contained in:
@@ -19,32 +19,48 @@
|
||||
<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">
|
||||
<div class="onboarding__field">
|
||||
<MudTextField @bind-Value="UserData.Username" Label="Username"
|
||||
Variant="Variant.Text" Immediate="true"
|
||||
UserAttributes="@(new() { ["autocomplete"] = "username", ["enterkeyhint"] = "next", ["autocapitalize"] = "none" })"/>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
<div class="onboarding__field">
|
||||
<MudTextField InputType="@_passwordInput" @bind-Value="UserData.Password" Label="Password"
|
||||
Variant="Variant.Text" Immediate="true"
|
||||
Adornment="Adornment.End" AdornmentIcon="@_passwordInputIcon"
|
||||
OnAdornmentClick="ShowPassword"
|
||||
AdornmentAriaLabel="@(_isShow ? "Nascondi la password" : "Mostra la password")"
|
||||
UserAttributes="@(new() { ["autocomplete"] = "current-password", ["enterkeyhint"] = "next" })"/>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
<div class="onboarding__field">
|
||||
<MudTextField @bind-Value="UserData.CodHash" Label="Profilo azienda"
|
||||
Variant="Variant.Text" Immediate="true"
|
||||
UserAttributes="@(new() { ["autocomplete"] = "organization", ["enterkeyhint"] = "go", ["autocapitalize"] = "none" })"/>
|
||||
</div>
|
||||
<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)
|
||||
{
|
||||
<p class="onboarding__error" role="alert" aria-live="assertive">@ErrorMessage</p>
|
||||
@* 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)">
|
||||
@@ -73,20 +89,13 @@
|
||||
private bool _busy;
|
||||
|
||||
private bool _isShow;
|
||||
private InputType _passwordInput = InputType.Password;
|
||||
private string _passwordInputIcon = Icons.Material.Rounded.VisibilityOff;
|
||||
|
||||
private bool CanSubmit =>
|
||||
!string.IsNullOrWhiteSpace(UserData.Username) &&
|
||||
!string.IsNullOrWhiteSpace(UserData.Password) &&
|
||||
!string.IsNullOrWhiteSpace(UserData.CodHash);
|
||||
|
||||
private void ShowPassword()
|
||||
{
|
||||
_isShow = !_isShow;
|
||||
_passwordInputIcon = _isShow ? Icons.Material.Rounded.Visibility : Icons.Material.Rounded.VisibilityOff;
|
||||
_passwordInput = _isShow ? InputType.Text : InputType.Password;
|
||||
}
|
||||
private void ShowPassword() => _isShow = !_isShow;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
|
||||
@@ -881,7 +881,7 @@
|
||||
padding: var(--space-lg);
|
||||
padding-top: calc(var(--space-lg) + env(safe-area-inset-top, 0px));
|
||||
padding-bottom: calc(var(--space-lg) + env(safe-area-inset-bottom, 0px));
|
||||
background-color: var(--surface-muted);
|
||||
background-color: var(--workspace);
|
||||
}
|
||||
|
||||
.onboarding__panel {
|
||||
@@ -892,40 +892,80 @@
|
||||
}
|
||||
|
||||
.onboarding__logo {
|
||||
height: 128px;
|
||||
height: 104px;
|
||||
object-fit: contain;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
/* Un pannello solo, tre righe divise da una linea: la stessa forma delle
|
||||
liste dell'app, invece di tre riquadri che galleggiano separati. */
|
||||
.onboarding__fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-md);
|
||||
margin-top: var(--space-xl);
|
||||
background-color: var(--surface);
|
||||
border-radius: var(--radius-surface);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.onboarding__field {
|
||||
background-color: var(--surface);
|
||||
border: 1px solid var(--divider);
|
||||
border-radius: var(--radius-control);
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
transition: border-color var(--duration-fast) var(--ease-out),
|
||||
box-shadow var(--duration-fast) var(--ease-out);
|
||||
display: block;
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
transition: background-color var(--duration-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.onboarding__field:focus-within {
|
||||
border-color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px var(--primary-dark);
|
||||
.onboarding__field + .onboarding__field { border-top: 1px solid var(--divider); }
|
||||
|
||||
.onboarding__field:focus-within { background-color: var(--surface-muted); }
|
||||
|
||||
/* L'etichetta sta sopra il campo e non si muove: niente testo che scivola
|
||||
quando appoggi il dito. */
|
||||
.onboarding__label {
|
||||
display: block;
|
||||
font-size: var(--label-md-size);
|
||||
line-height: 1.25;
|
||||
font-weight: 500;
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
|
||||
.onboarding__error {
|
||||
margin-top: var(--space-lg);
|
||||
text-align: center;
|
||||
.onboarding__input-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
.onboarding__input {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
min-height: 34px;
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
font-family: inherit;
|
||||
font-size: var(--body-lg-size);
|
||||
font-weight: 600;
|
||||
color: var(--danger-ink);
|
||||
font-weight: 500;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.onboarding__reveal {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--touch-min);
|
||||
height: var(--touch-min);
|
||||
margin-right: calc(var(--space-xs) * -1);
|
||||
border: none;
|
||||
border-radius: var(--radius-pill);
|
||||
background: none;
|
||||
color: var(--ink-muted);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.onboarding__reveal:active { background-color: var(--surface-muted); }
|
||||
|
||||
.onboarding__error { margin-top: var(--space-md); }
|
||||
|
||||
/* Bottone a pillola, alto 52: e' l'unico gesto della schermata. */
|
||||
.onboarding__submit {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user