Pagina profilo e modiche al theme
This commit is contained in:
@@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
|
||||
using MudBlazor.Services;
|
||||
using Template.Maui.Services;
|
||||
using Template.Shared;
|
||||
using Template.Shared.Core.Interface;
|
||||
using Template.Shared.Core.Services;
|
||||
using Template.Shared.Interfaces;
|
||||
|
||||
@@ -34,6 +35,8 @@ namespace Template.Maui
|
||||
builder.Services.AddScoped<AuthenticationStateProvider>(provider =>
|
||||
provider.GetRequiredService<AppAuthenticationStateProvider>());
|
||||
|
||||
builder.Services.AddScoped<INetworkService, NetworkService>();
|
||||
|
||||
#if DEBUG
|
||||
builder.Services.AddBlazorWebViewDeveloperTools();
|
||||
builder.Logging.AddDebug();
|
||||
|
||||
12
Template.Maui/Services/NetworkService.cs
Normal file
12
Template.Maui/Services/NetworkService.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Template.Shared.Core.Interface;
|
||||
|
||||
namespace Template.Maui.Services;
|
||||
|
||||
public class NetworkService : INetworkService
|
||||
{
|
||||
public bool IsNetworkAvailable()
|
||||
{
|
||||
return Connectivity.Current.NetworkAccess == NetworkAccess.Internet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
<div class="header">
|
||||
<div class="header-content">
|
||||
<h3 class="page-title">@Title</h3>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.FilterAlt" Color="Color.Dark" />
|
||||
@if (ShowFilter)
|
||||
{
|
||||
<MudIconButton Icon="@Icons.Material.Filled.FilterAlt" Color="Color.Dark" />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code{
|
||||
[Parameter] public string? Title { get; set; }
|
||||
[Parameter] public bool ShowFilter { get; set; }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<MudThemeProvider />
|
||||
<MudThemeProvider Theme="_currentTheme" />
|
||||
<MudPopoverProvider />
|
||||
<MudDialogProvider />
|
||||
<MudSnackbarProvider />
|
||||
@@ -15,3 +15,17 @@
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private readonly MudTheme _currentTheme = new()
|
||||
{
|
||||
PaletteLight = new PaletteLight()
|
||||
{
|
||||
Primary = "#ABA9BF",
|
||||
Secondary = "#BEB7DF",
|
||||
Tertiary = "#D4F2D2",
|
||||
Background = "#f6f6f8"
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
.navbar {
|
||||
background: var(--mud-palette-background-gray);
|
||||
background: var(--mud-palette-surface);
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
@@ -12,7 +12,7 @@
|
||||
.nav-item ::deep a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1.4;
|
||||
line-height: 1.2;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active > div { color: var(--mud-palette-primary); }
|
||||
.nav-item ::deep a.active > div { color: var(--mud-palette-secondary-darken); }
|
||||
|
||||
.nav-item ::deep a.active > div > i {
|
||||
/*background-color: color-mix(in srgb, var(--mud-palette-primary) 20%, transparent);*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@attribute [Authorize]
|
||||
@using Template.Shared.Components.Layout
|
||||
|
||||
<HeaderLayout Title="Agenda" />
|
||||
<HeaderLayout Title="Agenda" ShowFilter="true" />
|
||||
|
||||
<div class="content">
|
||||
<MudButtonGroup Size="Size.Small" Color="Color.Surface" OverrideStyles="true" Variant="Variant.Filled">
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
@page "/"
|
||||
@using Template.Shared.Core.Interface
|
||||
@using Template.Shared.Interfaces
|
||||
@attribute [Authorize]
|
||||
@inject IFormFactor FormFactor
|
||||
@inject INetworkService NetworkService
|
||||
|
||||
@code
|
||||
{
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
var lastSyncDate = DateOnly.FromDateTime(LocalStorage.Get<DateTime>("last-sync"));
|
||||
|
||||
if (!FormFactor.IsWeb() && NetworkService.IsNetworkAvailable() && lastSyncDate < DateOnly.FromDateTime(DateTime.Now))
|
||||
{
|
||||
//NavigationManager.NavigateTo("/sync");
|
||||
NavigationManager.NavigateTo("/Calendar");
|
||||
return base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
NavigationManager.NavigateTo("/Calendar");
|
||||
return base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
else
|
||||
{
|
||||
<div class="center-box container d-flex justify-content-center align-items-center min-vh-100">
|
||||
<div class="row border rounded-4 bg-white shadow box-area">
|
||||
<div class="row rounded-4 bg-white">
|
||||
|
||||
<div class="appName rounded-4 d-flex justify-content-center align-items-center flex-column">
|
||||
<span>Nome App</span>
|
||||
@@ -23,7 +23,7 @@ else
|
||||
<MudTextField @bind-Value="UserData.Username" Label="Username" Variant="Variant.Text"/>
|
||||
</div>
|
||||
<div class="input-group mb-2">
|
||||
<MudTextField @bind-Value="UserData.Password" Label="Password" Variant="Variant.Text"/>
|
||||
<MudTextField InputType="@_passwordInput" @bind-Value="UserData.Password" Label="Password" Variant="Variant.Text" Adornment="Adornment.End" AdornmentIcon="@_passwordInputIcon" OnAdornmentClick="ShowPassword" AdornmentAriaLabel="Show Password" />
|
||||
</div>
|
||||
<div class="input-group mb-4">
|
||||
<MudTextField @bind-Value="UserData.CodHash" Label="Profilo azienda" Variant="Variant.Text"/>
|
||||
@@ -55,6 +55,26 @@ else
|
||||
private string ErrorMessage { get; set; } = "";
|
||||
private bool _attemptFailed;
|
||||
|
||||
private bool _isShow;
|
||||
private InputType _passwordInput = InputType.Password;
|
||||
private string _passwordInputIcon = Icons.Material.Rounded.VisibilityOff;
|
||||
|
||||
private void ShowPassword()
|
||||
{
|
||||
@if (_isShow)
|
||||
{
|
||||
_isShow = false;
|
||||
_passwordInputIcon = Icons.Material.Rounded.VisibilityOff;
|
||||
_passwordInput = InputType.Password;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isShow = true;
|
||||
_passwordInputIcon = Icons.Material.Rounded.Visibility;
|
||||
_passwordInput = InputType.Text;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
UserData.CodHash = LocalStorage.GetString("codHash");
|
||||
|
||||
@@ -35,9 +35,8 @@
|
||||
|
||||
.button-login {
|
||||
text-align: center;
|
||||
border: 2px solid var(--mud-palette-primary);
|
||||
background-color: var(--mud-palette-primary);
|
||||
border-radius: 25px;
|
||||
border-radius: 6px;
|
||||
padding: .3rem 2rem;
|
||||
width: 100%;
|
||||
font-weight: 700;
|
||||
|
||||
@@ -1,9 +1,113 @@
|
||||
@page "/PersonalInfo"
|
||||
@attribute [Authorize]
|
||||
@using Template.Shared.Components.Layout
|
||||
@using Template.Shared.Core.Authorization.Enum
|
||||
@using Template.Shared.Core.Interface
|
||||
@using Template.Shared.Core.Services
|
||||
@using Template.Shared.Core.Utility
|
||||
@using Template.Shared.Interfaces
|
||||
@inject AppAuthenticationStateProvider AuthenticationStateProvider
|
||||
@inject INetworkService NetworkService
|
||||
@inject IFormFactor FormFactor
|
||||
|
||||
<HeaderLayout Title="Profilo" />
|
||||
|
||||
<div class="content">
|
||||
<div class="section-primary-info">
|
||||
<MudAvatar Style="height:85px; width:85px; font-size:2rem;">
|
||||
<MudImage Src="@($"https://ui-avatars.com/api/?name={UserSession.User.Username}&size=80&background={UtilityColor.CalcHexColor(UserSession.User.Username)}&bold=true")"></MudImage>
|
||||
</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="section-info">
|
||||
<div class="section-personal-info">
|
||||
<div>
|
||||
<span class="info-title">Telefono</span>
|
||||
<span class="info-text">000 0000000</span> @*Todo: to implement*@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="info-title">Status</span>
|
||||
@if (NetworkService.IsNetworkAvailable())
|
||||
{
|
||||
<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 class="section-personal-info">
|
||||
<div>
|
||||
<span class="info-title">E-mail</span>
|
||||
<span class="info-text">
|
||||
@if (string.IsNullOrEmpty(UserSession.User.Email))
|
||||
{
|
||||
@("Nessuna mail configurata")
|
||||
}
|
||||
else
|
||||
{
|
||||
@UserSession.User.Email
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="info-title">Ultima sincronizzazione</span>
|
||||
<span class="info-text">@LastSync.ToString("g")</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="user-button">
|
||||
<span>Impostazioni account</span>
|
||||
</div>
|
||||
|
||||
<div class="user-button logout" @onclick="Logout">
|
||||
<span>Esci</span>
|
||||
<i class="ri-logout-box-line"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool Unavailable { get; set; }
|
||||
private DateTime LastSync { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadData();
|
||||
}
|
||||
|
||||
private void Logout()
|
||||
{
|
||||
AuthenticationStateProvider.SignOut();
|
||||
}
|
||||
|
||||
private async Task LoadData()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Unavailable = FormFactor.IsWeb() || !NetworkService.IsNetworkAvailable();
|
||||
LastSync = LocalStorage.Get<DateTime>("last-sync");
|
||||
});
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
.section-primary-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.personal-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
line-height: normal;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.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 {
|
||||
width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: row;
|
||||
padding: .8rem 1.2rem;
|
||||
background: var(--mud-palette-surface);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.user-button {
|
||||
border: 2px solid var(--mud-palette-overlay-dark);
|
||||
margin-top: 1rem;
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: .45rem 2rem;
|
||||
width: 100%;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.user-button.logout {
|
||||
border: 2px solid var(--mud-palette-error);
|
||||
color: var(--mud-palette-error);
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="activity-card @Type shadow box-area">
|
||||
<div class="activity-card @Type">
|
||||
<div class="activity-left-section">
|
||||
<div class="activity-hours-section">
|
||||
<span class="activity-hours">14:00</span>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
padding: .5rem .7rem;
|
||||
border-radius: 12px;
|
||||
line-height: normal;
|
||||
background: var(--mud-palette-surface);
|
||||
}
|
||||
|
||||
.activity-card.memo { border-left: 5px solid var(--mud-palette-info-darken); }
|
||||
|
||||
8
Template.Shared/Core/Authorization/Enum/KeyGroupEnum.cs
Normal file
8
Template.Shared/Core/Authorization/Enum/KeyGroupEnum.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Template.Shared.Core.Authorization.Enum;
|
||||
|
||||
public enum KeyGroupEnum
|
||||
{
|
||||
UtenteAziendale = 2,
|
||||
Agenti = 5,
|
||||
Tecnico = 22
|
||||
}
|
||||
17
Template.Shared/Core/Helpers/KeyGroupHelper.cs
Normal file
17
Template.Shared/Core/Helpers/KeyGroupHelper.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Template.Shared.Core.Authorization.Enum;
|
||||
|
||||
namespace Template.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",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(keyGroup), keyGroup, null)
|
||||
};
|
||||
}
|
||||
}
|
||||
6
Template.Shared/Core/Interface/INetworkService.cs
Normal file
6
Template.Shared/Core/Interface/INetworkService.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Template.Shared.Core.Interface;
|
||||
|
||||
public interface INetworkService
|
||||
{
|
||||
public bool IsNetworkAvailable();
|
||||
}
|
||||
118
Template.Shared/Core/Utility/UtilityColor.cs
Normal file
118
Template.Shared/Core/Utility/UtilityColor.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
namespace Template.Shared.Core.Utility;
|
||||
|
||||
public static class UtilityColor
|
||||
{
|
||||
public static string CalcHexColor(string input)
|
||||
{
|
||||
try
|
||||
{
|
||||
var hue = (int)(Math.Abs(input.GetHashCode()) * 137.508 % 360);
|
||||
|
||||
var data = new HSL(hue, 0.90f, 0.85f);
|
||||
var myColor = HSLToRGB(data);
|
||||
|
||||
return myColor.R.ToString("X2") + myColor.G.ToString("X2") + myColor.B.ToString("X2");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
return "dddddd";
|
||||
}
|
||||
}
|
||||
|
||||
private struct RGB(byte r, byte g, byte b)
|
||||
{
|
||||
public byte R
|
||||
{
|
||||
get => r;
|
||||
set => r = value;
|
||||
}
|
||||
|
||||
public byte G
|
||||
{
|
||||
get => g;
|
||||
set => g = value;
|
||||
}
|
||||
|
||||
public byte B
|
||||
{
|
||||
get => b;
|
||||
set => b = value;
|
||||
}
|
||||
|
||||
public bool Equals(RGB rgb)
|
||||
{
|
||||
return (this.R == rgb.R) && (this.G == rgb.G) && (this.B == rgb.B);
|
||||
}
|
||||
}
|
||||
|
||||
private struct HSL(int h, float s, float l)
|
||||
{
|
||||
public int H
|
||||
{
|
||||
get => h;
|
||||
set => h = value;
|
||||
}
|
||||
|
||||
public float S
|
||||
{
|
||||
get => s;
|
||||
set => s = value;
|
||||
}
|
||||
|
||||
public float L
|
||||
{
|
||||
get => l;
|
||||
set => l = value;
|
||||
}
|
||||
|
||||
public bool Equals(HSL hsl)
|
||||
{
|
||||
return H == hsl.H && (this.S == hsl.S) && (this.L == hsl.L);
|
||||
}
|
||||
}
|
||||
|
||||
private static RGB HSLToRGB(HSL hsl)
|
||||
{
|
||||
byte r;
|
||||
byte g;
|
||||
byte b;
|
||||
|
||||
var hue = (float)hsl.H / 360;
|
||||
if (hsl.S == 0)
|
||||
{
|
||||
r = g = b = (byte)(hsl.L * 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
var v2 = hsl.L < 0.5 ? hsl.L * (1 + hsl.S) : hsl.L + hsl.S - hsl.L * hsl.S;
|
||||
var v1 = 2 * hsl.L - v2;
|
||||
|
||||
r = (byte)(255 * HueToRGB(v1, v2, hue + 1.0f / 3));
|
||||
g = (byte)(255 * HueToRGB(v1, v2, hue));
|
||||
b = (byte)(255 * HueToRGB(v1, v2, hue - 1.0f / 3));
|
||||
}
|
||||
|
||||
return new RGB(r, g, b);
|
||||
}
|
||||
|
||||
private static float HueToRGB(float v1, float v2, float vH)
|
||||
{
|
||||
if (vH < 0)
|
||||
vH += 1;
|
||||
|
||||
if (vH > 1)
|
||||
vH -= 1;
|
||||
|
||||
if (6 * vH < 1)
|
||||
return v1 + (v2 - v1) * 6 * vH;
|
||||
|
||||
if (2 * vH < 1)
|
||||
return v2;
|
||||
|
||||
if (3 * vH < 2)
|
||||
return v1 + (v2 - v1) * (2.0f / 3 - vH) * 6;
|
||||
|
||||
return v1;
|
||||
}
|
||||
}
|
||||
11
Template.Shared/Core/Utility/UtilityString.cs
Normal file
11
Template.Shared/Core/Utility/UtilityString.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Template.Shared.Core.Utility;
|
||||
|
||||
public static class UtilityString
|
||||
{
|
||||
public static string ExtractInitials(string fullname)
|
||||
{
|
||||
return string.Concat(fullname
|
||||
.Split(' ', StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(word => char.ToUpper(word[0])));
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,10 @@ public interface IFormFactor
|
||||
{
|
||||
public string GetFormFactor();
|
||||
public string GetPlatform();
|
||||
|
||||
public bool IsWeb()
|
||||
{
|
||||
var formFactor = GetFormFactor();
|
||||
return formFactor == "Web";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using MudBlazor.Services;
|
||||
using Template.Shared.Components;
|
||||
using Template.Shared.Core.Interface;
|
||||
using Template.Shared.Core.Services;
|
||||
using Template.Shared.Interfaces;
|
||||
using Template.Web.Services;
|
||||
@@ -14,6 +15,7 @@ builder.Services.AddMudServices();
|
||||
builder.Services.AddAuthorizationCore();
|
||||
|
||||
builder.Services.AddScoped<IFormFactor, FormFactor>();
|
||||
builder.Services.AddScoped<INetworkService, NetworkService>();
|
||||
|
||||
builder.Services.AddScoped<AppAuthenticationStateProvider>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider>(provider => provider.GetRequiredService<AppAuthenticationStateProvider>());
|
||||
|
||||
12
Template.Web/Services/NetworkService.cs
Normal file
12
Template.Web/Services/NetworkService.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Template.Shared.Core.Interface;
|
||||
|
||||
namespace Template.Web.Services;
|
||||
|
||||
public class NetworkService : INetworkService
|
||||
{
|
||||
public bool IsNetworkAvailable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user