+ @if (Expanded)
+ {
+
+ @foreach (var nomeGiorno in GiorniSettimana)
{
-
- @foreach (var nomeGiorno in GiorniSettimana)
+
+ }
+
+ @foreach (var unused in Enumerable.Range(0, StartOffset))
+ {
+
+ }
+
+ @if (_isInitialized && _monthDaysData.Length > 0)
+ {
+ @for (var d = 1; d <= DaysInMonth; d++)
{
-
-
@nomeGiorno
+ var day = new DateTime(CurrentMonth.Year, CurrentMonth.Month, d);
+ var dayData = _monthDaysData[d - 1];
+
+
SelezionaDataDalMese(day)">
+
@d
+ @if (dayData.HasEvents)
+ {
+
+ @foreach (var cat in dayData.EventCategories)
+ {
+
+ }
+
+ }
}
-
- @foreach (var unused in Enumerable.Range(0, StartOffset))
- {
-
- }
-
+ }
+ else
+ {
+ @* Fallback rendering per prima inizializzazione *@
@for (var d = 1; d <= DaysInMonth; d++)
{
var day = new DateTime(CurrentMonth.Year, CurrentMonth.Month, d);
var isSelected = IsSameDay(day, SelectedDate);
var isToday = IsSameDay(day, DateTime.Today);
- var events = ReturnFilteredActivity(day);
+ var events = GetEventsForDay(day);
SelezionaDataDalMese(day)">
@@ -52,29 +76,64 @@
}
}
+ }
- @foreach (var unused in Enumerable.Range(0, EndOffset))
+ @foreach (var unused in Enumerable.Range(0, EndOffset))
+ {
+
+ }
+ }
+ else
+ {
+
+ @if (_isInitialized && _weekDaysData.Length == 7 && _weekDaysData[0].Date != default)
+ {
+ @for (int i = 0; i < 7; i++)
{
-
+ var dayData = _weekDaysData[i];
+ var day = dayData.Date;
+
+
+
@dayData.DayName
+
SelezionaData(day)">
+
@day.Day
+ @if (dayData.HasEvents)
+ {
+
+ @foreach (var cat in dayData.EventCategories)
+ {
+
+ }
+
+ }
+
+
}
}
else
{
-
- @foreach (var day in DaysOfWeek)
+ var start = GetStartOfWeek(SelectedDate);
+ var culture = new System.Globalization.CultureInfo("it-IT");
+
+
+ for (var i = 0; i < 7; i++)
{
+ var day = start.AddDays(i);
var isSelected = IsSameDay(day, SelectedDate);
var isToday = IsSameDay(day, DateTime.Today);
+ var events = GetEventsForDay(day);
-
@day.ToString("ddd", new System.Globalization.CultureInfo("it-IT"))
+
@day.ToString("ddd", culture)
SelezionaData(day)">
+ @onclick="() => SelezionaData(day)"
+ aria-label="@day.ToString("dddd d MMMM", culture)">
@day.Day
- @if (ReturnFilteredActivity(day).Any())
+ @if (events.Any())
{
- @foreach (var cat in ReturnFilteredActivity(day).Select(x => x.Category).Distinct())
+ @foreach (var cat in events.Select(x => x.Category).Distinct())
{
}
@@ -84,22 +143,23 @@
}
}
-
+ }
+
@if (IsLoading)
{
-
+
}
else if (FilteredActivities is { Count: > 0 })
{
-
+
}
else
{
-
+
}
@@ -107,6 +167,19 @@
@code {
+ // Modelli per ottimizzazione rendering
+ private record DayData(DateTime Date, string CssClass, bool HasEvents, CategoryData[] EventCategories, string DayName = "");
+
+ private record CategoryData(string CssClass, string Title);
+
+ // Cache per rendering
+ private DayData[] _monthDaysData = Array.Empty
();
+ private DayData[] _weekDaysData = new DayData[7];
+ private string _headerTitle = string.Empty;
+ private Dictionary> _eventsCache = new();
+ private Dictionary _categoriesCache = new();
+ private bool _isInitialized = false;
+
// Stato UI
private bool Expanded { get; set; } = false;
private string SliderAnimation { get; set; } = string.Empty;
@@ -141,16 +214,6 @@
}
}
- // Supporto rendering settimana
- private IEnumerable DaysOfWeek
- {
- get
- {
- var start = GetStartOfWeek(SelectedDate);
- return Enumerable.Range(0, 7).Select(i => start.AddDays(i));
- }
- }
-
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
@@ -162,17 +225,141 @@
_internalMonth = new DateTime(SelectedDate.Year, SelectedDate.Month, 1);
await LoadMonthData();
- if (!Expanded)
- ApplyFilter();
-
+ PrepareRenderingData();
+ _isInitialized = true;
+ ApplyFilter();
StateHasChanged();
}
}
+ // Metodo per preparare i dati di rendering una sola volta
+ private void PrepareRenderingData()
+ {
+ PrepareHeaderTitle();
+ PrepareEventsCache();
+
+ if (Expanded)
+ {
+ PrepareMonthDaysData();
+ }
+ else
+ {
+ PrepareWeekDaysData();
+ }
+ }
+
+ private void PrepareHeaderTitle()
+ {
+ _headerTitle = CurrentMonth.ToString("MMMM yyyy", new System.Globalization.CultureInfo("it-IT")).FirstCharToUpper();
+ }
+
+ private void PrepareEventsCache()
+ {
+ _eventsCache.Clear();
+ _categoriesCache.Clear();
+
+ // Raggruppa le attività per data
+ var activitiesByDate = MonthActivities
+ .GroupBy(x => (x.EffectiveDate ?? x.EstimatedDate!).Value.Date)
+ .ToDictionary(g => g.Key, g => g.ToList());
+
+ foreach (var (date, activities) in activitiesByDate)
+ {
+ _eventsCache[date] = activities;
+
+ // Pre-calcola le categorie per ogni giorno
+ var categories = activities
+ .Select(x => x.Category)
+ .Distinct()
+ .Select(cat => new CategoryData(cat.ConvertToHumanReadable(), cat.ConvertToHumanReadable()))
+ .ToArray();
+
+ _categoriesCache[date] = categories;
+ }
+ }
+
+ private void PrepareMonthDaysData()
+ {
+ _monthDaysData = new DayData[DaysInMonth];
+ var today = DateTime.Today;
+
+ for (int d = 1; d <= DaysInMonth; d++)
+ {
+ var day = new DateTime(CurrentMonth.Year, CurrentMonth.Month, d);
+ var isSelected = day.Date == SelectedDate.Date;
+ var isToday = day.Date == today;
+
+ var cssClass = isSelected ? "selected" : (isToday ? "today" : "");
+ var hasEvents = _eventsCache.ContainsKey(day.Date);
+ var eventCategories = hasEvents ? GetFilteredCategoriesForDay(day.Date) : Array.Empty();
+
+ _monthDaysData[d - 1] = new DayData(day, cssClass, eventCategories.Length > 0, eventCategories);
+ }
+ }
+
+ private void PrepareWeekDaysData()
+ {
+ var start = GetStartOfWeek(SelectedDate);
+ var today = DateTime.Today;
+ var culture = new System.Globalization.CultureInfo("it-IT");
+
+ for (int i = 0; i < 7; i++)
+ {
+ var day = start.AddDays(i);
+ var isSelected = day.Date == SelectedDate.Date;
+ var isToday = day.Date == today;
+
+ var cssClass = isSelected ? "selected" : (isToday ? "today" : "");
+ var dayName = day.ToString("ddd", culture);
+ var hasEvents = _eventsCache.ContainsKey(day.Date);
+ var eventCategories = hasEvents ? GetFilteredCategoriesForDay(day.Date) : Array.Empty();
+
+ _weekDaysData[i] = new DayData(day, cssClass, eventCategories.Length > 0, eventCategories, dayName);
+ }
+ }
+
+ private CategoryData[] GetFilteredCategoriesForDay(DateTime date)
+ {
+ if (!_categoriesCache.TryGetValue(date, out var categories))
+ return Array.Empty();
+
+ if (Filter.ClearFilter)
+ return categories;
+
+ // Applica i filtri alle categorie
+ var filteredActivities = GetFilteredActivitiesForDay(date);
+ if (!filteredActivities.Any())
+ return Array.Empty();
+
+ return filteredActivities
+ .Select(x => x.Category)
+ .Distinct()
+ .Select(cat => new CategoryData(cat.ConvertToHumanReadable(), cat.ConvertToHumanReadable()))
+ .ToArray();
+ }
+
+ private List GetFilteredActivitiesForDay(DateTime date)
+ {
+ if (!_eventsCache.TryGetValue(date, out var activities))
+ return new List();
+
+ if (Filter.ClearFilter)
+ return activities;
+
+ return activities.Where(x =>
+ (!Filter.Text.IsNullOrEmpty() && x.ActivityDescription != null && x.ActivityDescription.ContainsIgnoreCase(Filter.Text!)) ||
+ (x.ActivityTypeId != null && !Filter.Type.IsNullOrEmpty() && x.ActivityTypeId.Equals(Filter.Type)) ||
+ (x.ActivityResultId != null && !Filter.Result.IsNullOrEmpty() && x.ActivityResultId.Equals(Filter.Result)) ||
+ (x.UserName != null && !Filter.User.IsNullOrEmpty() && Filter.User!.Contains(x.UserName)) ||
+ (Filter.Category != null && x.Category.Equals(Filter.Category))
+ ).ToList();
+ }
+
[JSInvokable]
public async Task OnSwipeLeft()
{
await CambiaPeriodo(1);
+ PrepareRenderingData();
StateHasChanged();
if (Expanded)
{
@@ -184,6 +371,7 @@
public async Task OnSwipeRight()
{
await CambiaPeriodo(-1);
+ PrepareRenderingData();
StateHasChanged();
if (Expanded)
{
@@ -210,7 +398,6 @@
{
if (Expanded)
{
- // Cambio solo il mese visualizzato, NON cambiare SelectedDate
var y = CurrentMonth.Year;
var m = CurrentMonth.Month + direzione;
if (m < 1)
@@ -229,7 +416,6 @@
}
else
{
- // Cambio settimana: aggiorno anche il giorno selezionato
await SelezionaData(SelectedDate.AddDays(7 * direzione));
_internalMonth = new DateTime(SelectedDate.Year, SelectedDate.Month, 1);
}
@@ -241,16 +427,17 @@
if (Expanded)
{
SliderAnimation = "collapse-animation";
- StateHasChanged();
Expanded = false;
}
else
{
Expanded = true;
SliderAnimation = "expand-animation";
- StateHasChanged();
}
+ PrepareRenderingData();
+ StateHasChanged();
+
SliderAnimation = "";
StateHasChanged();
}
@@ -261,7 +448,6 @@
IsLoading = true;
StateHasChanged();
- // Carica tutte le attività del mese corrente visualizzato
var start = CurrentMonth;
var end = start.AddDays(DaysInMonth - 1);
var activities = await ManageData.GetActivity(x =>
@@ -269,6 +455,7 @@
(x.EffectiveDate >= start && x.EffectiveDate <= end));
MonthActivities = activities.OrderBy(x => x.EffectiveDate ?? x.EstimatedDate).ToList();
+ PrepareRenderingData();
IsLoading = false;
StateHasChanged();
}
@@ -277,7 +464,6 @@
private async Task SelezionaData(DateTime day)
{
SelectedDate = day;
- StateHasChanged();
var cacheInternalMonth = _internalMonth;
_internalMonth = new DateTime(day.Year, day.Month, 1);
@@ -286,6 +472,10 @@
{
await LoadMonthData();
}
+ else
+ {
+ PrepareRenderingData();
+ }
ApplyFilter();
StateHasChanged();
@@ -295,12 +485,14 @@
private async Task SelezionaDataDalMese(DateTime day)
{
SelectedDate = day;
- ApplyFilter();
- // Chiudi la vista mese e passa alla settimana, con animazione
SliderAnimation = "collapse-animation";
- StateHasChanged();
Expanded = false;
- _internalMonth = new DateTime(day.Year, day.Month, 1); // Sync il mese visualizzato
+ _internalMonth = new DateTime(day.Year, day.Month, 1);
+
+ PrepareRenderingData();
+ ApplyFilter();
+ StateHasChanged();
+
SliderAnimation = "";
StateHasChanged();
}
@@ -315,7 +507,7 @@
}
private List GetEventsForDay(DateTime day)
- => MonthActivities?.Where(x => (x.EffectiveDate ?? x.EstimatedDate) == day.Date).ToList() ?? [];
+ => _eventsCache.TryGetValue(day.Date, out var events) ? events : new List();
public void Dispose()
{
@@ -330,6 +522,7 @@
if (indexActivity != null && !newActivity.IsNullOrEmpty())
{
MonthActivities![indexActivity.Value] = newActivity[0];
+ PrepareRenderingData(); // Ricalcola i dati di rendering
}
ApplyFilter();
@@ -344,40 +537,25 @@
private void ApplyFilter()
{
- FilteredActivities = GetEventsForDay(SelectedDate);
+ FilteredActivities = GetFilteredActivitiesForDay(SelectedDate);
- if (!Filter.ClearFilter)
+ // Aggiorna i dati di rendering se il filtro è cambiato
+ if (Expanded)
{
- FilteredActivities = GetEventsForDay(SelectedDate)?
- .Where(x =>
- (!Filter.Text.IsNullOrEmpty() && x.ActivityDescription != null && x.ActivityDescription.ContainsIgnoreCase(Filter.Text!)) ||
- (x.ActivityTypeId != null && !Filter.Type.IsNullOrEmpty() && x.ActivityTypeId.Equals(Filter.Type)) ||
- (x.ActivityResultId != null && !Filter.Result.IsNullOrEmpty() && x.ActivityResultId.Equals(Filter.Result)) ||
- (x.UserName != null && !Filter.User.IsNullOrEmpty() && Filter.User!.Contains(x.UserName)) ||
- (Filter.Category != null && x.Category.Equals(Filter.Category))
- )
- .ToList() ?? [];
+ PrepareMonthDaysData();
+ }
+ else
+ {
+ PrepareWeekDaysData();
}
StateHasChanged();
}
+ // Metodo ottimizzato per il rendering dei filtri
private List ReturnFilteredActivity(DateTime day)
{
- if (!Filter.ClearFilter)
- {
- return GetEventsForDay(day)?
- .Where(x =>
- (!Filter.Text.IsNullOrEmpty() && x.ActivityDescription != null && x.ActivityDescription.ContainsIgnoreCase(Filter.Text!)) ||
- (x.ActivityTypeId != null && !Filter.Type.IsNullOrEmpty() && x.ActivityTypeId.Equals(Filter.Type)) ||
- (x.ActivityResultId != null && !Filter.Result.IsNullOrEmpty() && x.ActivityResultId.Equals(Filter.Result)) ||
- (x.UserName != null && !Filter.User.IsNullOrEmpty() && Filter.User!.Contains(x.UserName)) ||
- (Filter.Category != null && x.Category.Equals(Filter.Category))
- )
- .ToList() ?? [];
- }
-
- return GetEventsForDay(day);
+ return GetFilteredActivitiesForDay(day);
}
}
\ No newline at end of file
diff --git a/Template.Shared/Components/Pages/Login.razor b/Template.Shared/Components/Pages/Login.razor
index f25980a..b319086 100644
--- a/Template.Shared/Components/Pages/Login.razor
+++ b/Template.Shared/Components/Pages/Login.razor
@@ -10,41 +10,34 @@
}
else
{
-
-
-
-
- Nome App
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ SalesBook
+
+
+
+
+
+
+ @if (_attemptFailed)
+ {
+
@ErrorMessage
+ }
}
diff --git a/Template.Shared/Components/Pages/Login.razor.css b/Template.Shared/Components/Pages/Login.razor.css
index a2610c3..f7c0617 100644
--- a/Template.Shared/Components/Pages/Login.razor.css
+++ b/Template.Shared/Components/Pages/Login.razor.css
@@ -1,46 +1,44 @@
-.center-box {
- margin-top: -1.1rem !important; /* remove page padding */
+.login-page {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ background: hsl(from var(--mud-palette-primary) h s 96%);
}
-.box-area {
- width: 930px;
-}
-
-.right-box {
- padding: 15px 30px 0 30px;
-}
-
-::placeholder {
- font-size: 16px;
-}
-
-.rounded-4 {
- border-radius: 20px;
-}
-
-.rounded-5 {
- border-radius: 30px;
-}
-
-.bg-white {
- background: var(--mud-palette-surface) !important;
-}
-
-.appName {
- margin-top: 15px;
- font-size: large;
+.container-top-logo > span {
+ font-size: x-large;
font-weight: 900;
color: var(--mud-palette-primary)
}
-.button-login {
+.container-login > span {
+ font-size: large;
+ font-weight: 900;
text-align: center;
- background-color: var(--mud-palette-primary);
- border-radius: 6px;
- padding: .3rem 2rem;
- width: 100%;
- font-weight: 700;
- color: var(--mud-palette-appbar-text);
+}
+
+.container-top-logo {
+ height: 35vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.login-form-container {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.container-login {
+ background: var(--mud-palette-surface);
+ border-top-left-radius: 16px;
+ border-top-right-radius: 16px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ padding: 4px 16px 16px;
+ box-shadow: 0 -2px 10px rgba(165, 165, 165, 0.5);
}
.login-footer {
@@ -57,9 +55,4 @@
.login-footer img {
height: 15px;
margin-left: 4px;
-}
-
-.container > .bg-white {
- box-shadow: var(--card-shadow);
- border: 1px solid var(--card-border-color);
}
\ No newline at end of file