From 588dbe308aab84e275d049ea9cec8da2863d7019 Mon Sep 17 00:00:00 2001 From: MarcoE Date: Fri, 29 Aug 2025 18:20:07 +0200 Subject: [PATCH] Creata pagina step della commessa --- salesbook.Maui/MauiProgram.cs | 8 +- .../Components/Layout/NavMenu.razor | 4 +- .../Components/Pages/Commessa.razor | 95 ++++++++ .../Components/Pages/Commessa.razor.css | 215 ++++++++++++++++++ salesbook.Shared/Components/Pages/User.razor | 125 ++++++++-- .../Components/Pages/User.razor.css | 118 ++++++++++ salesbook.Shared/Components/Pages/Users.razor | 50 ++-- .../SingleElements/Card/CommessaCard.razor | 56 ++++- .../Card/CommessaCard.razor.css | 16 +- .../JobProgress/CRMJobProgressResponseDTO.cs | 9 + .../Core/Dto/JobProgress/CRMJobStatusDTO.cs | 15 ++ .../Core/Dto/JobProgress/CRMJobStepDTO.cs | 15 ++ .../Core/Dto/PageState/JobSteps.cs | 8 + .../Core/Dto/PageState/UserListState.cs | 9 + .../Core/Dto/PageState/UserPageState.cs | 15 ++ .../Core/Dto/Users/UserDisplayItem.cs | 8 + salesbook.Shared/Core/Entity/JtbComt.cs | 3 + .../Core/Interface/IIntegryApiService.cs | 3 + .../Core/Services/IntegryApiService.cs | 8 + salesbook.Shared/wwwroot/css/app.css | 4 +- 20 files changed, 732 insertions(+), 52 deletions(-) create mode 100644 salesbook.Shared/Components/Pages/Commessa.razor create mode 100644 salesbook.Shared/Components/Pages/Commessa.razor.css create mode 100644 salesbook.Shared/Core/Dto/JobProgress/CRMJobProgressResponseDTO.cs create mode 100644 salesbook.Shared/Core/Dto/JobProgress/CRMJobStatusDTO.cs create mode 100644 salesbook.Shared/Core/Dto/JobProgress/CRMJobStepDTO.cs create mode 100644 salesbook.Shared/Core/Dto/PageState/JobSteps.cs create mode 100644 salesbook.Shared/Core/Dto/PageState/UserListState.cs create mode 100644 salesbook.Shared/Core/Dto/PageState/UserPageState.cs create mode 100644 salesbook.Shared/Core/Dto/Users/UserDisplayItem.cs diff --git a/salesbook.Maui/MauiProgram.cs b/salesbook.Maui/MauiProgram.cs index 2b3aa2a..d6350f3 100644 --- a/salesbook.Maui/MauiProgram.cs +++ b/salesbook.Maui/MauiProgram.cs @@ -9,6 +9,7 @@ using MudExtensions.Services; using salesbook.Maui.Core.Services; using salesbook.Shared; using salesbook.Shared.Core.Dto; +using salesbook.Shared.Core.Dto.PageState; using salesbook.Shared.Core.Helpers; using salesbook.Shared.Core.Interface; using salesbook.Shared.Core.Messages.Activity.Copy; @@ -58,6 +59,12 @@ namespace salesbook.Maui builder.Services.AddScoped(); builder.Services.AddScoped(); + //SessionData + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + //Message builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -73,7 +80,6 @@ namespace salesbook.Maui builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); - builder.Services.AddSingleton(); return builder.Build(); } diff --git a/salesbook.Shared/Components/Layout/NavMenu.razor b/salesbook.Shared/Components/Layout/NavMenu.razor index 9cf2d2e..0bd0fee 100644 --- a/salesbook.Shared/Components/Layout/NavMenu.razor +++ b/salesbook.Shared/Components/Layout/NavMenu.razor @@ -67,10 +67,10 @@ { var location = args.Location.Remove(0, NavigationManager.BaseUri.Length); - var newIsVisible = new List { "Calendar", "Users", "Notifications" } + var newIsVisible = new List { "Calendar", "Users", "Notifications", "Commessa" } .Contains(location); - var newPlusVisible = new List { "Calendar", "Users" } + var newPlusVisible = new List { "Calendar", "Users", "Commessa" } .Contains(location); if (IsVisible == newIsVisible && PlusVisible == newPlusVisible) return; diff --git a/salesbook.Shared/Components/Pages/Commessa.razor b/salesbook.Shared/Components/Pages/Commessa.razor new file mode 100644 index 0000000..15a88fe --- /dev/null +++ b/salesbook.Shared/Components/Pages/Commessa.razor @@ -0,0 +1,95 @@ +@page "/commessa/{CodJcom}" +@page "/commessa/{CodJcom}/{RagSoc}" +@attribute [Authorize] +@using salesbook.Shared.Components.Layout +@using salesbook.Shared.Components.Layout.Spinner +@using salesbook.Shared.Components.SingleElements +@using salesbook.Shared.Core.Dto.JobProgress +@using salesbook.Shared.Core.Dto.PageState +@using salesbook.Shared.Core.Entity +@using salesbook.Shared.Core.Interface +@inject JobSteps JobSteps +@inject IManageDataService ManageData + + + +@if (IsLoading) +{ + +} +else +{ +
+ @if (CommessaModel == null) + { + + } + else + { + + + + +
+
    +
  • +
  • +
  • +
+
+ + +
+
+ @if (Steps != null) + { +
+
+ @foreach (var step in Steps) + { +
+
+
+
@step.StepName
+ @if (step.Date is not null) + { +
@($"{step.Date.Value:D}") @(step.Status!.Progress ? "(In corso...)" : "")
+ } +
+
+ } +
+
+ } +
+
Contenuto 2
+
Contenuto 3
+
+ } +
+} + +@code { + [Parameter] public string CodJcom { get; set; } = ""; + [Parameter] public string RagSoc { get; set; } = ""; + + private List? Steps { get; set; } + private JtbComt? CommessaModel { get; set; } + + private bool IsLoading { get; set; } = true; + + protected override async Task OnInitializedAsync() + { + await LoadData(); + } + + private async Task LoadData() + { + CommessaModel = (await ManageData.GetTable(x => x.CodJcom.Equals(CodJcom))).LastOrDefault(); + Steps = JobSteps.Steps; + + IsLoading = false; + } + +} + diff --git a/salesbook.Shared/Components/Pages/Commessa.razor.css b/salesbook.Shared/Components/Pages/Commessa.razor.css new file mode 100644 index 0000000..6ae66ef --- /dev/null +++ b/salesbook.Shared/Components/Pages/Commessa.razor.css @@ -0,0 +1,215 @@ +/* Container scrollabile */ + +.timeline-container { + height: 100%; + overflow-y: auto; + padding-right: 10px; +} + +.timeline { + display: flex; + flex-direction: column; + gap: 1.5rem; + position: relative; + padding-left: 40px; /* spazio per linea e cerchi */ +} + +.step { + display: flex; + align-items: flex-start; + gap: 15px; + position: relative; +} + +/* Linea sopra e sotto ogni step */ + +.step::before, +.step::after { + content: ""; + position: absolute; + left: -31px; + width: 2px; + background: #ddd; +} + +.step::after { + top: 30%; + bottom: -1.5rem; +} + +.step:first-child::before { display: none; } + +.step:last-child::after { display: none; } + +/* Cerchio base */ + +.circle, +.in-progress { + width: 20px; + height: 20px; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + flex-shrink: 0; + z-index: 1; + margin-left: -40px; + background-color: var(--mud-palette-tertiary); +} + +/* Stato skippato */ + +.skipped { background: #ccc; } + +/* Stato completato */ + +.completed { + background: var(--mud-palette-primary); + color: white; + font-weight: bold; +} + +/* Stato in corso con spinner */ + +.in-progress { + border: 2px solid var(--mud-palette-primary); + border-top: 2px solid transparent; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + + 100% { transform: rotate(360deg); } +} + +/* Label con titolo + sottotitolo */ + +.label { + display: flex; + flex-direction: column; +} + +.titleStep { + font-size: 1.1rem; + font-weight: 600; + color: #111; + line-height: normal; +} + +.subtitleStep { + font-size: .90rem; + color: #666; + line-height: normal; +} + +.timeline-container::-webkit-scrollbar { width: 6px; } + +.timeline-container::-webkit-scrollbar-thumb { + background: #bbb; + border-radius: 3px; +} + +/*-------------- + TabPanel +----------------*/ + +.box { + display: flex; + flex-direction: column; + width: -webkit-fill-available; + box-shadow: var(--custom-box-shadow); + border-radius: 16px; + overflow: clip; + margin-bottom: 1rem; +} + +/* nascondo gli input */ + +.tab-toggle { display: none; } + +.tab-list { + margin: 0; + padding: 0; + list-style: none; + display: flex; + position: relative; + z-index: 1; + background: var(--mud-palette-surface); +} + +/* la lineetta */ + +.tab-list::before { + content: ''; + display: block; + height: 3px; + width: calc(100% / 3); + position: absolute; + bottom: 0; + left: 0; + background-color: var(--mud-palette-primary); + transition: transform .3s; +} + +.tab-item { + flex: 1; + text-align: center; + transition: .3s; + opacity: 0.5; +} + +.tab-trigger { + display: block; + padding: 10px 0; + cursor: pointer; +} + +/* tab attivo */ + +#tab1:checked ~ .box .tab-list .tab-item:nth-child(1), +#tab2:checked ~ .box .tab-list .tab-item:nth-child(2), +#tab3:checked ~ .box .tab-list .tab-item:nth-child(3) { + opacity: 1; + font-weight: bold; + display: block; +} + +/* spostamento lineetta */ + +#tab1:checked ~ .box .tab-list::before { transform: translateX(0%); } + +#tab2:checked ~ .box .tab-list::before { transform: translateX(100%); } + +#tab3:checked ~ .box .tab-list::before { transform: translateX(200%); } + +.tab-container { + display: flex; + flex-direction: column; + overflow: hidden; + width: -webkit-fill-available; +} + +.tab-content { + display: none; + flex: 1; + overflow-y: auto; + animation: fade .3s ease; + padding: .5rem; +} + +#tab1:checked ~ .tab-container .tab-content:nth-child(1), +#tab2:checked ~ .tab-container .tab-content:nth-child(2), +#tab3:checked ~ .tab-container .tab-content:nth-child(3) { display: block; } + +@keyframes fade { + from { + opacity: 0; + transform: translateY(5px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file diff --git a/salesbook.Shared/Components/Pages/User.razor b/salesbook.Shared/Components/Pages/User.razor index dedce52..0ef50bc 100644 --- a/salesbook.Shared/Components/Pages/User.razor +++ b/salesbook.Shared/Components/Pages/User.razor @@ -7,12 +7,15 @@ @using salesbook.Shared.Components.Layout.Spinner @using salesbook.Shared.Core.Dto @using salesbook.Shared.Components.SingleElements +@using salesbook.Shared.Core.Dto.JobProgress +@using salesbook.Shared.Core.Dto.PageState @inject IManageDataService ManageData @inject IMapper Mapper @inject IDialogService Dialog -@inject INetworkService NetworkService +@inject IIntegryApiService IntegryApiService +@inject UserPageState UserState - + @if (IsLoading) { @@ -89,11 +92,27 @@ else - - + + + +
+
    +
  • + +
  • +
  • + +
  • +
+
+ + +
+
+ @if (PersRif is { Count: > 0 }) { -
+
@{ var index = PersRif.IndexOf(person); @@ -117,20 +136,30 @@ else Aggiungi contatto
- - - @if (Commesse.IsNullOrEmpty()) +
+
+ + @if (LoadCommessa) { - + } else { - - - + @if (Commesse.IsNullOrEmpty()) + { + + } + else + { +
+ + + +
+ } } - - +
+
} @@ -140,14 +169,26 @@ else private ContactDTO Anag { get; set; } = new(); private List? PersRif { get; set; } - private List Commesse { get; set; } + private List? Commesse { get; set; } private StbUser? Agente { get; set; } + private Dictionary?> Steps { get; set; } = []; private bool IsLoading { get; set; } = true; + private bool LoadCommessa { get; set; } = true; protected override async Task OnInitializedAsync() { - await LoadData(); + if (UserState.CodUser != null && UserState.CodUser.Equals(CodContact)) + { + LoadDataFromSession(); + } + else + { + await LoadData(); + } + + IsLoading = false; + StateHasChanged(); } private async Task LoadData() @@ -164,18 +205,64 @@ else } await LoadPersRif(); - - Commesse = await ManageData.GetTable(x => x.CodAnag != null && x.CodAnag.Equals(CodContact)); + _ = LoadCommesse(); if (Anag.CodVage != null) { Agente = (await ManageData.GetTable(x => x.UserCode != null && x.UserCode.Equals(Anag.CodVage))).LastOrDefault(); } - IsLoading = false; + SetDataSession(); + } + + private void LoadDataFromSession() + { + Anag = UserState.Anag; + PersRif = UserState.PersRif; + Commesse = UserState.Commesse; + Agente = UserState.Agente; + Steps = UserState.Steps; + + SortCommesse(); + + LoadCommessa = false; StateHasChanged(); } + private void SetDataSession() + { + UserState.CodUser = CodContact; + UserState.Anag = Anag; + UserState.PersRif = PersRif; + UserState.Agente = Agente; + UserState.Steps = Steps; + } + + private async Task LoadCommesse() + { + await Task.Run(async () => + { + Commesse = await ManageData.GetTable(x => x.CodAnag != null && x.CodAnag.Equals(CodContact)); + UserState.Commesse = Commesse; + + foreach (var commessa in Commesse) + { + var steps = (await IntegryApiService.RetrieveJobProgress(commessa.CodJcom)).Steps; + Steps.Add(commessa.CodJcom, steps); + } + + LoadCommessa = false; + }); + + SortCommesse(); + StateHasChanged(); + } + + private void SortCommesse() + { + Commesse = Commesse?.OrderBy(x => x.LastUpd.HasValue).ThenBy(x => x.LastUpd).ToList(); + } + private async Task LoadPersRif() { if (IsContact) diff --git a/salesbook.Shared/Components/Pages/User.razor.css b/salesbook.Shared/Components/Pages/User.razor.css index 45277bc..a47a4b1 100644 --- a/salesbook.Shared/Components/Pages/User.razor.css +++ b/salesbook.Shared/Components/Pages/User.razor.css @@ -87,6 +87,7 @@ box-shadow: var(--custom-box-shadow); padding: .25rem 0; border-radius: 16px; + margin-bottom: 0 !important; } .container-button .divider { @@ -156,4 +157,121 @@ display: flex; gap: 1rem; flex-direction: column; +} + +.commesse-container { + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +.commesse-container ::deep > div:first-child:not(.activity-card) { + display: none; +} + +/*-------------- + TabPanel +----------------*/ + +.box { + display: flex; + flex-direction: column; + width: -webkit-fill-available; + box-shadow: var(--custom-box-shadow); + border-radius: 16px; + overflow: clip; + margin-bottom: 1rem; +} + +/* nascondo gli input */ + +.tab-toggle { display: none; } + +.tab-list { + margin: 0; + padding: 0; + list-style: none; + display: flex; + position: relative; + z-index: 1; + background: var(--mud-palette-surface); +} + +/* la lineetta */ + +.tab-list::before { + content: ''; + display: block; + height: 3px; + width: calc(100% / 2); + position: absolute; + bottom: 0; + left: 0; + background-color: var(--mud-palette-primary); + transition: transform .3s; +} + +.tab-item { + flex: 1; + text-align: center; + transition: .3s; + opacity: 0.5; +} + +.tab-trigger { + display: block; + padding: 10px 0; + cursor: pointer; +} + +/* tab attivo */ + +#tab1:checked ~ .box .tab-list .tab-item:nth-child(1), +#tab2:checked ~ .box .tab-list .tab-item:nth-child(2) { + opacity: 1; + font-weight: bold; + display: block; +} + +/* spostamento lineetta */ + +#tab1:checked ~ .box .tab-list::before { transform: translateX(0%); } + +#tab2:checked ~ .box .tab-list::before { transform: translateX(100%); } + +.tab-container { + display: flex; + flex-direction: column; + overflow: hidden; + width: -webkit-fill-available; +} + +.tab-content { + display: none; + flex: 1; + overflow-y: auto; + animation: fade .3s ease; + padding: .5rem; +} + +.tab-content::-webkit-scrollbar { width: 3px; } + +.tab-content::-webkit-scrollbar-thumb { + background: #bbb; + border-radius: 2px; +} + +#tab1:checked ~ .tab-container .tab-content:nth-child(1), +#tab2:checked ~ .tab-container .tab-content:nth-child(2) { display: block; } + +@keyframes fade { + from { + opacity: 0; + transform: translateY(5px); + } + + to { + opacity: 1; + transform: translateY(0); + } } \ No newline at end of file diff --git a/salesbook.Shared/Components/Pages/Users.razor b/salesbook.Shared/Components/Pages/Users.razor index 666fae8..76b12b5 100644 --- a/salesbook.Shared/Components/Pages/Users.razor +++ b/salesbook.Shared/Components/Pages/Users.razor @@ -6,11 +6,14 @@ @using salesbook.Shared.Components.SingleElements.BottomSheet @using salesbook.Shared.Components.Layout.Spinner @using salesbook.Shared.Components.SingleElements +@using salesbook.Shared.Core.Dto.PageState +@using salesbook.Shared.Core.Dto.Users @using salesbook.Shared.Core.Entity @using salesbook.Shared.Core.Messages.Contact @inject IManageDataService ManageData @inject NewContactService NewContact @inject FilterUserDTO Filter +@inject UserListState UserState @@ -70,22 +73,46 @@ protected override void OnInitialized() { NewContact.OnContactCreated += async response => await OnUserCreated(response); - Console.WriteLine($"Filter HashCode: {Filter.GetHashCode()} - IsInitialized: {Filter.IsInitialized}"); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - await LoadData(); + IsLoading = true; + StateHasChanged(); + + if (UserState.FilteredGroupedUserList == null && UserState.GroupedUserList == null) + { + await LoadData(); + SetDataSession(); + } + else + { + LoadFromSession(); + } + + FilterUsers(); + + IsLoading = false; + StateHasChanged(); } } + private void LoadFromSession() + { + GroupedUserList = UserState.GroupedUserList!; + FilteredGroupedUserList = UserState.FilteredGroupedUserList!; + } + + private void SetDataSession() + { + UserState.GroupedUserList = GroupedUserList; + UserState.FilteredGroupedUserList = FilteredGroupedUserList; + } + private async Task LoadData() { - IsLoading = true; - StateHasChanged(); - if (!Filter.IsInitialized) { var loggedUser = (await ManageData.GetTable(x => x.UserName.Equals(UserSession.User.Username))).Last(); @@ -126,19 +153,6 @@ HeaderLetter = currentLetter }); } - - FilterUsers(); - - IsLoading = false; - StateHasChanged(); - } - - - private class UserDisplayItem - { - public required ContactDTO User { get; set; } - public bool ShowHeader { get; set; } - public string? HeaderLetter { get; set; } } private void FilterUsers() => FilterUsers(false); diff --git a/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor b/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor index d8fb918..00ed37a 100644 --- a/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor +++ b/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor @@ -1,24 +1,68 @@ +@using salesbook.Shared.Core.Dto.JobProgress +@using salesbook.Shared.Core.Dto.PageState @using salesbook.Shared.Core.Entity +@inject JobSteps JobSteps -
+
- @Commessa.Descrizione + @Commessa.CodJcom
- - @Commessa.CodJcom - + @if (LastUpd is not null) + { + Aggiornato il @($"{LastUpd:d}") + }
+ @Commessa.Descrizione
- Stato + @if (Stato is not null) + { + @Stato + }
@code { [Parameter] public JtbComt Commessa { get; set; } = new(); + [Parameter] public string RagSoc { get; set; } = ""; + [Parameter] public List? Steps { get; set; } + + private string? Stato { get; set; } + private DateTime? LastUpd { get; set; } + + protected override async Task OnParametersSetAsync() + { + GetStepInfo(); + } + + private void GetStepInfo() + { + if (Steps is null) return; + + var lastBeforeSkip = Steps + .TakeWhile(s => s.Status is { Skip: false }) + .LastOrDefault(); + + if (lastBeforeSkip is not null) Stato = lastBeforeSkip.StepName; + + LastUpd = Steps + .Where(s => s.Date.HasValue) + .Select(s => s.Date!.Value) + .DefaultIfEmpty() + .Max(); + + if (LastUpd.Equals(DateTime.MinValue)) LastUpd = null; + } + + private void OpenPageCommessa() + { + JobSteps.Steps = Steps; + NavigationManager.NavigateTo($"commessa/{Commessa.CodJcom}/{RagSoc}"); + } + } \ No newline at end of file diff --git a/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor.css b/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor.css index 947044b..40a538d 100644 --- a/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor.css +++ b/salesbook.Shared/Components/SingleElements/Card/CommessaCard.razor.css @@ -28,8 +28,9 @@ } .activity-hours { - font-weight: 700; - color: var(--mud-palette-text-primary); + color: var(--mud-palette-gray-darker); + font-weight: 600; + font-size: .8rem; } .activity-hours-section ::deep .mud-chip { margin: 5px 0 0 !important; } @@ -40,13 +41,18 @@ flex-direction: column; } -.title-section ::deep > .activity-title { +.activity-title { font-weight: 800 !important; margin: 0 !important; line-height: normal !important; color: var(--mud-palette-text-primary); } +.title-section ::deep > .activity-title { + font-weight: 600; + color: var(--mud-palette-text-primary); +} + .activity-body-section ::deep > .activity-subtitle { color: var(--mud-palette-gray-darker); margin: .2rem 0 !important; @@ -55,5 +61,7 @@ .activity-info-section { display: flex; - flex-wrap: wrap; + align-items: center; + justify-content: space-between; + margin-top: .25rem; } \ No newline at end of file diff --git a/salesbook.Shared/Core/Dto/JobProgress/CRMJobProgressResponseDTO.cs b/salesbook.Shared/Core/Dto/JobProgress/CRMJobProgressResponseDTO.cs new file mode 100644 index 0000000..ecec944 --- /dev/null +++ b/salesbook.Shared/Core/Dto/JobProgress/CRMJobProgressResponseDTO.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace salesbook.Shared.Core.Dto.JobProgress; + +public class CRMJobProgressResponseDTO +{ + [JsonPropertyName("steps")] + public List Steps { get; set; } +} \ No newline at end of file diff --git a/salesbook.Shared/Core/Dto/JobProgress/CRMJobStatusDTO.cs b/salesbook.Shared/Core/Dto/JobProgress/CRMJobStatusDTO.cs new file mode 100644 index 0000000..7318f3c --- /dev/null +++ b/salesbook.Shared/Core/Dto/JobProgress/CRMJobStatusDTO.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace salesbook.Shared.Core.Dto.JobProgress; + +public class CRMJobStatusDTO +{ + [JsonPropertyName("completed")] + public bool Completed { get; set; } + + [JsonPropertyName("progress")] + public bool Progress { get; set; } + + [JsonPropertyName("skip")] + public bool Skip { get; set; } +} \ No newline at end of file diff --git a/salesbook.Shared/Core/Dto/JobProgress/CRMJobStepDTO.cs b/salesbook.Shared/Core/Dto/JobProgress/CRMJobStepDTO.cs new file mode 100644 index 0000000..13c5cf8 --- /dev/null +++ b/salesbook.Shared/Core/Dto/JobProgress/CRMJobStepDTO.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace salesbook.Shared.Core.Dto.JobProgress; + +public class CRMJobStepDTO +{ + [JsonPropertyName("stepName")] + public string? StepName { get; set; } + + [JsonPropertyName("status")] + public CRMJobStatusDTO? Status { get; set; } + + [JsonPropertyName("date")] + public DateTime? Date { get; set; } +} \ No newline at end of file diff --git a/salesbook.Shared/Core/Dto/PageState/JobSteps.cs b/salesbook.Shared/Core/Dto/PageState/JobSteps.cs new file mode 100644 index 0000000..ec31be7 --- /dev/null +++ b/salesbook.Shared/Core/Dto/PageState/JobSteps.cs @@ -0,0 +1,8 @@ +using salesbook.Shared.Core.Dto.JobProgress; + +namespace salesbook.Shared.Core.Dto.PageState; + +public class JobSteps +{ + public List? Steps { get; set; } +} \ No newline at end of file diff --git a/salesbook.Shared/Core/Dto/PageState/UserListState.cs b/salesbook.Shared/Core/Dto/PageState/UserListState.cs new file mode 100644 index 0000000..c1eb635 --- /dev/null +++ b/salesbook.Shared/Core/Dto/PageState/UserListState.cs @@ -0,0 +1,9 @@ +using salesbook.Shared.Core.Dto.Users; + +namespace salesbook.Shared.Core.Dto.PageState; + +public class UserListState +{ + public List? GroupedUserList { get; set; } + public List? FilteredGroupedUserList { get; set; } +} \ No newline at end of file diff --git a/salesbook.Shared/Core/Dto/PageState/UserPageState.cs b/salesbook.Shared/Core/Dto/PageState/UserPageState.cs new file mode 100644 index 0000000..a437ea1 --- /dev/null +++ b/salesbook.Shared/Core/Dto/PageState/UserPageState.cs @@ -0,0 +1,15 @@ +using salesbook.Shared.Core.Dto.JobProgress; +using salesbook.Shared.Core.Entity; + +namespace salesbook.Shared.Core.Dto.PageState; + +public class UserPageState +{ + public string? CodUser { get; set; } + + public ContactDTO Anag { get; set; } + public List? PersRif { get; set; } + public List Commesse { get; set; } + public StbUser? Agente { get; set; } + public Dictionary?> Steps { get; set; } +} \ No newline at end of file diff --git a/salesbook.Shared/Core/Dto/Users/UserDisplayItem.cs b/salesbook.Shared/Core/Dto/Users/UserDisplayItem.cs new file mode 100644 index 0000000..53e007f --- /dev/null +++ b/salesbook.Shared/Core/Dto/Users/UserDisplayItem.cs @@ -0,0 +1,8 @@ +namespace salesbook.Shared.Core.Dto.Users; + +public class UserDisplayItem +{ + public required ContactDTO User { get; set; } + public bool ShowHeader { get; set; } + public string? HeaderLetter { get; set; } +} \ No newline at end of file diff --git a/salesbook.Shared/Core/Entity/JtbComt.cs b/salesbook.Shared/Core/Entity/JtbComt.cs index 6c80f64..9d03496 100644 --- a/salesbook.Shared/Core/Entity/JtbComt.cs +++ b/salesbook.Shared/Core/Entity/JtbComt.cs @@ -107,4 +107,7 @@ public class JtbComt [Column("note_tecniche"), JsonPropertyName("noteTecniche")] public string NoteTecniche { get; set; } + + [Ignore, JsonIgnore] + public DateTime? LastUpd { get; set; } } \ No newline at end of file diff --git a/salesbook.Shared/Core/Interface/IIntegryApiService.cs b/salesbook.Shared/Core/Interface/IIntegryApiService.cs index 3635223..90eb85c 100644 --- a/salesbook.Shared/Core/Interface/IIntegryApiService.cs +++ b/salesbook.Shared/Core/Interface/IIntegryApiService.cs @@ -1,4 +1,5 @@ using salesbook.Shared.Core.Dto; +using salesbook.Shared.Core.Dto.JobProgress; using salesbook.Shared.Core.Entity; namespace salesbook.Shared.Core.Interface; @@ -22,6 +23,8 @@ public interface IIntegryApiService Task> GetActivityFile(string activityId); Task DownloadFile(string activityId, string fileName); + Task RetrieveJobProgress(string codJcom); + //Position Task SavePosition(PositionDTO position); Task RetrievePosition(string id); diff --git a/salesbook.Shared/Core/Services/IntegryApiService.cs b/salesbook.Shared/Core/Services/IntegryApiService.cs index 5cc6714..112f87e 100644 --- a/salesbook.Shared/Core/Services/IntegryApiService.cs +++ b/salesbook.Shared/Core/Services/IntegryApiService.cs @@ -1,6 +1,7 @@ using IntegryApiClient.Core.Domain.Abstraction.Contracts.Account; using IntegryApiClient.Core.Domain.RestClient.Contacts; using salesbook.Shared.Core.Dto; +using salesbook.Shared.Core.Dto.JobProgress; using salesbook.Shared.Core.Entity; using salesbook.Shared.Core.Interface; using System.Net.Http.Headers; @@ -146,4 +147,11 @@ public class IntegryApiService(IIntegryApiRestClient integryApiRestClient, IUser return integryApiRestClient.Get("retrievePosition", queryParams)!; } + + public Task RetrieveJobProgress(string codJcom) + { + var queryParams = new Dictionary { { "codJcom", codJcom } }; + + return integryApiRestClient.Get("crm/retrieveJobProgress", queryParams)!; + } } \ No newline at end of file diff --git a/salesbook.Shared/wwwroot/css/app.css b/salesbook.Shared/wwwroot/css/app.css index e224251..31a3a3c 100644 --- a/salesbook.Shared/wwwroot/css/app.css +++ b/salesbook.Shared/wwwroot/css/app.css @@ -31,11 +31,11 @@ a, .btn-link { .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; } .content { - /*padding-top: 1.1rem;*/ + padding-top: 1rem; display: flex; align-items: center; flex-direction: column; - height: 84vh; + height: 90vh; } h1:focus { outline: none; }