Create prime pagine

This commit is contained in:
2025-05-08 16:38:31 +02:00
parent 77bcca44eb
commit ea52494dfb
36 changed files with 4681 additions and 369 deletions

View File

@@ -43,6 +43,7 @@
<!-- Add sortable.js reference if SortableList component is used in your application. --> <!-- Add sortable.js reference if SortableList component is used in your application. -->
<!--<script src="_content/Template.Shared/js/bootstrap/Sortable.min.js"></script>--> <!--<script src="_content/Template.Shared/js/bootstrap/Sortable.min.js"></script>-->
<script src="_content/MudBlazor/MudBlazor.min.js"></script> <script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="_content/Template.Shared/js/main.js"></script>
</body> </body>

View File

@@ -0,0 +1,10 @@
<div class="header">
<div class="header-content">
<h3 class="page-title">@Title</h3>
<MudIconButton Icon="@Icons.Material.Filled.FilterAlt" Color="Color.Dark" />
</div>
</div>
@code{
[Parameter] public string? Title { get; set; }
}

View File

@@ -0,0 +1,7 @@
.header-content {
display: flex;
justify-content: space-between;
color: var(--lighter-color);
align-items: center;
padding-top: .5rem;
}

View File

@@ -6,14 +6,10 @@
<MudSnackbarProvider /> <MudSnackbarProvider />
<div class="page"> <div class="page">
@*<div class="sidebar"> <NavMenu />
<NavMenu />
</div>*@
<NavMenu/>
<main> <main>
<article class="content px-4"> <article class="container">
@Body @Body
</article> </article>
</main> </main>

View File

@@ -21,29 +21,29 @@ main {
align-items: center; align-items: center;
} }
.top-row ::deep a, .top-row ::deep .btn-link { .top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap; white-space: nowrap;
margin-left: 1.5rem; margin-left: 1.5rem;
text-decoration: none; text-decoration: none;
} }
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover { .top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline; text-decoration: underline;
} }
.top-row ::deep a:first-child { .top-row ::deep a:first-child {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
@media (max-width: 640.98px) { @media (max-width: 640.98px) {
.top-row { .top-row {
justify-content: space-between; justify-content: space-between;
} }
.top-row ::deep a, .top-row ::deep .btn-link { .top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0; margin-left: 0;
} }
} }
@media (min-width: 641px) { @media (min-width: 641px) {
@@ -64,14 +64,14 @@ main {
z-index: 1; z-index: 1;
} }
.top-row.auth ::deep a:first-child { .top-row.auth ::deep a:first-child {
flex: 1; flex: 1;
text-align: right; text-align: right;
width: 0; width: 0;
} }
.top-row, article { .top-row, article {
padding-left: 2rem !important; padding-left: 2rem !important;
padding-right: 1.5rem !important; padding-right: 1.5rem !important;
} }
} }

View File

@@ -1,40 +0,0 @@
<div class="container">
<nav>
<ul>
<li>
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span>Home</span>
<i class="ri-home-5-line"/>
</NavLink>
</li>
</ul>
<ul>
<li>
<a href="#" id="workout">
<span>Workout</span>
<i class="ri-empathize-line"/>
</a>
</li>
</ul>
<ul>
<li>
<a href="#" id="logbook">
<span>Logbook</span>
<i class="ri-health-book-line"></i>
</a>
</li>
</ul>
<ul>
<li>
<a href="#" id="settings">
<span>Impostazioni</span>
<i class="ri-settings-5-line"/>
</a>
</li>
</ul>
</nav>
</div>
@code {
}

View File

@@ -1,81 +0,0 @@
a {
text-decoration: none;
color: inherit;
}
ul {
list-style-type: none;
}
.container {
max-width: 100%;
margin: 0 auto;
padding: 0;
}
nav {
position: fixed;
bottom: 0;
width: 100%;
background-color: var(--ligther-color);
margin: 0;
display: flex;
border-radius: 40px 40px 0px 0px;
box-shadow: rgb(50 50 93 / 25%) 0 50px 100px 10px,
rgb(0 0 0 / 30%) 0 30px 60px -30px;
}
nav ul {
display: inline-flex;
align-items: center;
padding: 0;
flex: 0 0 25%;
justify-content: center;
}
nav :where(li a) {
position: relative;
}
nav ul li a {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column-reverse;
padding: 1em;
line-height: 1.4;
-webkit-transition: all .3s ease-out;
transition: all .3s ease-out;
}
nav ul li a:hover {
color: var(--primary-color);
}
nav ul li a i {
font-size: 1.5rem;
}
nav ul li a span {
font-size: 0.9rem;
}
/* animations */
nav li.active a::before, nav li.active a::after {
content: "";
position: absolute;
background-color: var(--primary-color);
z-index: -1;
}
nav li.active a::before {
top: 5%;
width: calc(100% - 0px);
height: 100%;
border-radius: 25px;
}
nav li.active a {
color: var(--ligther-color);
}

View File

@@ -1,38 +1,52 @@
<nav class="navbar navbar-expand justify-content-center"> @if (IsVisible)
<div class="container-fluid"> {
<ul class="navbar-nav nav-justified w-100 text-center"> <nav class="navbar navbar-expand justify-content-center">
<div class="container-fluid">
<ul class="navbar-nav nav-justified w-100 text-center">
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link " href="workout" Match="NavLinkMatch.All"> <NavLink class="nav-link" href="Users" Match="NavLinkMatch.All">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<i class="ri-empathize-line"/> <i class="ri-group-fill"></i>
@* <span>Workout</span> *@ <span>Contatti</span>
</div> </div>
</NavLink> </NavLink>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <NavLink class="nav-link" href="Calendar" Match="NavLinkMatch.All">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<i class="ri-home-5-line"/> <i class="ri-calendar-todo-fill"></i>
@* <span>Home</span> *@ <span>Agenda</span>
</div> </div>
</NavLink> </NavLink>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link" href="logbook" Match="NavLinkMatch.All"> <NavLink class="nav-link" href="PersonalInfo" Match="NavLinkMatch.All">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<i class="ri-health-book-line"></i> <i class="ri-user-fill"></i>
@* <span>Log Book</span> *@ <span>Profilo</span>
</div> </div>
</NavLink> </NavLink>
</li> </li>
@* <li class="nav-item"> *@ </ul>
@* <NavLink class="nav-link d-flex flex-column" href="settings" Match="NavLinkMatch.All"> *@ </div>
@* <i class="ri-settings-5-line"/> *@ </nav>
@* <span>Impostazioni</span> *@ }
@* </NavLink> *@
@* </li> *@
</ul>
</div>
</nav> @code
{
private bool IsVisible { get; set; } = true;
protected override Task OnInitializedAsync()
{
NavigationManager.LocationChanged += (sender, args) =>
{
var location = args.Location.Remove(0, NavigationManager.BaseUri.Length);
IsVisible = new List<string> { "Calendar", "Users", "PersonalInfo" }
.Contains(location);
StateHasChanged();
};
return Task.CompletedTask;
}
}

View File

@@ -1,19 +1,15 @@
.navbar { .navbar {
background-color: var(--ligther-color); background: var(--mud-palette-background-gray);
border-radius: 50px 50px 0 0;
border: #eceff2 solid 1px;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
} }
.nav-item { .navbar-expand { padding: 0 !important; }
font-size: 0.9rem;
padding-bottom: 0.5rem; .nav-item { font-size: 0.9rem; }
}
.nav-item ::deep a { .nav-item ::deep a {
color: var(--darker-color);
display: flex; display: flex;
align-items: center; align-items: center;
line-height: 1.4; line-height: 1.4;
@@ -21,30 +17,31 @@
} }
.nav-item ::deep a > div { .nav-item ::deep a > div {
width: 4.3rem; -webkit-transition: all .1s ease-out;
height: 4.3rem; transition: all .1s ease-out;
border-radius: 100px; min-width: 60px;
justify-content: center;
padding-bottom: 0.1rem;
-webkit-transition: all .3s ease-out;
transition: all .3s ease-out;
} }
.nav-item ::deep a.active > div { .nav-item ::deep a.active > div { color: var(--mud-palette-primary); }
background-color: var(--primary-color);
color: white; .nav-item ::deep a.active > div > i {
/*background-color: color-mix(in srgb, var(--mud-palette-primary) 20%, transparent);*/
border-radius: 10px;
} }
/*.nav-item a:hover :not(.active) {*/ .nav-item ::deep a.active > div > span { font-weight: 800; }
/* background-color: rgba(255, 255, 255, 0.1);*/
/* color: var(--primary-color);*/
/*}*/
.nav-item ::deep a:not(.active) > div { color: var(--mud-palette-drawer-icon); }
.nav-item ::deep a i { .nav-item ::deep a i { font-size: 1.5rem; }
font-size: 2rem;
}
.nav-item ::deep a span { .nav-item ::deep a span {
font-size: 0.9rem; font-size: 0.8rem;
font-weight: 500;
} }
@supports (-webkit-touch-callout: none) {
.nav-item { padding-bottom: env(safe-area-inset-bottom) !important; }
.nav-item ::deep > .nav-link { padding-bottom: 0 !important; }
}

View File

@@ -0,0 +1,55 @@
@page "/Calendar"
@using Template.Shared.Components.Layout
<HeaderLayout Title="Agenda" />
<div class="content">
<MudButtonGroup Size="Size.Small" Color="Color.Surface" OverrideStyles="true" Variant="Variant.Filled">
<MudButton>Giorno</MudButton>
<MudButton Disabled="true">Settimana</MudButton>
<MudButton Disabled="true">Mese</MudButton>
</MudButtonGroup>
<div class="activity-filter">
<div class="date-controller">
<MudIconButton Icon="@Icons.Material.Filled.ChevronLeft" @onclick="() => DateFilter = DateFilter.AddDays(-1)" Color="Color.Surface"/>
<MudButton Variant="Variant.Text" Color="Color.Surface" OnClick="OpenCalendar">
@($"{DateFilter:M}")
</MudButton>
<MudIconButton Icon="@Icons.Material.Filled.ChevronRight" @onclick="() => DateFilter = DateFilter.AddDays(1)" Color="Color.Surface" />
</div>
<MudOverlay @bind-Visible="_isVisible" DarkBackground="true" AutoClose="true">
<MudDatePicker PickerVariant="PickerVariant.Static" Date="DateFilter" />
</MudOverlay>
</div>
<div class="card-container">
<ActivityCard Type="memo" />
<ActivityCard Type="commessa"/>
<ActivityCard Type="interna"/>
</div>
<MudMenu PopoverClass="custom_popover" Class="custom-mudfab" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomRight">
<ActivatorContent>
<MudFab Color="Color.Primary" Size="Size.Small" StartIcon="@Icons.Material.Filled.Add" />
</ActivatorContent>
<ChildContent>
<MudMenuItem>Nuovo contatto</MudMenuItem>
<MudMenuItem>Nuova attivit<69></MudMenuItem>
</ChildContent>
</MudMenu>
</div>
@code {
private DateTime DateFilter { get; set; } = DateTime.Today;
private bool _isVisible;
public void OpenCalendar()
{
_isVisible = true;
StateHasChanged();
}
}

View File

@@ -0,0 +1,17 @@
.activity-filter {
margin-top: .5rem;
}
.card-container {
margin-top: .5rem;
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
gap: 1rem;
}
.date-controller {
display: flex;
align-items: center;
}

View File

@@ -1,16 +0,0 @@
@page "/counter"
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}

View File

@@ -1,23 +0,0 @@
@page "/device-form-factor"
@using Template.Shared.Interfaces
@inject IFormFactor FormFactor
<PageTitle>Form Factor</PageTitle>
<h1>Device Form Factor</h1>
<p>You are running on:</p>
<ul>
<li>Form Factor: @factor</li>
<li>Platform: @platform</li>
</ul>
<p>
<em>This component is defined in the Template.Shared library.</em>
</p>
@code {
private string factor => FormFactor.GetFormFactor();
private string platform => FormFactor.GetPlatform();
}

View File

@@ -1,5 +1,10 @@
@page "/" @page "/"
<h1>Hello, world!</h1> @code
{
Welcome to your new app. protected override Task OnInitializedAsync()
{
NavigationManager.NavigateTo("/Calendar");
return base.OnInitializedAsync();
}
}

View File

@@ -1,6 +0,0 @@
@page "/settings"
<h3>Impostazioni</h3>
@code {
}

View File

@@ -1,10 +0,0 @@
@page "/logbook"
@using Template.Shared.Components.SingleElements
<h3 class="page-title">Log book</h3>
<NoDataAvailable ImageSource="_content/Template.Shared/images/log-book.svg"
Text="Nessun log book memorizzato"/>
@code {
}

View File

@@ -0,0 +1,8 @@
@page "/PersonalInfo"
@using Template.Shared.Components.Layout
<HeaderLayout Title="Profilo" />
@code {
}

View File

@@ -0,0 +1,8 @@
@page "/Users"
@using Template.Shared.Components.Layout
<HeaderLayout Title="Contatti" />
@code {
}

View File

@@ -1,61 +0,0 @@
@page "/weather"
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
// Simulate asynchronous loading to demonstrate a loading indicator
await Task.Delay(500);
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).ToArray();
}
private class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}

View File

@@ -1,12 +0,0 @@
@page "/workout"
@using Template.Shared.Components.SingleElements
<h3 class="page-title">Workout</h3>
<NoDataAvailable ImageSource="_content/Template.Shared/images/man-doing-squats.svg"
Text="Nessun workout disponibile"/>
@code {
}

View File

@@ -0,0 +1,20 @@
<div class="activity-card @Type">
<div class="activity-hours-section">
<span class="activity-hours">14:00</span>
<MudChip T="string" Icon="@IconConstants.Chip.Time" Color="Color.Dark" Size="Size.Small">1h</MudChip>
</div>
<div class="activity-body-section">
<span class="activity-title">Format</span>
<span class="activity-subtitle">Preparazione preventivo</span>
</div>
<div class="activity-info-section">
<MudChip T="string" Icon="@IconConstants.Chip.Stato" Size="Size.Small" Color="Color.Success">Completata</MudChip>
<MudChip T="string" Icon="@IconConstants.Chip.User" Size="Size.Small">GMANCINI</MudChip>
</div>
</div>
@code {
[Parameter] public string Type { get; set; } = "";
}

View File

@@ -0,0 +1,47 @@
.activity-card {
background: var(--mud-palette-background-gray);
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: .5rem .7rem;
border-radius: 12px;
line-height: normal;
}
.activity-card.memo { border-left: 5px solid var(--mud-palette-info-darken); }
.activity-card.interna { border-left: 5px solid var(--mud-palette-success-darken); }
.activity-card.commessa { border-left: 5px solid var(--mud-palette-warning); }
.activity-hours-section {
width: min-content;
display: flex;
flex-direction: column;
align-items: center;
}
.activity-hours { font-weight: 700; }
.activity-hours-section ::deep .mud-chip { margin: 5px 0 0 !important; }
.activity-body-section {
width: fit-content;
margin: 0 .5rem;
display: flex;
flex-direction: column;
}
.activity-title {
font-weight: 800;
font-size: medium;
}
.activity-subtitle {
font-size: smaller;
color: var(--mud-palette-gray-darker)
}
.activity-info-section { width: min-content; }

View File

@@ -0,0 +1,11 @@
namespace Template.Shared.Core.Helpers;
class IconConstants
{
public class Chip
{
public const string Stato = "ri-list-check-3 fa-fw fa-chip";
public const string User = "ri-user-fill fa-fw fa-chip";
public const string Time = "ri-time-line fa-fw fa-chip";
}
}

View File

@@ -14,9 +14,11 @@
<PackageReference Include="IntegryApiClient.Core" Version="1.1.3" /> <PackageReference Include="IntegryApiClient.Core" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.4" /> <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.4" />
<PackageReference Include="MudBlazor" Version="8.6.0" /> <PackageReference Include="MudBlazor" Version="8.6.0" />
<PackageReference Include="MudBlazor.ThemeManager" Version="3.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="wwwroot\css\lineicons\" />
<Folder Include="wwwroot\js\bootstrap\" /> <Folder Include="wwwroot\js\bootstrap\" />
</ItemGroup> </ItemGroup>

View File

@@ -7,4 +7,9 @@
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using Template.Shared.Components @using Template.Shared.Components
@using MudBlazor @using MudBlazor
@using MudBlazor.ThemeManager
@using Template.Shared.Core.Helpers
@using Template.Shared.Components.SingleElements.Card
@using static InteractiveRenderSettings @using static InteractiveRenderSettings
@inject NavigationManager NavigationManager

View File

@@ -1,11 +1,15 @@
html, body { html, body {
font-family: 'Poppins', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: "Nunito", sans-serif;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 1.8; line-height: 1.8;
color: black; color: black;
} }
* { font-family: "Nunito", sans-serif !important; }
.mud-button-label { font-weight: 700 !important; }
a, .btn-link { a, .btn-link {
/*color: #006bb7;*/ /*color: #006bb7;*/
text-decoration: none; text-decoration: none;
@@ -18,29 +22,22 @@ a, .btn-link {
border-color: var(--darker-color); border-color: var(--darker-color);
} }
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; }
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
.content { .content {
padding-top: 1.1rem; padding-top: 1.1rem;
display: flex;
align-items: center;
flex-direction: column;
} }
h1:focus { h1:focus { outline: none; }
outline: none;
}
.valid.modified:not([type=checkbox]) { .valid.modified:not([type=checkbox]) { outline: 1px solid #26b050; }
outline: 1px solid #26b050;
}
.invalid { .invalid { outline: 1px solid #e50000; }
outline: 1px solid #e50000;
}
.validation-message { .validation-message { color: #e50000; }
color: #e50000;
}
#blazor-error-ui { #blazor-error-ui {
background: lightyellow; background: lightyellow;
@@ -67,18 +64,41 @@ h1:focus {
color: white; color: white;
} }
.blazor-error-boundary::after { .blazor-error-boundary::after { content: "An error has occurred." }
content: "An error has occurred."
}
.status-bar-safe-area { .status-bar-safe-area { display: none; }
display: none;
}
.page-title { .page-title {
/*text-align: center;*/
font-size: x-large; font-size: x-large;
color: var(--darker-color); font-weight: 800;
color: var(--mud-palette-text-primary);
}
.custom-mudfab {
position: fixed !important;
bottom: 4rem;
margin-bottom: 16px;
right: 16px;
}
.custom_popover {
border-radius: 5px !important;
background-color: var(--mud-palette-drawer-background) !important;
box-shadow: 4px 4px 20px 0px rgba(0, 0, 0, 0.26), 0px 0px 0px 1px rgb(255 255 255 / 25%) !important;
color: var(--mud-palette-text-primary) !important;
}
.custom_popover .mud-divider { border-color: var(--mud-palette-text-primary) !important; }
.custom_popover .mud-list-padding { padding: 3px 0px 3px 0px !important; }
.custom_popover .mud-list-item { padding: 5px 12px 5px 12px; }
.custom_popover .mud-menu-item-text { font-weight: 600; }
.custom_popover .mud-list-item-icon {
min-width: fit-content !important;
padding-right: 12px !important;
} }
@supports (-webkit-touch-callout: none) { @supports (-webkit-touch-callout: none) {
@@ -98,7 +118,5 @@ h1:focus {
height: 100vh; height: 100vh;
} }
.flex-column, .navbar-brand { .flex-column, .navbar-brand { padding-left: env(safe-area-inset-left); }
padding-left: env(safe-area-inset-left); }
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.8 MiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@


View File

@@ -36,6 +36,7 @@
<!-- Add sortable.js reference if SortableList component is used in your application. --> <!-- Add sortable.js reference if SortableList component is used in your application. -->
<!--<script src="_content/ConSegna.Shared/js/bootstrap/Sortable.min.js"></script>--> <!--<script src="_content/ConSegna.Shared/js/bootstrap/Sortable.min.js"></script>-->
<script src="_content/MudBlazor/MudBlazor.min.js"></script> <script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="_content/Template.Shared/js/main.js"></script>
</body> </body>
</html> </html>