From 38055903832b7381446e3685897fe5ce2f046fa9 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 4 Aug 2024 19:18:53 +0200 Subject: [PATCH] Company, Product management changes, other fixes --- .../CardComponents/CompanyCardComponent.razor | 137 +++++++++++++++ .../CompanyCardComponent.razor.css | 29 ++++ .../CardComponents/ProductCardComponent.razor | 161 ++++++++++++++++++ .../ProductCardComponent.razor.css | 29 ++++ .../Pages/User/MyServiceProviders.razor | 155 +++++++++++------ .../ProductDetailGridComponent.razor | 88 +++++----- TIAMSharedUI/TIAMSharedUI.csproj | 3 + TIAMSharedUI/wwwroot/css/TourIAm.css | 3 + .../ServiceProviderAPIController.cs | 33 ++++ .../Interfaces/IServiceProviderDataService.cs | 1 + TIAMWebApp/Shared/Models/APIUrls.cs | 3 + .../Services/ServiceProviderDataService.cs | 17 ++ 12 files changed, 570 insertions(+), 89 deletions(-) create mode 100644 TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor create mode 100644 TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor.css create mode 100644 TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor create mode 100644 TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor.css diff --git a/TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor b/TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor new file mode 100644 index 00000000..6ee719f1 --- /dev/null +++ b/TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor @@ -0,0 +1,137 @@ +@using BlazorAnimation +@using TIAM.Core.Enums +@using TIAM.Entities.Profiles +@using TIAM.Entities.ServiceProviders +@using TIAM.Entities.Transfers +@using TIAM.Entities.Users +@using TIAM.Models.Dtos.Users +@using TIAM.Services +@using TIAMSharedUI.Shared.Components.Cards +@using TIAMWebApp.Shared.Application.Interfaces +@using TIAMWebApp.Shared.Application.Models.ClientSide.UI +@using TIAMWebApp.Shared.Application.Models.PageModels +@using TIAMWebApp.Shared.Application.Services +@inject IServiceProviderDataService ServiceProviderDataService +@inject IUserDataService UserDataService +@inject AdminSignalRClient AdminSignalRClient +@inject IJSRuntime JsRuntime + +
+
+
+ +
+
+
@($"{Context.Name}")
+

@Context.Profile.EmailAddress

+

@Context.Profile.Address.AddressText

+
+
+ +
+ +
+
+

Information

+ @RenderDetailsItem("fa-solid fa-user", "Contact Name", companyProfile.FullName) + +
+ +
+

Services in this company

+ @{ + if (Context.Products.Count() > 0) + { + + + + @foreach (var item in Context.Products) + { + + + +
+ +
+
+
+ } +
+
+ + } + } +
+ +

@msg

+
+
+ + +@code { + [Parameter] public Company Context { get; set; } + + [Parameter] public EventCallback DataChanged { get; set; } + + AccordionExpandMode ExpandMode { get; set; } = AccordionExpandMode.SingleOrNone; + AccordionExpandCollapseAction ExpandCollapseAction { get; set; } = AccordionExpandCollapseAction.HeaderClick; + + string msg; + private bool isSaveActive = false; + + private Profile companyProfile = new Profile(); + + void OnPasswordConfirmed(string password) + { + + + } + + protected async Task ChangeName() + { + + isSaveActive = false; + + + await DataChanged.InvokeAsync(msg); + } + + + + protected override async Task OnInitializedAsync() + { + var CompanyProfiles = await AdminSignalRClient.GetByIdAsync>(SignalRTags.GetProfileById, Context.ProfileId); + if (CompanyProfiles != null) + { + companyProfile = CompanyProfiles[0]; + } + await base.OnInitializedAsync(); + } + + protected override async Task OnParametersSetAsync() + { + + await base.OnParametersSetAsync(); + } + + RenderFragment RenderDetailsItem(string iconCssClass, string caption, string value) + { + + return @
+
+ +
+
+ +
@value
+
+
; + } + + private void RefreshComponent() + { + StateHasChanged(); + } +} diff --git a/TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor.css b/TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor.css new file mode 100644 index 00000000..ca9b8b1d --- /dev/null +++ b/TIAMSharedUI/Pages/User/CardComponents/CompanyCardComponent.razor.css @@ -0,0 +1,29 @@ +.e-name { + margin-bottom: 0.25rem; + font-size: 1.25rem; + font-weight: 500; + line-height: 1.2; +} + +.e-email { + font-size: 0.75rem; + text-decoration: underline; + margin-bottom: 0; +} + +.e-title { + font-size: 0.875rem; + margin-bottom: 0.5rem; +} + +.e-details .text-container label { + font-size: 0.8125rem; + line-height: 1rem; +} + +.e-details .text-container { + font-size: 0.875rem; + line-height: 1.125rem; + white-space: nowrap; +} + diff --git a/TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor b/TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor new file mode 100644 index 00000000..36100689 --- /dev/null +++ b/TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor @@ -0,0 +1,161 @@ +@using BlazorAnimation +@using TIAM.Core.Enums +@using TIAM.Entities.Products +@using TIAM.Entities.Profiles +@using TIAM.Entities.ServiceProviders +@using TIAM.Entities.Transfers +@using TIAM.Entities.Users +@using TIAM.Models.Dtos.Users +@using TIAM.Services +@using TIAMSharedUI.Shared.Components.Cards +@using TIAMWebApp.Shared.Application.Interfaces +@using TIAMWebApp.Shared.Application.Models.ClientSide.UI +@using TIAMWebApp.Shared.Application.Models.PageModels +@using TIAMWebApp.Shared.Application.Services +@inject IServiceProviderDataService ServiceProviderDataService +@inject IUserDataService UserDataService; +@inject AdminSignalRClient AdminSignalRClient; +@inject IJSRuntime JsRuntime; + +
+
+ @*
+ +
*@ + + + +
+
@($"{Context.Name}")
+

@Context.Profile.EmailAddress

+

@Context.Profile.Address.AddressText

+
+
+ +
+ +
+
+

Information

+ + @RenderDetailsItem("fa-solid fa-user", "Contact Name", productProfile.FullName) + +
+ +
+

Affiliate information

+ @{ + if (Context.ServiceProviderId != null) + { + var _url = $"{Setting.BaseUrl}/public/transfer/{Context.ServiceProvider.AffiliateId}/{Context.Id}"; + @_url + + // Copy referral url + + } + } +
+ +
+ +
+
+ Save +
+ +

@msg

+
+
+ + + +@code { + [Parameter] public Product Context { get; set; } + + [Parameter] public EventCallback DataChanged { get; set; } + + public string ImageSource { get; set; } = ""; + AccordionExpandMode ExpandMode { get; set; } = AccordionExpandMode.SingleOrNone; + AccordionExpandCollapseAction ExpandCollapseAction { get; set; } = AccordionExpandCollapseAction.HeaderClick; + + private Profile productProfile = new Profile(); + + string msg; + private bool isSaveActive = false; + + private async Task CopyUrl(string url) + { + + await JsRuntime.InvokeVoidAsync("copyToClipboard", url); + } + + void OnPasswordConfirmed(string password) + { + + + } + + protected async Task ChangeName() + { + + isSaveActive = false; + + + await DataChanged.InvokeAsync(msg); + } + + + + protected override async Task OnInitializedAsync() + { + var productOwner = await AdminSignalRClient.GetByIdAsync>(SignalRTags.GetCompaniesById, Context.ServiceProviderId); + if (productOwner != null) + { + ImageSource = await ServiceProviderDataService.GetQRCodeByProductIdAndOwnerAffiliateIdAsync(new Guid[] { productOwner[0].AffiliateId, Context.Id }); + } + var ProductProfiles = await AdminSignalRClient.GetByIdAsync>(SignalRTags.GetProfileById, Context.ProfileId); + if (ProductProfiles != null) + { + productProfile = ProductProfiles[0]; + } + await base.OnInitializedAsync(); + } + + protected override async Task OnParametersSetAsync() + { + + await base.OnParametersSetAsync(); + } + + RenderFragment RenderDetailsItem(string iconCssClass, string caption, string value) + { + return @
+
+ +
+
+ +
@value
+
+
; + } + + private void RefreshComponent() + { + StateHasChanged(); + } +} diff --git a/TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor.css b/TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor.css new file mode 100644 index 00000000..ca9b8b1d --- /dev/null +++ b/TIAMSharedUI/Pages/User/CardComponents/ProductCardComponent.razor.css @@ -0,0 +1,29 @@ +.e-name { + margin-bottom: 0.25rem; + font-size: 1.25rem; + font-weight: 500; + line-height: 1.2; +} + +.e-email { + font-size: 0.75rem; + text-decoration: underline; + margin-bottom: 0; +} + +.e-title { + font-size: 0.875rem; + margin-bottom: 0.5rem; +} + +.e-details .text-container label { + font-size: 0.8125rem; + line-height: 1rem; +} + +.e-details .text-container { + font-size: 0.875rem; + line-height: 1.125rem; + white-space: nowrap; +} + diff --git a/TIAMSharedUI/Pages/User/MyServiceProviders.razor b/TIAMSharedUI/Pages/User/MyServiceProviders.razor index d544dcfe..2c7f9a08 100644 --- a/TIAMSharedUI/Pages/User/MyServiceProviders.razor +++ b/TIAMSharedUI/Pages/User/MyServiceProviders.razor @@ -1,5 +1,6 @@ @page "/user/properties" @using BlazorAnimation +@using TIAM.Core.Enums @using TIAM.Entities.ServiceProviders @using TIAM.Resources @using TIAM.Services @@ -12,6 +13,7 @@ @using TIAMWebApp.Shared.Application.Services @using AyCode.Core.Helpers @using TIAMSharedUI.Shared.Components.Grids +@using TIAMSharedUI.Pages.User.CardComponents @layout AdminLayout @inject IEnumerable LogWriters @inject IStringLocalizer localizer @@ -29,60 +31,72 @@
- -
-
-
- -
- - - - - - - - - Manage - - - + + + - - - @{ -

Address: @(((Company)context.DataItem).Profile.Address.AddressText)

- } + + + @foreach (var company in companies) + { - - - - + + +
+ +
+
+
+ } +
+
- + + + + + + + + + + + Manage + + + -
-
-
+ + + @{ +

Address: @(((Company)context.DataItem).Profile.Address.AddressText)

+ } -
-
-
+ + + + -
+ + + + + + + +
@@ -90,10 +104,14 @@ @code { + + AccordionExpandMode ExpandMode { get; set; } = AccordionExpandMode.SingleOrNone; + AccordionExpandCollapseAction ExpandCollapseAction { get; set; } = AccordionExpandCollapseAction.HeaderClick; private LoggerClient _logger = null!; private CompanyGrid _gridCompany = null!; - + private List companies = []; + public List Companies = []; public ServiceProviderWizardModel MyModel = new ServiceProviderWizardModel(); bool EulaAccepted { get; set; } @@ -136,23 +154,58 @@ } } - protected override Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); _logger = new LoggerClient(LogWriters.ToArray()); - var myId = SessionService.User!.UserId; + + _logger.Debug(companies.Count().ToString()); _contextIds = new Guid[1]; _contextIds[0] = myId; + var result = await AdminSignalRClient.GetByIdAsync>(SignalRTags.GetCompaniesByContextId, myId); + //await AdminSignalRClient.GetAllIntoAsync(Companies, SignalRTags.GetCompaniesByContextId, new object[] { myId }); + companies = result; // ServiceProviderDataService.GetPropertiesByOwnerIdAsync(myId, companyPropertiesByOwner => // { // _logger.DetailConditional($"companyPropertiesByOwner count: {companyPropertiesByOwner?.Count.ToString() ?? "NULL"}"); // }).Forget(); - return base.OnInitializedAsync(); + } void ColumnChooserButton_Click() { _gridCompany.ShowColumnChooser(); } + + string GetCustomColor(ProductType productType) + { + + var transferStatusByte = (byte)productType; + + switch (transferStatusByte) + { + case 5: + return "bg-important"; + + case > 5 and < 35: + return "bg-attention"; + + case 35: + return "bg-finished"; + + case > 35: + return "bg-cancel"; + + default: + return ""; + } + + } + + private void RefreshComponent() + { + StateHasChanged(); + } } diff --git a/TIAMSharedUI/Pages/User/SysAdmins/ProductDetailGridComponent.razor b/TIAMSharedUI/Pages/User/SysAdmins/ProductDetailGridComponent.razor index 5f502669..d1a2e006 100644 --- a/TIAMSharedUI/Pages/User/SysAdmins/ProductDetailGridComponent.razor +++ b/TIAMSharedUI/Pages/User/SysAdmins/ProductDetailGridComponent.razor @@ -22,6 +22,7 @@ @inject IStringLocalizer Localizer @inject IEnumerable LogWriters @inject AdminSignalRClient AdminSignalRClient; +@inject IJSRuntime JsRuntime; - - - - - @{ - Product product = (Product)context.DataItem; - if (product.ProductType == TIAM.Core.Enums.ProductType.Hotel) - { - Manage hotel - } - else if (product.ProductType == TIAM.Core.Enums.ProductType.Transfer) - { - Manage transfer service - } - } - - + - - - @* - /public/transfer/{referralId:guid}/{productId:guid} - *@ - @{ - Product product = (Product)context.DataItem; - -

@Setting.BaseUrl/public/transfer/@product.ServiceProvider.AffiliateId/@product.Id

- - } -
-
- + + @{ //check if has transferdestination var AddressId = ((Product)context.DataItem).Profile.AddressId; var result = CheckDestinations(AddressId); //if not, display button + + Product product = (Product)context.DataItem; + var _url = $"{Setting.BaseUrl}/public/transfer/{product.ServiceProvider.AffiliateId}/{product.Id}"; + + Copy referral url + if (!result) { //

Address:

//

@(((Product)context.DataItem).Profile.Address.AddressText)

} - else + // else + // { + //

Address: @(((Product)context.DataItem).Profile.Address.AddressText)

+ // } + + if (product.ProductType == TIAM.Core.Enums.ProductType.Hotel) { -

Address:

-

@(((Product)context.DataItem).Profile.Address.AddressText)

+ } + else if (product.ProductType == TIAM.Core.Enums.ProductType.Transfer) + { + + } + }
- - + + - + @{ + Product product = (Product)context.DataItem; + var _url = $"{Setting.BaseUrl}/public/transfer/{product.ServiceProvider.AffiliateId}/{product.Id}"; +

Referral link

+ @_url +
+ Copy URL + } @@ -139,6 +134,16 @@
+ + @code { [Parameter] public Guid? ContextId { get; set; } [Parameter] public IProductsRelation? ParentData { get; set; } = null!; @@ -150,7 +155,14 @@ private List destinations = []; private ProductDetailGrid _productGrid = null!; - private LoggerClient _logger = null!; + private LoggerClient _logger = null!; + + private async Task CopyUrl(string url) + { + + await JsRuntime.InvokeVoidAsync("copyToClipboard", url); + } + protected override void OnInitialized() { _logger = new LoggerClient(LogWriters.ToArray()); diff --git a/TIAMSharedUI/TIAMSharedUI.csproj b/TIAMSharedUI/TIAMSharedUI.csproj index f8321858..59132e49 100644 --- a/TIAMSharedUI/TIAMSharedUI.csproj +++ b/TIAMSharedUI/TIAMSharedUI.csproj @@ -78,6 +78,9 @@ + + true + true diff --git a/TIAMSharedUI/wwwroot/css/TourIAm.css b/TIAMSharedUI/wwwroot/css/TourIAm.css index c19a7b3d..c94494f7 100644 --- a/TIAMSharedUI/wwwroot/css/TourIAm.css +++ b/TIAMSharedUI/wwwroot/css/TourIAm.css @@ -273,6 +273,9 @@ select { border-bottom: 0; } +.dxbl-tabs.dxbl-tabs-top > .dxbl-tabs-tablist { + background-color: aliceblue; +} /*my blazor overrides end*/ .custom-select { padding: 10px 15px 10px 10px !important; diff --git a/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs b/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs index c7d030c7..f085fce6 100644 --- a/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs +++ b/TIAMWebApp/Server/Controllers/ServiceProviderAPIController.cs @@ -21,6 +21,7 @@ using TIAM.Services; using TIAM.Entities.Products; using TIAM.Models.Dtos.Products; using TIAM.Models.Dtos.Users; +using TIAMWebApp.Shared.Application.Models.ClientSide; namespace TIAMWebApp.Server.Controllers { @@ -523,5 +524,37 @@ namespace TIAMWebApp.Server.Controllers return Ok(sigBase64); } } + + [AllowAnonymous] + [HttpPost] + [Route(APIUrls.GetQrCodeByProductIdAndOwnerAffiliateIdRouteName)] + public async Task GetQrCodeByProductIdAndOwnerAffiliateId([FromBody] Guid[] Ids) + { + _logger.Info(@"GetQRCode called"); + + if (Ids[0].IsNullOrEmpty() || Ids[1].IsNullOrEmpty()) + { + return BadRequest("Product is required"); + } + else + { + + var qrGenerator = new QRCodeGenerator(); + var qrCodeData = qrGenerator.CreateQrCode($"{Setting.BaseUrl}/public/transfer/{Ids[0]}/{Ids[1]}", QRCodeGenerator.ECCLevel.Q); + var qrCode = new QRCode(qrCodeData); + //Bitmap qrCodeImage = qrCode.GetGraphic(20); + //var rootpath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "assets"); + var rootpath = System.IO.Path.Combine(env.WebRootPath, "assets"); + var qrCodeImage = qrCode.GetGraphic(20, Color.DarkMagenta, Color.White, (Bitmap)Bitmap.FromFile(rootpath + "/myimage.png")); + _logger.Info($@"qrCodeLogo: {rootpath}/myimage.png"); + var ms = new MemoryStream(); + qrCodeImage.Save(ms, ImageFormat.Jpeg); + var byteImage = ms.ToArray(); + + var sigBase64 = Convert.ToBase64String(byteImage); // Get Base64 + + return Ok(sigBase64); + } + } } } \ No newline at end of file diff --git a/TIAMWebApp/Shared/Interfaces/IServiceProviderDataService.cs b/TIAMWebApp/Shared/Interfaces/IServiceProviderDataService.cs index 44e04baf..a875e7e4 100644 --- a/TIAMWebApp/Shared/Interfaces/IServiceProviderDataService.cs +++ b/TIAMWebApp/Shared/Interfaces/IServiceProviderDataService.cs @@ -46,6 +46,7 @@ namespace TIAMWebApp.Shared.Application.Interfaces //25. (IServiceProviderDataService) Get QRCode by ProductId public Task GetQRCodeByProductIdAsync(Guid productId); + public Task GetQRCodeByProductIdAndOwnerAffiliateIdAsync(Guid[] Ids); public Task> GetProductsForServiceProviderAsync(Guid serviceProviderId); diff --git a/TIAMWebApp/Shared/Models/APIUrls.cs b/TIAMWebApp/Shared/Models/APIUrls.cs index 17415c75..5e35471c 100644 --- a/TIAMWebApp/Shared/Models/APIUrls.cs +++ b/TIAMWebApp/Shared/Models/APIUrls.cs @@ -162,6 +162,9 @@ namespace TIAMWebApp.Shared.Application.Models public const string GetQrCodeByProductIdRouteName = "GetQRCodeByProductId"; public const string GetQrCodeByProductId = ServiceProviderAPI + GetQrCodeByProductIdRouteName; + public const string GetQrCodeByProductIdAndOwnerAffiliateIdRouteName = "GetQrCodeByProductIdAndOwnerAffiliateId"; + public const string GetQrCodeByProductIdAndOwnerAffiliateId = ServiceProviderAPI + GetQrCodeByProductIdAndOwnerAffiliateIdRouteName; + public const string AddProductRouteName = "AddProduct"; public const string AddProduct = ServiceProviderAPI + AddProductRouteName; diff --git a/TIAMWebApp/Shared/Services/ServiceProviderDataService.cs b/TIAMWebApp/Shared/Services/ServiceProviderDataService.cs index 561dfbf4..7d0a70b8 100644 --- a/TIAMWebApp/Shared/Services/ServiceProviderDataService.cs +++ b/TIAMWebApp/Shared/Services/ServiceProviderDataService.cs @@ -215,6 +215,23 @@ namespace TIAMWebApp.Shared.Application.Services } } + public async Task GetQRCodeByProductIdAndOwnerAffiliateIdAsync(Guid[] Ids) + { + + var url = APIUrls.GetQrCodeByProductIdAndOwnerAffiliateId; + var response = await http.PostAsJsonAsync(url, Ids); + if (response.IsSuccessStatusCode) + { + var result = await response.Content.ReadAsStringAsync(); + + return result; + } + else + { + return null; + } + } + public async Task> GetProductsForServiceProviderAsync(Guid serviceProviderId) { var url = APIUrls.GetProductsByServiceProviderId;