diff --git a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs index 893e32b..0812704 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs @@ -1,9 +1,13 @@ -using Microsoft.AspNetCore.Mvc; +using DocumentFormat.OpenXml.EMMA; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Models; using Nop.Plugin.Misc.AuctionPlugin.Domains; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; using Nop.Plugin.Misc.AuctionPlugin.Hubs; +using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages; using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Services.Logging; using Nop.Web.Framework; @@ -64,13 +68,67 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Controllers if (viewModel.IsActive == true) { + var announcement = new MessageBase + { + MessageType = "announcement", + Data = new AnnouncementMessage + { + Title = viewModel.Name, + Message = viewModel.Body, + } + }; + var jsonMessage = JsonConvert.SerializeObject(announcement, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); await _logger.InformationAsync($"sending announcements"); - await _announcementHubContext.Clients.All.SendAsync("send", viewModel.Body.ToString()); + await _announcementHubContext.Clients.All.SendAsync("send", jsonMessage); + //await _announcementHubContext.Clients.All.SendAsync("send", viewModel.Body.ToString()); } return RedirectToAction("AnnouncementList"); } + public async Task SendBidNotificationViewModel() + { + var viewModel = new BidNotificationViewModel(); + viewModel.ProductName = "Picasso - Önarckép"; + viewModel.BidPrice = 200000; + viewModel.NextStepAmount = 50000; + return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/BidNotification.cshtml", viewModel); + + } + + [HttpPost] + public async Task SendBidNotificationViewModel(BidNotificationViewModel viewModel) + { + AuctionBid objOfAuctionBid = new AuctionBid(); + objOfAuctionBid.ProductId = 4; + objOfAuctionBid.BidPrice = viewModel.BidPrice; + + objOfAuctionBid.Created = DateTime.UtcNow; + //await _announcementService.InsertAsync(objOfAuctionBid); + + + var bid = new MessageBase + { + MessageType = "bidNotification", + Data = new BidNotificationMessage + { + ProductName = viewModel.ProductName, + BidPrice = viewModel.BidPrice, + NextStepAmount = viewModel.NextStepAmount + } + }; + var jsonMessage = JsonConvert.SerializeObject(bid, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } + ); + + await _announcementHubContext.Clients.All.SendAsync("send", jsonMessage); + + + return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/BidNotification.cshtml", viewModel); + + } + [HttpPost] public async Task Edit(Announcement model) { diff --git a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Models/BidNotificationViewModel.cs b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Models/BidNotificationViewModel.cs new file mode 100644 index 0000000..fdad9ab --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Models/BidNotificationViewModel.cs @@ -0,0 +1,17 @@ +using Nop.Web.Framework.Models; +using Nop.Web.Framework.Mvc.ModelBinding; + +namespace Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Models +{ + public record BidNotificationViewModel : BaseNopModel + { + [NopResourceDisplayName("Name")] + public string ProductName { get; set; } + + public int BidPrice { get; set; } + + public int NextStepAmount { get; set; } + + } + +} diff --git a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Views/BidNotification.cshtml b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Views/BidNotification.cshtml new file mode 100644 index 0000000..ca2d2e3 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Views/BidNotification.cshtml @@ -0,0 +1,87 @@ +@model BidNotificationViewModel +@using Nop.Core.Infrastructure +@using Nop.Web.Framework + +@{ + var defaultGridPageSize = EngineContext.Current.Resolve().DefaultGridPageSize; + var gridPageSizes = EngineContext.Current.Resolve().GridPageSizes; + Layout = "_AdminLayout"; + //page title + ViewBag.Title = T("Admin.Plugins.HomePageProduct").Text; +} + +@using (Html.BeginForm()) +{ +
+

+ Send BidNotification +

+ +
+ + +
+
+ +
+
+
+ +
+
+
+ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/AuctionDefaults.cs b/Nop.Plugin.Misc.AuctionPlugin/AuctionDefaults.cs index 3cfac55..aa2629a 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/AuctionDefaults.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/AuctionDefaults.cs @@ -29,6 +29,7 @@ public static class AuctionDefaults public static string AnnouncementListRouteName => "Plugin.Misc.AuctionPlugin.AnnouncementList"; public static string AuctionRouteName => "Plugin.Misc.AuctionPlugin.Auction"; public static string TestPageRouteName => "Plugin.Misc.AuctionPlugin.TestPage"; + public static string BidNotificationRouteName => "Plugin.Misc.AuctionPlugin.BidNotification"; /// /// Gets the name of autosuggest component diff --git a/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs b/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs index cfa3425..19b5294 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs @@ -193,6 +193,14 @@ namespace Nop.Plugin.Misc.AuctionPlugin Url = "~/Admin/AuctionPluginAdmin/TestPage" }); + liveAnnouncementPluginNode.ChildNodes.Add(new SiteMapNode() + { + Title = await _localizationService.GetResourceAsync("Misc.SendBid"), + Visible = true, + IconClass = "fa-dot-circle-o", + Url = "~/Admin/Announcement/SendBidNotificationViewModel" + }); + } } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js index 12fdb5e..3f127f2 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js +++ b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js @@ -1,12 +1,15 @@ -$(function () { +// Define the message handler library +// SignalR connection setup +$(function () { console.log("signalRJs Starts"); + var connection = new signalR.HubConnectionBuilder() .withUrl('/auctionhub') .build(); connection.on('send', data => { - showannouncement(data); + MessageHandler.handle(data); }); function start() { @@ -20,67 +23,97 @@ connection.onclose(function () { start(); }); - + start(); }); -function showannouncement(announcemant) { - console.log("announcement arrived!"); - if (announcemant) { - toastr.options = { - "closeButton": true, - "debug": false, - "newestOnTop": false, - "progressBar": false, - "positionClass": "toast-bottom-right", - "preventDuplicates": false, - "onclick": null, - "showDuration": 300, - "hideDuration": 10000, - "timeOut": 100000, - "extendedTimeOut": 20000, - "showEasing": "swing", - "hideEasing": "linear", - "showMethod": "fadeIn", - "hideMethod": "fadeOut" - }; - tostView = '
' + announcemant + '
' - toastr["info"](tostView); - $('.toast-info').css("background-color", "#008080"); - toastr.options.onclick = function () { - $("html, body").animate( - { scrollTop: 0 }, - 1000); - } +//$(function () { - $(".toast").click(function () { - $("html, body").animate( - { scrollTop: 0 }, - 1000); - }); +// console.log("signalRJs Starts"); +// var connection = new signalR.HubConnectionBuilder() +// .withUrl('/auctionhub') +// .build(); - $(".toast-info").click(function () { - $("html, body").animate( - { scrollTop: 0 }, - 1000); - }); +// connection.on('send', data => { +// showannouncement(data); +// }); - toastr.options = { - onclick: function () { - $("html, body").animate( - { scrollTop: 0 }, - 1000); - } - } +// function start() { +// connection.start().catch(function (err) { +// setTimeout(function () { +// start(); +// }, 100000); +// }); +// } - $(".announcemantToast").on("click", function () { - $("html, body").animate( - { scrollTop: 0 }, - 1000); - }); - } -} +// connection.onclose(function () { +// start(); +// }); + +// start(); +//}); + + + +//function showannouncement(announcemant) { +// console.log("announcement arrived!"); +// if (announcemant) { +// toastr.options = { +// "closeButton": true, +// "debug": false, +// "newestOnTop": false, +// "progressBar": false, +// "positionClass": "toast-bottom-right", +// "preventDuplicates": false, +// "onclick": null, +// "showDuration": 300, +// "hideDuration": 10000, +// "timeOut": 100000, +// "extendedTimeOut": 20000, +// "showEasing": "swing", +// "hideEasing": "linear", +// "showMethod": "fadeIn", +// "hideMethod": "fadeOut" +// }; + +// tostView = '
' + announcemant + '
' +// toastr["info"](tostView); +// $('.toast-info').css("background-color", "#008080"); + +// toastr.options.onclick = function () { +// $("html, body").animate( +// { scrollTop: 0 }, +// 1000); +// } + +// $(".toast").click(function () { +// $("html, body").animate( +// { scrollTop: 0 }, +// 1000); +// }); + +// $(".toast-info").click(function () { +// $("html, body").animate( +// { scrollTop: 0 }, +// 1000); +// }); + +// toastr.options = { +// onclick: function () { +// $("html, body").animate( +// { scrollTop: 0 }, +// 1000); +// } +// } + +// $(".announcemantToast").on("click", function () { +// $("html, body").animate( +// { scrollTop: 0 }, +// 1000); +// }); +// } +//} diff --git a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/MgMessageHandler.js b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/MgMessageHandler.js new file mode 100644 index 0000000..41b2e3b --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/MgMessageHandler.js @@ -0,0 +1,71 @@ +var MessageHandler = (function () { + // Handlers for each message type + let animation = "slideDown"; + const handlers = { + announcement: function (data) { + toastr.info(`
${data.message}
`, data.title, { + "closeButton": true, + "positionClass": "toast-bottom-right", + "newestOnTop": true, + "progressBar": true, + "preventDuplicates": false, + "onclick": null, + "showDuration": "30000", + "hideDuration": "1000", + "timeOut": "5000", + "extendedTimeOut": "1000", + "showEasing": "swing", + "hideEasing": "linear", + "showMethod": animation, + "hideMethod": "fadeOut" + }); + $('.toast-info').css("background-color", "#008080"); + }, + bidNotification: function (data) { + //console.log("Bid product name" + data.productName); + toastr.success(`

${data.bidPrice}

${data.productName}

`, "New bid arrived", { + //"timeOut": 150000, + "closeButton": true, + "positionClass": "toast-bottom-right", + "newestOnTop": true, + "progressBar": true, + "preventDuplicates": false, + "onclick": null, + "showDuration": "30000", + "hideDuration": "1000", + "timeOut": "5000", + "extendedTimeOut": "1000", + "showEasing": "swing", + "hideEasing": "linear", + "showMethod": animation, + "hideMethod": "fadeOut" + + }); + $('.toast-success').css("background-color", "#4caf50"); + }, + // Add more handlers as needed + default: function (data) { + console.warn("Unhandled message type:", data); + } + }; + + // Message router to route to the appropriate handler based on message type + function messageRouter(message) { + // Parse the JSON message + try { + /*console.log(message);*/ + const parsedMessage = JSON.parse(message); + const messageType = parsedMessage.messageType; + const messageData = parsedMessage.data; + console.log("Message type:" + messageType); + // Route to appropriate handler, default if no match + (handlers[messageType] || handlers.default)(messageData); + } catch (e) { + console.error("Error parsing message:", e); + } + } + + return { + handle: messageRouter + }; +})(); diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs index 7785158..2a0ba7d 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/AuctionHub.cs @@ -41,11 +41,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs //await _signalRservice.TestHub(); } - public async Task Send(string announcement) - { - await _logger.InformationAsync($" Hub Send method called with messgae: {announcement}"); - await Clients.All.SendAsync("send", announcement); - } + //public async Task Send(string announcement) + //{ + // await _logger.InformationAsync($" Hub Send method called with messgae: {announcement}"); + // await Clients.All.SendAsync("send", announcement); + //} public async Task SendPriceToUsers(string message) { diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AnnouncementMessage.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AnnouncementMessage.cs new file mode 100644 index 0000000..165aad5 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AnnouncementMessage.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages +{ + public class AnnouncementMessage + { + public string Title { get; set; } + public string Message { get; set; } + } +} diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/BidNotificationMessage.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/BidNotificationMessage.cs new file mode 100644 index 0000000..d5fbcec --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/BidNotificationMessage.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages +{ + public class BidNotificationMessage + { + public string ProductName { get; set; } + public int BidPrice { get; set; } + public int NextStepAmount { get; set; } + } +} diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageBase.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageBase.cs new file mode 100644 index 0000000..636d5b5 --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageBase.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages +{ + public class MessageBase + { + public string MessageType { get; set; } + public object Data { get; set; } + } +} diff --git a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs index cd750f8..e447110 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/PluginNopStartup.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -15,6 +16,7 @@ using Nop.Services.Catalog; using Nop.Services.Configuration; using Nop.Services.Localization; using Nop.Web.Framework; +using Nop.Web.Framework.Mvc.Routing; namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure { @@ -51,7 +53,8 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); + services.AddScoped(); } /// diff --git a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/RouteProvider.cs b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/RouteProvider.cs index f12af53..64eeb18 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/RouteProvider.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Infrastructure/RouteProvider.cs @@ -37,6 +37,10 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Infrastructure endpointRouteBuilder.MapControllerRoute(name: AuctionDefaults.TestPageRouteName, pattern: "Admin/Auction/TestPage", defaults: new { controller = "AuctionPluginAdmin", action = "TestPage" }); + + endpointRouteBuilder.MapControllerRoute(name: AuctionDefaults.BidNotificationRouteName, + pattern: "Admin/Announcement/SendBidNotificationViewModel", + defaults: new { controller = "Announcement", action = "SendBidNotificationViewModel" }); } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj b/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj index 9b60f4b..448060e 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj +++ b/Nop.Plugin.Misc.AuctionPlugin/Nop.Plugin.Misc.AuctionPlugin.csproj @@ -14,6 +14,7 @@ + @@ -29,6 +30,9 @@ + + Always + Always @@ -100,6 +104,9 @@ Always + + Always + Always diff --git a/Nop.Plugin.Misc.AuctionPlugin/Views/LiveAnnouncement.cshtml b/Nop.Plugin.Misc.AuctionPlugin/Views/LiveAnnouncement.cshtml index 3c4183e..4acfec9 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Views/LiveAnnouncement.cshtml +++ b/Nop.Plugin.Misc.AuctionPlugin/Views/LiveAnnouncement.cshtml @@ -11,6 +11,7 @@ IStoreContext _storeContext = EngineContext.Current.Resolve(); NopHtml.AddScriptParts(ResourceLocation.Head, "~/Plugins/Misc.AuctionPlugin/Content/Js/signalr.js"); + NopHtml.AddScriptParts(ResourceLocation.Footer, "~/Plugins/Misc.AuctionPlugin/Content/Js/MgMessageHandler.js"); NopHtml.AddScriptParts(ResourceLocation.Footer, "~/Plugins/Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js"); NopHtml.AddCssFileParts("~/Plugins/Misc.AuctionPlugin/Content/Css/toastr.min.css"); NopHtml.AddScriptParts(ResourceLocation.Footer, "~/Plugins/Misc.AuctionPlugin/Content/Js/toastr.js");