@page "/user" @attribute [Authorize] @using Microsoft.Extensions.Logging @using SteUp.Shared.Components.Layout @using SteUp.Shared.Components.Layout.Overlay @using SteUp.Shared.Components.SingleElements @using SteUp.Shared.Components.SingleElements.MessageBox @using SteUp.Shared.Core.Authorization.Enum @using SteUp.Shared.Core.Dto @using SteUp.Shared.Core.Interface.IntegryApi @using SteUp.Shared.Core.Interface.System @using SteUp.Shared.Core.Services @using SteUp.Shared.Core.Utility @inject AppAuthenticationStateProvider AuthenticationStateProvider @inject IGenericSystemService GenericSystemService @inject IFileManager FileManager @inject IIntegryApiService IntegryApiService @inject ILogger Logger
@if (IsLoggedIn) { @* §6.16 Intestazione profilo *@

@UserSession.User.Fullname

@if (UserSession.User.KeyGroup is not null) {

@(((KeyGroupEnum)UserSession.User.KeyGroup).ConvertToHumanReadable())

}
@* Le voci distruttive portano l'icona nel tono danger e non hanno chevron. *@
}
@code { private bool IsLoggedIn { get; set; } private bool VisibleOverlay { get; set; } private string? _progressMessage; private string? CodHash { get; set; } = ""; private ConfirmMessageBox _logoutBox = null!; private ConfirmMessageBox _imagesBox = null!; private string _imagesBoxMessage = string.Empty; private Core.Helpers.StatusBadgeHelper.BadgeSpec ConnessioneBadge => NetworkService.ConnectionAvailable ? new Core.Helpers.StatusBadgeHelper.BadgeSpec("success", "ri-cloud-line", "Online") : new Core.Helpers.StatusBadgeHelper.BadgeSpec("danger", "ri-wifi-off-line", "Offline"); protected override async Task OnInitializedAsync() { IsLoggedIn = await UserSession.IsLoggedIn(); CodHash = LocalStorage.GetString("codHash"); StateHasChanged(); } private async Task ExportLog() { if (VisibleOverlay) return; if (!NetworkService.ConnectionAvailable) { Snackbar.Add("Sei offline: per inviare i log serve la connessione.", Severity.Warning); return; } var includeImages = await AskIncludeImages(); if (includeImages is null) return; _progressMessage = "Preparazione dei log…"; VisibleOverlay = true; StateHasChanged(); var partCount = 0; var sentParts = 0; try { // Un'email per parte: ogni parte resta sotto i limiti di upload dei servizi. await using var export = await FileManager.PrepareLogExportAsync(includeImages.Value); partCount = export.PartCount; var profiloAzienda = LocalStorage.GetString("codHash"); var subject = $"SteUP - Log del {DateTime.Today:d} di {UserSession.User.Username}"; var body = $"Username: {UserSession.User.Username}
" + $"Profilo azienda: {profiloAzienda}
" + $"ProfileDb: {UserSession.ProfileDb}
" + $"Versione app: {GenericSystemService.GetCurrentAppVersion()}"; for (var i = 0; i < partCount; i++) { var multiPart = partCount > 1; _progressMessage = multiPart ? $"Invio dei log… parte {i + 1} di {partCount}" : "Invio dei log…"; StateHasChanged(); var attachments = await export.BuildPartAsync(i); await IntegryApiService.SendEmail(new SendEmailDto { FromName = "Integry Log", To = "developer@integry.it", Subject = multiPart ? $"{subject} (parte {i + 1}/{partCount})" : subject, IsHtml = true, MsgText = multiPart ? $"{body}
Parte: {i + 1} di {partCount}" : body, Attachments = attachments }); sentParts++; } Snackbar.Add(partCount > 1 ? $"Log inviati allo sviluppo in {partCount} parti" : "Log inviati allo sviluppo", Severity.Success); } catch (Exception e) { Logger.LogError(e, "Invio dei log interrotto dopo {Sent} parti su {Total}", sentParts, partCount); Snackbar.Add(sentParts > 0 ? $"Invio interrotto: inviate {sentParts} parti su {partCount}. Controlla la connessione e riprova." : "Invio dei log non riuscito. Controlla la connessione e riprova.", Severity.Error); } finally { VisibleOverlay = false; _progressMessage = null; StateHasChanged(); } } /// /// Chiede se allegare le foto, indicando quanto pesano. Null = invio annullato. /// Se sul dispositivo non ci sono foto non chiede niente. /// private async Task AskIncludeImages() { long imagesSize; _progressMessage = "Controllo delle foto…"; VisibleOverlay = true; StateHasChanged(); try { imagesSize = await FileManager.GetLogExportImagesSizeAsync(); } catch (Exception e) { // Senza sapere quanto pesano, meglio un invio leggero che uno che rischia di fallire. Logger.LogWarning(e, "Impossibile calcolare la dimensione delle foto da inviare"); imagesSize = 0; } finally { VisibleOverlay = false; _progressMessage = null; StateHasChanged(); } if (imagesSize == 0) return false; var sizeText = imagesSize < 1024 * 1024 ? "meno di 1 MB" : $"circa {imagesSize / (1024d * 1024):N0} MB"; _imagesBoxMessage = $"Le foto delle ispezioni occupano {sizeText}. Servono solo se il problema " + "riguarda le foto: senza, l'invio è molto più veloce."; StateHasChanged(); // "Solo i log" è la scelta consigliata (pulsante pieno, true); "Includi le foto" -> false. var result = await _imagesBox.ShowAsync(); return result is null ? null : result == false; } private async Task UpdateDb() { _progressMessage = "Sincronizzazione…"; VisibleOverlay = true; StateHasChanged(); try { await SteupDataService.CheckAndUpdateStatus(); Snackbar.Add("Ispezioni aggiornate", Severity.Success); } catch { Snackbar.Add("Sincronizzazione non riuscita. Controlla la connessione e riprova.", Severity.Error); } finally { VisibleOverlay = false; _progressMessage = null; StateHasChanged(); } } private async Task ConfirmLogout() { var result = await _logoutBox.ShowAsync(); if (result is not true) return; await AuthenticationStateProvider.SignOut(); IsLoggedIn = await UserSession.IsLoggedIn(); StateHasChanged(); } }