Rename salesbook
This commit is contained in:
89
salesbook.Shared/Components/Layout/HeaderLayout.razor
Normal file
89
salesbook.Shared/Components/Layout/HeaderLayout.razor
Normal file
@@ -0,0 +1,89 @@
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<div class="@(Back ? "" : "container") header">
|
||||
<div class="header-content @(Back ? "with-back" : "no-back")">
|
||||
@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())
|
||||
{
|
||||
@if (ShowFilter)
|
||||
{
|
||||
<MudIconButton OnClick="OnFilterToggle" Icon="@Icons.Material.Outlined.FilterAlt"/>
|
||||
}
|
||||
|
||||
@* @if (ShowCalendarToggle)
|
||||
{
|
||||
<MudIconButton OnClick="OnCalendarToggle" Icon="@Icons.Material.Filled.CalendarMonth" Color="Color.Dark"/>
|
||||
} *@
|
||||
|
||||
@if (ShowProfile)
|
||||
{
|
||||
<MudIconButton Class="user" OnClick="OpenPersonalInfo" Icon="@Icons.Material.Filled.Person"/>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudButton OnClick="OnSave"
|
||||
Color="Color.Info"
|
||||
Style="text-transform: none"
|
||||
Variant="Variant.Text">
|
||||
@LabelSave
|
||||
</MudButton>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code{
|
||||
[Parameter] public string? Title { get; set; }
|
||||
[Parameter] public bool ShowFilter { get; set; }
|
||||
[Parameter] public bool ShowProfile { get; set; } = true;
|
||||
[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 ShowCalendarToggle { get; set; }
|
||||
[Parameter] public EventCallback OnCalendarToggle { 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");
|
||||
}
|
||||
|
||||
private void OpenPersonalInfo() =>
|
||||
NavigationManager.NavigateTo("/PersonalInfo");
|
||||
|
||||
}
|
||||
21
salesbook.Shared/Components/Layout/HeaderLayout.razor.css
Normal file
21
salesbook.Shared/Components/Layout/HeaderLayout.razor.css
Normal file
@@ -0,0 +1,21 @@
|
||||
.header-content {
|
||||
line-height: normal;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.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; }
|
||||
92
salesbook.Shared/Components/Layout/MainLayout.razor
Normal file
92
salesbook.Shared/Components/Layout/MainLayout.razor
Normal file
@@ -0,0 +1,92 @@
|
||||
@using System.Globalization
|
||||
@using CommunityToolkit.Mvvm.Messaging
|
||||
@using salesbook.Shared.Core.Messages.Back
|
||||
@inherits LayoutComponentBase
|
||||
@inject IJSRuntime JS
|
||||
@inject IMessenger Messenger
|
||||
@inject BackNavigationService BackService
|
||||
|
||||
<MudThemeProvider Theme="_currentTheme" @ref="@_mudThemeProvider" @bind-IsDarkMode="@IsDarkMode" />
|
||||
<MudPopoverProvider/>
|
||||
<MudDialogProvider/>
|
||||
<MudSnackbarProvider/>
|
||||
|
||||
<div class="page">
|
||||
<NavMenu/>
|
||||
|
||||
<main>
|
||||
<article>
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private MudThemeProvider? _mudThemeProvider;
|
||||
private bool IsDarkMode { get; set; }
|
||||
private string _mainContentClass = "";
|
||||
|
||||
private readonly MudTheme _currentTheme = new()
|
||||
{
|
||||
PaletteLight = new PaletteLight()
|
||||
{
|
||||
Primary = "#00a0de",
|
||||
Secondary = "#002339",
|
||||
Tertiary = "#dff2ff",
|
||||
TextPrimary = "#000"
|
||||
},
|
||||
PaletteDark = new PaletteDark
|
||||
{
|
||||
Primary = "#00a0de",
|
||||
Secondary = "#002339",
|
||||
Tertiary = "#dff2ff",
|
||||
Surface = "#000406",
|
||||
Background = "#000406",
|
||||
TextPrimary = "#fff",
|
||||
GrayDark = "#E0E0E0"
|
||||
}
|
||||
};
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
// if (firstRender)
|
||||
// {
|
||||
// var isDarkMode = LocalStorage.GetString("isDarkMode");
|
||||
|
||||
// if (isDarkMode == null && _mudThemeProvider != null)
|
||||
// {
|
||||
// IsDarkMode = await _mudThemeProvider.GetSystemPreference();
|
||||
// await _mudThemeProvider.WatchSystemPreference(OnSystemPreferenceChanged);
|
||||
// LocalStorage.SetString("isDarkMode", IsDarkMode.ToString());
|
||||
// StateHasChanged();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// IsDarkMode = bool.Parse(isDarkMode!);
|
||||
// }
|
||||
|
||||
// if (IsDarkMode)
|
||||
// {
|
||||
// _mainContentClass += "is-dark";
|
||||
// StateHasChanged();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private async Task OnSystemPreferenceChanged(bool newValue)
|
||||
{
|
||||
IsDarkMode = newValue;
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
BackService.OnHardwareBack += async () => { await JS.InvokeVoidAsync("goBack"); };
|
||||
|
||||
var culture = new CultureInfo("it-IT", false);
|
||||
|
||||
CultureInfo.CurrentCulture = culture;
|
||||
CultureInfo.CurrentUICulture = culture;
|
||||
}
|
||||
|
||||
}
|
||||
77
salesbook.Shared/Components/Layout/MainLayout.razor.css
Normal file
77
salesbook.Shared/Components/Layout/MainLayout.razor.css
Normal file
@@ -0,0 +1,77 @@
|
||||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row ::deep a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth ::deep a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
96
salesbook.Shared/Components/Layout/NavMenu.razor
Normal file
96
salesbook.Shared/Components/Layout/NavMenu.razor
Normal file
@@ -0,0 +1,96 @@
|
||||
@using CommunityToolkit.Mvvm.Messaging
|
||||
@using salesbook.Shared.Core.Dto
|
||||
@using salesbook.Shared.Core.Entity
|
||||
@using salesbook.Shared.Core.Messages.Activity.Copy
|
||||
@using salesbook.Shared.Core.Messages.Activity.New
|
||||
@inject IDialogService Dialog
|
||||
@inject IMessenger Messenger
|
||||
@inject CopyActivityService CopyActivityService
|
||||
|
||||
<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")">
|
||||
<div class="container-navbar">
|
||||
<ul class="navbar-nav flex-row nav-justified align-items-center w-100 text-center">
|
||||
<li class="nav-item">
|
||||
<NavLink class="nav-link" href="Users" Match="NavLinkMatch.All">
|
||||
<div class="d-flex flex-column">
|
||||
<i class="ri-group-line"></i>
|
||||
<span>Contatti</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>Agenda</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<NavLink class="nav-link" href="Notifications" Match="NavLinkMatch.All">
|
||||
<div class="d-flex flex-column">
|
||||
<i class="ri-notification-4-line"></i>
|
||||
<span>Notifiche</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@if (PlusVisible)
|
||||
{
|
||||
<MudMenu PopoverClass="custom_popover" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomRight">
|
||||
<ActivatorContent>
|
||||
<MudFab Class="custom-plus-button" Color="Color.Surface" Size="Size.Medium" IconSize="Size.Medium" IconColor="Color.Primary" StartIcon="@Icons.Material.Filled.Add" />
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<MudMenuItem Disabled="true">Nuovo contatto</MudMenuItem>
|
||||
<MudMenuItem OnClick="CreateActivity">Nuova attivit<69></MudMenuItem>
|
||||
</ChildContent>
|
||||
</MudMenu>
|
||||
}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private bool IsVisible { get; set; } = true;
|
||||
private bool PlusVisible { get; set; } = true;
|
||||
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
CopyActivityService.OnCopyActivity += async dto => await CreateActivity(dto);
|
||||
|
||||
NavigationManager.LocationChanged += (_, args) =>
|
||||
{
|
||||
var location = args.Location.Remove(0, NavigationManager.BaseUri.Length);
|
||||
|
||||
var newIsVisible = new List<string> { "Calendar", "Users", "Notifications" }
|
||||
.Contains(location);
|
||||
|
||||
var newPlusVisible = new List<string> { "Calendar", "Users" }
|
||||
.Contains(location);
|
||||
|
||||
if (IsVisible == newIsVisible && PlusVisible == newPlusVisible) return;
|
||||
|
||||
IsVisible = newIsVisible;
|
||||
PlusVisible = newPlusVisible;
|
||||
StateHasChanged();
|
||||
};
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task CreateActivity() => CreateActivity(null);
|
||||
|
||||
private async Task CreateActivity(ActivityDTO? activity)
|
||||
{
|
||||
var result = await ModalHelpers.OpenActivityForm(Dialog, activity, null);
|
||||
|
||||
if (result is { Canceled: false, Data: not null } && result.Data.GetType() == typeof(StbActivity))
|
||||
{
|
||||
Messenger.Send(new NewActivityMessage(((StbActivity)result.Data).ActivityId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
97
salesbook.Shared/Components/Layout/NavMenu.razor.css
Normal file
97
salesbook.Shared/Components/Layout/NavMenu.razor.css
Normal file
@@ -0,0 +1,97 @@
|
||||
.animated-navbar {
|
||||
background: transparent;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
z-index: 1001;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.animated-navbar.show-nav { transform: translateY(0); }
|
||||
|
||||
.animated-navbar.hide-nav { transform: translateY(100%); }
|
||||
|
||||
.animated-navbar.with-plus { margin-left: 30px; }
|
||||
|
||||
.navbar {
|
||||
padding-bottom: 1rem;
|
||||
padding-top: 0 !important;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: end;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.navbar.with-plus { transform: translateX(-30px); }
|
||||
|
||||
.navbar.without-plus {
|
||||
transform: translateX(0);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.container-navbar {
|
||||
background: var(--mud-palette-surface);
|
||||
border-radius: 50px;
|
||||
padding: 0 10px;
|
||||
box-shadow: var(--custom-box-shadow);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.nav-item { font-size: 0.9rem; }
|
||||
|
||||
.nav-item.plus-button {
|
||||
position: relative;
|
||||
bottom: 15px;
|
||||
}
|
||||
|
||||
.navbar ::deep .custom-plus-button .mud-icon-root {
|
||||
transition: .5s;
|
||||
transform: rotate(0);
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.navbar ::deep .custom-plus-button {
|
||||
background: var(--mud-palette-surface);
|
||||
box-shadow: var(--custom-box-shadow);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.navbar ::deep .custom-plus-button:focus .mud-icon-root { transform: rotate(225deg); }
|
||||
|
||||
.nav-item ::deep a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1.2;
|
||||
justify-content: center;
|
||||
padding-top: .25rem !important;
|
||||
padding-bottom: .25rem !important;
|
||||
}
|
||||
|
||||
.nav-item ::deep a > div {
|
||||
-webkit-transition: all .1s ease-out;
|
||||
transition: all .1s ease-out;
|
||||
min-width: 75px;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active > div { color: var(--mud-palette-primary); }
|
||||
|
||||
.nav-item ::deep a.active > div > i {
|
||||
/*background-color: color-mix(in srgb, var(--mud-palette-primary) 20%, transparent);*/
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active > div > span { font-weight: 800; }
|
||||
|
||||
.nav-item ::deep a:not(.active) > div {
|
||||
color: var(--mud-palette-text-primary);
|
||||
}
|
||||
|
||||
.nav-item ::deep a i { font-size: 1.65rem; }
|
||||
|
||||
.nav-item ::deep a span {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@supports (-webkit-touch-callout: none) { .navbar { padding-bottom: env(safe-area-inset-bottom); } }
|
||||
23
salesbook.Shared/Components/Layout/Overlay/SaveOverlay.razor
Normal file
23
salesbook.Shared/Components/Layout/Overlay/SaveOverlay.razor
Normal file
@@ -0,0 +1,23 @@
|
||||
@using salesbook.Shared.Components.Layout.Spinner
|
||||
<MudOverlay Visible="VisibleOverlay" LightBackground="true">
|
||||
@if (SuccessAnimation)
|
||||
{
|
||||
<div class="success-checkmark">
|
||||
<div class="check-icon">
|
||||
<span class="icon-line line-tip"></span>
|
||||
<span class="icon-line line-long"></span>
|
||||
<div class="icon-circle"></div>
|
||||
<div class="icon-fix"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<SpinnerLayout/>
|
||||
}
|
||||
</MudOverlay>
|
||||
|
||||
@code {
|
||||
[Parameter] public required bool SuccessAnimation { get; set; }
|
||||
[Parameter] public required bool VisibleOverlay { get; set; }
|
||||
}
|
||||
156
salesbook.Shared/Components/Layout/Overlay/SaveOverlay.razor.css
Normal file
156
salesbook.Shared/Components/Layout/Overlay/SaveOverlay.razor.css
Normal file
@@ -0,0 +1,156 @@
|
||||
.success-checkmark {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
box-sizing: content-box;
|
||||
border: 4px solid var(--mud-palette-success);
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon::before {
|
||||
top: 3px;
|
||||
left: -2px;
|
||||
width: 30px;
|
||||
transform-origin: 100% 50%;
|
||||
border-radius: 100px 0 0 100px;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon::after {
|
||||
top: 0;
|
||||
left: 30px;
|
||||
width: 60px;
|
||||
transform-origin: 0 50%;
|
||||
border-radius: 0 100px 100px 0;
|
||||
animation: rotate-circle 4.25s ease-in;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon::before,
|
||||
.success-checkmark .check-icon::after {
|
||||
content: '';
|
||||
height: 100px;
|
||||
position: absolute;
|
||||
transform: rotate(-45deg);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.icon-line {
|
||||
height: 5px;
|
||||
background-color: var(--mud-palette-success);
|
||||
display: block;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.icon-line.line-tip {
|
||||
top: 46px;
|
||||
left: 14px;
|
||||
width: 25px;
|
||||
transform: rotate(45deg);
|
||||
animation: icon-line-tip 0.75s;
|
||||
}
|
||||
|
||||
.icon-line.line-long {
|
||||
top: 38px;
|
||||
right: 8px;
|
||||
width: 47px;
|
||||
transform: rotate(-45deg);
|
||||
animation: icon-line-long 0.75s;
|
||||
}
|
||||
|
||||
|
||||
.icon-circle {
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
z-index: 10;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
box-sizing: content-box;
|
||||
border: 4px solid var(--mud-palette-success);
|
||||
}
|
||||
|
||||
.icon-fix {
|
||||
top: 8px;
|
||||
width: 5px;
|
||||
left: 26px;
|
||||
z-index: 1;
|
||||
height: 85px;
|
||||
position: absolute;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
@keyframes rotate-circle {
|
||||
0% { transform: rotate(-45deg); }
|
||||
|
||||
5% { transform: rotate(-45deg); }
|
||||
|
||||
12% { transform: rotate(-405deg); }
|
||||
|
||||
100% { transform: rotate(-405deg); }
|
||||
}
|
||||
|
||||
@keyframes icon-line-tip {
|
||||
0% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px;
|
||||
}
|
||||
|
||||
54% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
top: 19px;
|
||||
}
|
||||
|
||||
70% {
|
||||
width: 50px;
|
||||
left: -8px;
|
||||
top: 37px;
|
||||
}
|
||||
|
||||
84% {
|
||||
width: 17px;
|
||||
left: 21px;
|
||||
top: 48px;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 25px;
|
||||
left: 14px;
|
||||
top: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes icon-line-long {
|
||||
0% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px;
|
||||
}
|
||||
|
||||
65% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
top: 54px;
|
||||
}
|
||||
|
||||
84% {
|
||||
width: 55px;
|
||||
right: 0px;
|
||||
top: 35px;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 47px;
|
||||
right: 8px;
|
||||
top: 38px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="spinner-container @(FullScreen ? "" : "not-fullScreen")">
|
||||
<span class="loader"></span>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter] public bool FullScreen { get; set; } = true;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
.spinner-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: calc(100vh - 10.1rem);
|
||||
align-items: center;
|
||||
color: var(--mud-palette-primary);
|
||||
}
|
||||
|
||||
.not-fullScreen {
|
||||
height: auto !important;
|
||||
padding: 2rem 0 !important;
|
||||
}
|
||||
|
||||
.loader {
|
||||
width: 50px;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 50%;
|
||||
border: 8px solid #0000;
|
||||
border-right-color: var(--mud-palette-secondary);
|
||||
position: relative;
|
||||
animation: l24 1s infinite linear;
|
||||
}
|
||||
|
||||
.loader:before,
|
||||
.loader:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -8px;
|
||||
border-radius: 50%;
|
||||
border: inherit;
|
||||
animation: inherit;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
|
||||
.loader:after {
|
||||
animation-duration: 4s;
|
||||
}
|
||||
|
||||
@keyframes l24 {
|
||||
100% {
|
||||
transform: rotate(1turn)
|
||||
}
|
||||
}
|
||||
20
salesbook.Shared/Components/Layout/Spinner/SyncSpinner.razor
Normal file
20
salesbook.Shared/Components/Layout/Spinner/SyncSpinner.razor
Normal file
@@ -0,0 +1,20 @@
|
||||
@if (Elements is not null)
|
||||
{
|
||||
<div class="container-loader">
|
||||
<span>Download risorse in corso</span>
|
||||
<div>
|
||||
@foreach (var element in Elements)
|
||||
{
|
||||
<div class="progress-content">
|
||||
<span>@element.Key</span>
|
||||
<MudProgressLinear Indeterminate="@(!element.Value)" Value="100" Rounded="true" Color="@(element.Value ? Color.Tertiary : Color.Secondary)" Size="Size.Large" />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter] public Dictionary<string, bool>? Elements { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
.container-loader {
|
||||
display: flex;
|
||||
height: 95vh;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 0 1rem;
|
||||
align-items: center;
|
||||
gap: 5vh;
|
||||
}
|
||||
|
||||
.container-loader > div {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.container-loader > span {
|
||||
font-weight: 900;
|
||||
font-size: large;
|
||||
color: var(--mud-palette-primary);
|
||||
}
|
||||
|
||||
.progress-content > span {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.progress-content:nth-last-child(2) {
|
||||
margin: 10px 0;
|
||||
}
|
||||
Reference in New Issue
Block a user