Creata pagina "user"

This commit is contained in:
2026-02-06 18:08:40 +01:00
parent 755f78ef9d
commit d8bef12f30
18 changed files with 660 additions and 25 deletions

View File

@@ -18,6 +18,7 @@
<link rel="stylesheet" href="_content/SteUp.Shared/css/remixicon/remixicon.css"/> <link rel="stylesheet" href="_content/SteUp.Shared/css/remixicon/remixicon.css"/>
<link rel="stylesheet" href="_content/SteUp.Shared/css/app.css"/> <link rel="stylesheet" href="_content/SteUp.Shared/css/app.css"/>
<link rel="stylesheet" href="_content/SteUp.Shared/css/form.css"/>
<link rel="stylesheet" href="_content/SteUp.Shared/css/default-theme.css"/> <link rel="stylesheet" href="_content/SteUp.Shared/css/default-theme.css"/>
<link rel="stylesheet" href="SteUp.Maui.styles.css"/> <link rel="stylesheet" href="SteUp.Maui.styles.css"/>
<link rel="icon" type="image/png" href="favicon.png"/> <link rel="icon" type="image/png" href="favicon.png"/>

View File

@@ -0,0 +1,79 @@
@using SteUp.Shared.Core.Helpers
@inject IJSRuntime Js
<div class="@(Back ? "" : "container") header">
<div class="header-content @(Back ? "with-back" : "no-back")">
@if (!SmallHeader)
{
if (Back)
{
<div class="left-section">
<MudButton StartIcon="@(!Cancel ? Icons.Material.Outlined.ArrowBackIosNew : "")"
OnClick="@GoBack"
Color="Color.Info"
Style="text-transform: none"
Variant="Variant.Text">
@BackTo
</MudButton>
</div>
}
<h3 class="page-title">@Title</h3>
<div class="right-section">
@if (!LabelSave.IsNullOrEmpty())
{
<MudButton OnClick="@OnSave"
Color="Color.Info"
Style="text-transform: none"
Variant="Variant.Text">
@LabelSave
</MudButton>
}
</div>
}
else
{
<div class="title">
<MudText Typo="Typo.h6">
<b>@Title</b>
</MudText>
<MudIconButton Icon="@Icons.Material.Filled.Close" OnClick="@GoBack" />
</div>
}
</div>
</div>
@code{
[Parameter] public string? Title { get; set; }
[Parameter] public bool Back { get; set; }
[Parameter] public bool BackOnTop { get; set; }
[Parameter] public string BackTo { get; set; } = "";
[Parameter] public EventCallback OnFilterToggle { get; set; }
[Parameter] public bool Cancel { get; set; }
[Parameter] public EventCallback OnCancel { get; set; }
[Parameter] public string? LabelSave { get; set; }
[Parameter] public EventCallback OnSave { get; set; }
[Parameter] public bool SmallHeader { get; set; }
protected override void OnParametersSet()
{
Back = !Back ? !Back && Cancel : Back;
BackTo = Cancel ? "Annulla" : BackTo;
}
private async Task GoBack()
{
if (Cancel)
{
await OnCancel.InvokeAsync();
return;
}
await Js.InvokeVoidAsync("goBack");
}
}

View File

@@ -0,0 +1,31 @@
.header {
min-height: var(--mh-header);
width: 100%;
display: flex;
align-items: center;
}
.header-content {
width: 100%;
line-height: normal;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
}
.header-content > .title { width: 100%; }
.header-content.with-back .page-title {
position: absolute;
left: 50%;
transform: translateX(-50%);
margin: 0;
font-size: larger;
}
.left-section ::deep button, .right-section ::deep button { font-size: 1.1rem; }
.left-section ::deep .mud-button-icon-start { margin-right: 3px !important; }
.header-content.no-back .page-title { margin: 0; }

View File

@@ -1,28 +1,23 @@
@using SteUp.Shared.Core.Interface.System.Network
@inject INetworkService NetworkService
<div class="container animated-navbar @(IsVisible ? "show-nav" : "hide-nav") @(IsVisible ? PlusVisible ? "with-plus" : "without-plus" : "with-plus")"> <div class="container animated-navbar @(IsVisible ? "show-nav" : "hide-nav") @(IsVisible ? PlusVisible ? "with-plus" : "without-plus" : "with-plus")">
<nav class="navbar @(IsVisible ? PlusVisible ? "with-plus" : "without-plus" : "with-plus")"> <nav class="navbar @(IsVisible ? PlusVisible ? "with-plus" : "without-plus" : "with-plus")">
<div class="container-navbar"> <div class="container-navbar">
<ul class="navbar-nav flex-row nav-justified align-items-center w-100 text-center"> <ul class="navbar-nav flex-row nav-justified align-items-center w-100 text-center">
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link" href="Users" Match="NavLinkMatch.All"> <NavLink class="nav-link" href="ispezioni" Match="NavLinkMatch.All">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<i class="ri-group-line"></i> <i class="ri-file-list-3-line"></i>
<span>Test</span> <span>Ispezioni</span>
</div> </div>
</NavLink> </NavLink>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link" href="home" Match="NavLinkMatch.All"> <NavLink class="nav-link" href="user" Match="NavLinkMatch.All">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<i class="ri-calendar-todo-line"></i> <i class="ri-user-line"></i>
<span>Home</span> <span>Profilo</span>
</div>
</NavLink>
</li>
<li class="nav-item">
<NavLink class="nav-link" href="Calendar" Match="NavLinkMatch.All">
<div class="d-flex flex-column">
<i class="ri-calendar-todo-line"></i>
<span>Altro</span>
</div> </div>
</NavLink> </NavLink>
</li> </li>
@@ -33,11 +28,13 @@
{ {
<MudMenu PopoverClass="custom_popover" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomRight"> <MudMenu PopoverClass="custom_popover" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomRight">
<ActivatorContent> <ActivatorContent>
<MudFab Class="custom-plus-button" Color="Color.Surface" Size="Size.Medium" IconSize="Size.Medium" IconColor="Color.Primary" StartIcon="@Icons.Material.Filled.Add"/> <MudFab Class="custom-plus-button" Color="Color.Surface" Size="Size.Medium" IconSize="Size.Medium"
IconColor="Color.Primary" StartIcon="@Icons.Material.Filled.Add"/>
</ActivatorContent> </ActivatorContent>
<ChildContent> <ChildContent>
@* <MudMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="() => CreateUser()">Nuovo contatto</MudMenuItem> *@ <MudMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="@NewActivity">
@* <MudMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="() => CreateActivity()">Nuova attivit<69></MudMenuItem> *@ Nuova rilevazione
</MudMenuItem>
</ChildContent> </ChildContent>
</MudMenu> </MudMenu>
} }
@@ -55,10 +52,10 @@
{ {
var location = args.Location.Remove(0, NavigationManager.BaseUri.Length); var location = args.Location.Remove(0, NavigationManager.BaseUri.Length);
var newIsVisible = new List<string> { "home" } var newIsVisible = new List<string> { "ispezioni", "user" }
.Contains(location); .Contains(location);
var newPlusVisible = new List<string> { } var newPlusVisible = new List<string> { "ispezioni", "user" }
.Contains(location); .Contains(location);
if (IsVisible == newIsVisible && PlusVisible == newPlusVisible) return; if (IsVisible == newIsVisible && PlusVisible == newPlusVisible) return;
@@ -69,4 +66,8 @@
}; };
return Task.CompletedTask; return Task.CompletedTask;
} }
private void NewActivity()
{
}
} }

View File

@@ -1,4 +0,0 @@
@page "/home"
@attribute [Authorize]
<h3>Home</h3>

View File

@@ -7,6 +7,6 @@
@code { @code {
protected override void OnInitialized() protected override void OnInitialized()
{ {
NavigationManager.NavigateTo("/home"); NavigationManager.NavigateTo("/ispezioni");
} }
} }

View File

@@ -0,0 +1,9 @@
@page "/ispezioni"
@attribute [Authorize]
@using SteUp.Shared.Components.Layout
<HeaderLayout Title="Ispezioni"/>
<div class="container">
</div>

View File

@@ -0,0 +1,115 @@
@page "/user"
@attribute [Authorize]
@using SteUp.Shared.Components.Layout
@using SteUp.Shared.Components.SingleElements
@using SteUp.Shared.Core.Authorization.Enum
@using SteUp.Shared.Core.Helpers
@using SteUp.Shared.Core.Interface.System.Network
@using SteUp.Shared.Core.Services
@using SteUp.Shared.Core.Utility
@inject AppAuthenticationStateProvider AuthenticationStateProvider
@inject INetworkService NetworkService
<HeaderLayout Title="Profilo"/>
@if (IsLoggedIn)
{
<div class="container content pb-safe-area">
<div class="container-primary-info">
<div class="section-primary-info">
<MudAvatar Style="height: 70px; width: 70px; font-size: 2rem; font-weight: bold"
Color="Color.Secondary">
@UtilityString.ExtractInitials(UserSession.User.Fullname)
</MudAvatar>
<div class="personal-info">
<span class="info-nome">@UserSession.User.Fullname</span>
@if (UserSession.User.KeyGroup is not null)
{
<span
class="info-section">@(((KeyGroupEnum)UserSession.User.KeyGroup).ConvertToHumanReadable())</span>
}
</div>
</div>
<div class="divider"></div>
<div class="section-info">
<div class="section-personal-info">
<div>
<span class="info-title">Profilo azienda</span>
<span class="info-text">@CodHash</span>
</div>
</div>
<div class="section-personal-info">
<div>
<span class="info-title">Status</span>
@if (NetworkService.ConnectionAvailable)
{
<div class="status online">
<i class="ri-wifi-line"></i>
<span>Online</span>
</div>
}
else
{
<div class="status offline">
<i class="ri-wifi-off-line"></i>
<span>Offline</span>
</div>
}
</div>
</div>
</div>
</div>
<div class="container-button">
<MudButton Class="button-settings green-icon"
FullWidth="true"
StartIcon="@Icons.Material.Outlined.Sync"
Size="Size.Medium"
OnClick="@UpdateDb"
Variant="Variant.Outlined">
Sincronizza ispezioni
</MudButton>
</div>
<div class="container-button">
<MudButton Class="button-settings exit"
FullWidth="true"
Color="Color.Error"
Size="Size.Medium"
OnClick="@Logout"
Variant="Variant.Outlined">
Esci
</MudButton>
</div>
<AppVersion/>
</div>
}
@code {
private bool IsLoggedIn { get; set; }
private string? CodHash { get; set; } = "";
protected override async Task OnInitializedAsync()
{
IsLoggedIn = await UserSession.IsLoggedIn();
CodHash = LocalStorage.GetString("codHash");
StateHasChanged();
}
private void UpdateDb()
{
}
private async Task Logout()
{
await AuthenticationStateProvider.SignOut();
IsLoggedIn = await UserSession.IsLoggedIn();
StateHasChanged();
}
}

View File

@@ -0,0 +1,83 @@
.container-primary-info {
background: var(--light-card-background);
width: 100%;
margin-bottom: 2rem;
border-radius: 12px;
}
.container-primary-info .divider {
margin: 0 0 0 7rem;
width: unset;
}
.section-primary-info {
display: flex;
flex-direction: row;
align-items: center;
gap: 1.5rem;
padding: .8rem 1.2rem .4rem;
}
.personal-info {
display: flex;
flex-direction: column;
align-items: flex-start;
line-height: normal;
}
.info-nome {
color: var(--mud-palette-text-primary);
font-weight: 800;
font-size: x-large;
}
.info-section {
color: var(--mud-palette-gray-default);
font-size: medium;
font-weight: 600;
}
.section-info {
display: flex;
justify-content: space-between;
flex-direction: row;
padding: .4rem 1.2rem .8rem;
}
.section-personal-info {
display: flex;
flex-direction: column;
}
.section-personal-info > div {
display: flex;
flex-direction: column;
line-height: normal;
margin: .25rem 0;
}
.info-title {
color: var(--mud-palette-gray-darker);
font-weight: 800;
}
.info-text {
color: var(--mud-palette-text-secondary);
font-weight: 700;
font-size: small;
}
.content ::deep .user-button { border: 1px solid var(--card-border-color) !important; }
.user-button > i { font-size: large; }
.user-button > span {
font-size: medium;
font-weight: 600;
}
.status { font-weight: 700; }
.status.online { color: var(--mud-palette-success); }
.status.offline { color: var(--mud-palette-error); }

View File

@@ -0,0 +1,22 @@
@using SteUp.Shared.Core.Interface.System
@inject IGenericSystemService GenericSystemService
<div class="app-version">
<span>@Version</span>
</div>
@code
{
private string Version { get; set; } = "";
protected override void OnInitialized()
{
#if DEBUG
Version = $"v{GenericSystemService.GetCurrentAppVersion()} [DEBUG]";
#else
Version = $"v{GenericSystemService.GetCurrentAppVersion()}";
#endif
StateHasChanged();
}
}

View File

@@ -0,0 +1,11 @@
.app-version{
width: 100%;
display: flex;
justify-content: center;
margin: 8px 0;
}
.app-version span{
font-size: smaller;
color: var(--mud-palette-gray-darker);
}

View File

@@ -6,8 +6,12 @@ public enum KeyGroupEnum
Cliente = 3, Cliente = 3,
Agenti = 5, Agenti = 5,
AmministratoreAziendale = 9, AmministratoreAziendale = 9,
PuntoVendita = 10,
Rilevatore = 21,
Tecnico = 22, Tecnico = 22,
ResponsabileDiReparto = 23, ResponsabileDiReparto = 23,
ResponsabileAcquisti = 24,
ResponsabileEdp = 25,
ResponsabileAmministrativo = 29, ResponsabileAmministrativo = 29,
Programmatore = 30 Programmatore = 30
} }

View File

@@ -0,0 +1,26 @@
using SteUp.Shared.Core.Authorization.Enum;
namespace SteUp.Shared.Core.Helpers;
public static class KeyGroupHelper
{
public static string ConvertToHumanReadable(this KeyGroupEnum keyGroup)
{
return keyGroup switch
{
KeyGroupEnum.Agenti => "Agenti",
KeyGroupEnum.Tecnico => "Tecnico",
KeyGroupEnum.UtenteAziendale => "Utente Aziendale",
KeyGroupEnum.AmministratoreAziendale => "Amministratore Aziendale",
KeyGroupEnum.PuntoVendita => "Punto Vendita/Deposito",
KeyGroupEnum.ResponsabileDiReparto => "Responsabile Di Reparto",
KeyGroupEnum.Programmatore => "Programmatore",
KeyGroupEnum.Cliente => "Cliente",
KeyGroupEnum.ResponsabileAmministrativo => "Responsabile Amministrativo",
KeyGroupEnum.Rilevatore => "Rilevatore",
KeyGroupEnum.ResponsabileAcquisti => "Responsabile Acquisti",
KeyGroupEnum.ResponsabileEdp => "Responsabile EDP",
_ => "Tipologia utente non riconosciuta"
};
}
}

View File

@@ -0,0 +1,18 @@
using System.Collections;
namespace SteUp.Shared.Core.Helpers;
public static class ObjectExtensions
{
public static bool IsNullOrEmpty(this IEnumerable? obj) =>
obj == null || !obj.GetEnumerator().MoveNext();
public static bool IsNullOrEmpty(this string? obj) =>
string.IsNullOrEmpty(obj);
public static bool EqualsIgnoreCase(this string obj, string other) =>
string.Equals(obj, other, StringComparison.InvariantCultureIgnoreCase);
public static bool ContainsIgnoreCase(this string obj, string other) =>
obj.Contains(other, StringComparison.InvariantCultureIgnoreCase);
}

View File

@@ -0,0 +1,22 @@
namespace SteUp.Shared.Core.Utility;
public static class UtilityString
{
public static string ExtractInitials(string? fullname)
{
if (fullname == null) return "";
return string.Concat(fullname
.Split(' ', StringSplitOptions.RemoveEmptyEntries)
.Take(3)
.Select(word => char.ToUpper(word[0])));
}
public static string FirstCharToUpper(this string input) =>
input switch
{
null => throw new ArgumentNullException(nameof(input)),
"" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
_ => input[0].ToString().ToUpper() + input[1..]
};
}

View File

@@ -0,0 +1,170 @@
.title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1rem;
}
.customDialog-form.disable-safe-area .mud-dialog-content { margin-top: unset !important; }
.customDialog-form.disable-safe-area .content { height: 100% !important; }
.customDialog-form .content {
height: calc(100vh - (.6rem + 40px));
overflow: auto;
-ms-overflow-style: none;
scrollbar-width: none;
}
@supports (-webkit-touch-callout: none) {
.customDialog-form .content { height: calc(100vh - (.6rem + 40px) - env(safe-area-inset-top)) !important; }
.customDialog-form.disable-safe-area .content { height: 100% !important; }
.customDialog-form.disable-safe-area .mud-dialog-content { margin-top: unset !important; }
}
.customDialog-form .header { padding: 0 !important; }
.customDialog-form .content::-webkit-scrollbar { display: none; }
.input-card {
width: 100%;
background: var(--mud-palette-background-gray);
border-radius: 9px;
padding: .5rem 1rem;
margin-bottom: 1.5rem;
}
.input-card.clearButton {
display: flex;
align-items: center;
justify-content: space-between;
padding: .4rem 1rem !important;
}
.input-card.clearButton.custom-border-bottom { border-bottom: .1rem solid var(--card-border-color); }
.input-card > .divider { margin: 0 !important; }
.form-container {
display: flex;
justify-content: space-between;
align-items: center;
min-height: 35px;
}
.form-container > span {
font-weight: 700;
width: 50%;
margin-right: .3rem;
}
.form-container > .warning-text {
font-weight: 700;
color: var(--mud-palette-gray-darker);
width: unset;
margin: 0;
}
.form-container > .disable-full-width {
width: unset !important;
white-space: nowrap;
}
.dateTime-picker {
display: flex;
gap: .3rem;
flex-direction: row;
align-items: center;
}
/*Custom mudBlazor*/
.form-container .mud-input.mud-input-underline:before { border-bottom: none !important; }
.form-container .mud-input.mud-input-underline:after { border-bottom: none !important; }
.form-container.text-align-end .mud-input-slot { text-align: end; }
.input-card .mud-input.mud-input-underline:before { border-bottom: none !important; }
.input-card .mud-input.mud-input-underline:after { border-bottom: none !important; }
.form-container .customIcon-select .mud-icon-root.mud-svg-icon {
rotate: 90deg !important;
font-size: 1.1rem;
}
.form-container .customIcon-select .mud-input-slot { text-align: end; }
.input-card .mud-input {
width: 100%;
font-weight: 500;
}
.container-button {
width: 100%;
background: var(--light-card-background);
padding: .5rem 0;
border-radius: 12px;
margin-bottom: 2rem;
}
.container-button .divider {
margin: .5rem 0 .5rem 3rem;
width: unset;
}
.container-button .button-settings { border: none !important; }
.container-button .button-settings .mud-icon-root {
border-radius: 6px;
padding: 2px;
min-width: 25px;
min-height: 25px;
}
.container-button > .mud-button-root {
padding-top: .15rem;
padding-bottom: .15rem;
}
.container-button .button-settings.gray-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-gray-darker) h s 88%);
background: hsl(from var(--mud-palette-gray-darker) h s 88%);
color: var(--mud-palette-dark);
}
.container-button .button-settings.blue-icon .mud-icon-root {
border: 1px solid var(--mud-palette-primary);
background: hsl(from var(--mud-palette-primary-lighten) h s 95%);
color: var(--mud-palette-primary-darken);
}
.container-button .button-settings.green-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-success-lighten) h s 95%);
background: hsl(from var(--mud-palette-success-lighten) h s 95%);
color: var(--mud-palette-success-darken);
}
.container-button .button-settings.red-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-error-lighten) h s 95%);
background: hsl(from var(--mud-palette-error-lighten) h s 95%);
color: var(--mud-palette-error-darken);
}
.container-button .button-settings .mud-button-label {
justify-content: flex-start;
text-transform: capitalize;
font-size: 1rem;
}
.container-button .button-settings.exit { padding: 0; }
.container-button .button-settings.exit .mud-button-label {
justify-content: center;
font-size: 1.1rem;
line-height: normal;
}

View File

@@ -0,0 +1,47 @@
// Funzione goBack
window.goBack = function () {
console.log("goBack");
history.back();
};
// Funzione per aggiungere tabindex ai bottoni
function addTabindexToButtons() {
document.querySelectorAll('button.custom-plus-button').forEach(btn => {
if (!btn.hasAttribute('tabindex')) {
btn.setAttribute('tabindex', '0');
}
});
}
// Esegui la funzione tabindex inizialmente
addTabindexToButtons();
// Observer combinato per tutte le funzionalità
const observer = new MutationObserver((mutations) => {
// Aggiungi tabindex ai nuovi bottoni
addTabindexToButtons();
});
// Osserva sia i cambiamenti nel DOM che gli attributi
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class']
});
// Sync iniziale per la navbar (nel caso la pagina parte già con .show)
document.addEventListener("DOMContentLoaded", () => {
const bottomSheet = document.querySelector(".bottom-sheet-container");
const navbar = document.querySelector(".animated-navbar");
if (bottomSheet && navbar) {
if (bottomSheet.classList.contains("show")) {
navbar.classList.remove("show-nav");
navbar.classList.add("hide-nav");
} else {
navbar.classList.remove("hide-nav");
navbar.classList.add("show-nav");
}
}
});